ACK: [SRU Focal 1/1] io_uring: fix fs->users overflow
Stefan Bader
stefan.bader at canonical.com
Wed May 18 09:05:00 UTC 2022
On 18.05.22 06:30, Thadeu Lima de Souza Cascardo wrote:
> From: Pavel Begunkov <asml.silence at gmail.com>
>
> There is a bunch of cases where we can grab req->fs but not put it, this
> can be used to cause a controllable overflow with further implications.
> Release req->fs in the request free path and make sure we zero the field
> to be sure we don't do it twice.
>
> Fixes: cac68d12c531 ("io_uring: grab ->fs as part of async offload")
> Reported-by: Bing-Jhong Billy Jheng <billy at starlabs.sg>
> Signed-off-by: Pavel Begunkov <asml.silence at gmail.com>
> Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> (cherry picked from commit 1a623d361ffe5cecd4244a02f449528416360038 linux-5.4.y)
> CVE-2022-1116
> Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo at canonical.com>
Acked-by: Stefan Bader <stefan.bader at canonical.com>
> ---
> fs/io_uring.c | 28 ++++++++++++++++++----------
> 1 file changed, 18 insertions(+), 10 deletions(-)
>
> diff --git a/fs/io_uring.c b/fs/io_uring.c
> index 478df7e10767..e73969fa96bc 100644
> --- a/fs/io_uring.c
> +++ b/fs/io_uring.c
> @@ -438,6 +438,22 @@ static struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p)
> return ctx;
> }
>
> +static void io_req_put_fs(struct io_kiocb *req)
> +{
> + struct fs_struct *fs = req->fs;
> +
> + if (!fs)
> + return;
> +
> + spin_lock(&req->fs->lock);
> + if (--fs->users)
> + fs = NULL;
> + spin_unlock(&req->fs->lock);
> + if (fs)
> + free_fs_struct(fs);
> + req->fs = NULL;
> +}
> +
> static inline bool __io_sequence_defer(struct io_ring_ctx *ctx,
> struct io_kiocb *req)
> {
> @@ -695,6 +711,7 @@ static void io_free_req_many(struct io_ring_ctx *ctx, void **reqs, int *nr)
>
> static void __io_free_req(struct io_kiocb *req)
> {
> + io_req_put_fs(req);
> if (req->file && !(req->flags & REQ_F_FIXED_FILE))
> fput(req->file);
> percpu_ref_put(&req->ctx->refs);
> @@ -1701,16 +1718,7 @@ static int io_send_recvmsg(struct io_kiocb *req, const struct io_uring_sqe *sqe,
> ret = -EINTR;
> }
>
> - if (req->fs) {
> - struct fs_struct *fs = req->fs;
> -
> - spin_lock(&req->fs->lock);
> - if (--fs->users)
> - fs = NULL;
> - spin_unlock(&req->fs->lock);
> - if (fs)
> - free_fs_struct(fs);
> - }
> + io_req_put_fs(req);
> io_cqring_add_event(req->ctx, sqe->user_data, ret);
> io_put_req(req);
> return 0;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <https://lists.ubuntu.com/archives/kernel-team/attachments/20220518/6dd50719/attachment.sig>
More information about the kernel-team
mailing list