Re: [PATCH] io_uring: fix possible use after free to sqd

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Oct 15, 2020 at 06:46:34PM +0800, Xiaoguang Wang wrote:
hi閿涳拷

On Thu, Oct 15, 2020 at 05:13:35PM +0800, Xiaoguang Wang wrote:
Reading codes finds a possible use after free issue to sqd:
            thread1              |       thread2
==> io_attach_sq_data()        |
===> sqd = ctx_attach->sq_data;|
                                 | ==> io_put_sq_data()
                                 | ===> refcount_dec_and_test(&sqd->refs)
                                 |     If sqd->refs is zero, will free sqd.
                                 |
===> refcount_inc(&sqd->refs); |
                                 |
                                 | ====> kfree(sqd);
===> now use after free to sqd |


IIUC the io_attach_sq_data() is called only during the setup of an
io_uring context, before that the fd is returned to the user space.
Sorry I didn't make it clear in commit message.
In io_attach_sq_data(), we'll try to attach to a previous io_uring instance
indicated by p->wq_fd, this p->wq_fd could be closed independently.

Thanks to clarify! Got it.

Also in this case, IIUC io_put_sq_data() is called only when
io_uring_release() is invoked on the previous io_uring instance.

Since we are taking a reference with fdget at the begin of io_attach_sq_data()
and we release this reference only at the end of io_attach_sq_data(),
can io_put_sq_data() runs in another thread while we have the reference?
Oh, right, thanks. Jens, you can ignore this patch, thanks.

Regards,
Xiaoguang Wang


Thanks,
Stefano


Regards,
Xiaoguang Wang

So, I'm not sure a second thread can call io_put_sq_data() while the
first thread is in io_attach_sq_data().

Can you check if this situation can really happen?

Thanks,
Stefano

Use refcount_inc_not_zero() to fix this issue.

Signed-off-by: Xiaoguang Wang <xiaoguang.wang@xxxxxxxxxxxxxxxxx>
---
   fs/io_uring.c | 6 +++++-
   1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/fs/io_uring.c b/fs/io_uring.c
index 33b5cf18bb51..48e230feb704 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -6868,7 +6868,11 @@ static struct io_sq_data *io_attach_sq_data(struct io_uring_params *p)
   		return ERR_PTR(-EINVAL);
   	}
-	refcount_inc(&sqd->refs);
+	if (!refcount_inc_not_zero(&sqd->refs)) {
+		fdput(f);
+		return ERR_PTR(-EINVAL);
+	}
+
   	fdput(f);
   	return sqd;
   }
--
2.17.2





[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux