diff mbox series

io_uring: Add NULL checks for current->io_uring

Message ID 20230111101907.600820-1-baijiaju1990@gmail.com (mailing list archive)
State New
Headers show
Series io_uring: Add NULL checks for current->io_uring | expand

Commit Message

Jia-Ju Bai Jan. 11, 2023, 10:19 a.m. UTC
As described in a previous commit 998b30c3948e, current->io_uring could
be NULL, and thus a NULL check is required for this variable.

In the same way, other functions that access current->io_uring also
require NULL checks of this variable.

Signed-off-by: Jia-Ju Bai <baijiaju1990@gmail.com>
Reported-by: TOTE Robot <oslab@tsinghua.edu.cn>
---
 io_uring/io_uring.c | 3 ++-
 io_uring/io_uring.h | 3 +++
 io_uring/tctx.c     | 9 ++++++++-
 3 files changed, 13 insertions(+), 2 deletions(-)

Comments

Jens Axboe Jan. 11, 2023, 2:49 p.m. UTC | #1
On 1/11/23 3:19 AM, Jia-Ju Bai wrote:
> As described in a previous commit 998b30c3948e, current->io_uring could
> be NULL, and thus a NULL check is required for this variable.
> 
> In the same way, other functions that access current->io_uring also
> require NULL checks of this variable.

This seems odd. Have you actually seen traces of this, or is it just
based on "guess it can be NULL sometimes, check it in all spots"?
Pavel Begunkov Jan. 11, 2023, 2:49 p.m. UTC | #2
On 1/11/23 10:19, Jia-Ju Bai wrote:
> As described in a previous commit 998b30c3948e, current->io_uring could
> be NULL, and thus a NULL check is required for this variable.
> 
> In the same way, other functions that access current->io_uring also
> require NULL checks of this variable.

io_uring_enter() {
...
	ret = io_uring_add_tctx_node(ctx);
	if (unlikely(ret))
		goto out;

	mutex_lock(&ctx->uring_lock);
	ret = io_submit_sqes(ctx, to_submit);
}

io_uring_add_tctx_node() should make sure to setup current->io_uring
or fail, so it should be NULL there, and SQPOLL should be fine as well.
Did you see it hitting NULL?


> 
> Signed-off-by: Jia-Ju Bai <baijiaju1990@gmail.com>
> Reported-by: TOTE Robot <oslab@tsinghua.edu.cn>
> ---
>   io_uring/io_uring.c | 3 ++-
>   io_uring/io_uring.h | 3 +++
>   io_uring/tctx.c     | 9 ++++++++-
>   3 files changed, 13 insertions(+), 2 deletions(-)
> 
> diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
> index 2ac1cd8d23ea..8075c0880c7a 100644
> --- a/io_uring/io_uring.c
> +++ b/io_uring/io_uring.c
> @@ -2406,7 +2406,8 @@ int io_submit_sqes(struct io_ring_ctx *ctx, unsigned int nr)
>   		/* try again if it submitted nothing and can't allocate a req */
>   		if (!ret && io_req_cache_empty(ctx))
>   			ret = -EAGAIN;
> -		current->io_uring->cached_refs += left;
> +		if (likely(current->io_uring))
> +			current->io_uring->cached_refs += left;
>   	}
>   
>   	io_submit_state_end(ctx);
> diff --git a/io_uring/io_uring.h b/io_uring/io_uring.h
> index ab4b2a1c3b7e..398c7c2ba22b 100644
> --- a/io_uring/io_uring.h
> +++ b/io_uring/io_uring.h
> @@ -362,6 +362,9 @@ static inline void io_get_task_refs(int nr)
>   {
>   	struct io_uring_task *tctx = current->io_uring;
>   
> +	if (unlikely(!tctx))
> +		return;
> +
>   	tctx->cached_refs -= nr;
>   	if (unlikely(tctx->cached_refs < 0))
>   		io_task_refs_refill(tctx);
> diff --git a/io_uring/tctx.c b/io_uring/tctx.c
> index 4324b1cf1f6a..6574bbe82b5d 100644
> --- a/io_uring/tctx.c
> +++ b/io_uring/tctx.c
> @@ -145,7 +145,8 @@ int __io_uring_add_tctx_node_from_submit(struct io_ring_ctx *ctx)
>   	if (ret)
>   		return ret;
>   
> -	current->io_uring->last = ctx;
> +	if (likely(current->io_uring))
> +		current->io_uring->last = ctx;
>   	return 0;
>   }
>   
> @@ -200,6 +201,9 @@ void io_uring_unreg_ringfd(void)
>   	struct io_uring_task *tctx = current->io_uring;
>   	int i;
>   
> +	if (unlikely(!tctx))
> +		return;
> +
>   	for (i = 0; i < IO_RINGFD_REG_MAX; i++) {
>   		if (tctx->registered_rings[i]) {
>   			fput(tctx->registered_rings[i]);
> @@ -259,6 +263,9 @@ int io_ringfd_register(struct io_ring_ctx *ctx, void __user *__arg,
>   		return ret;
>   
>   	tctx = current->io_uring;
> +	if (unlikely(!tctx))
> +		return -EINVAL;
> +
>   	for (i = 0; i < nr_args; i++) {
>   		int start, end;
>
Jia-Ju Bai Jan. 12, 2023, 2:10 a.m. UTC | #3
On 2023/1/11 22:49, Jens Axboe wrote:
> On 1/11/23 3:19 AM, Jia-Ju Bai wrote:
>> As described in a previous commit 998b30c3948e, current->io_uring could
>> be NULL, and thus a NULL check is required for this variable.
>>
>> In the same way, other functions that access current->io_uring also
>> require NULL checks of this variable.
> This seems odd. Have you actually seen traces of this, or is it just
> based on "guess it can be NULL sometimes, check it in all spots"?
>

Thanks for the reply!
I checked the previous commit and inferred that there may be some problems.
I am not quite sure of this, and thus want to listen to your opinions :)


Best wishes,
Jia-Ju Bai
Jens Axboe Jan. 12, 2023, 2:37 a.m. UTC | #4
On 1/11/23 7:10 PM, Jia-Ju Bai wrote:
> 
> 
> On 2023/1/11 22:49, Jens Axboe wrote:
>> On 1/11/23 3:19 AM, Jia-Ju Bai wrote:
>>> As described in a previous commit 998b30c3948e, current->io_uring could
>>> be NULL, and thus a NULL check is required for this variable.
>>>
>>> In the same way, other functions that access current->io_uring also
>>> require NULL checks of this variable.
>> This seems odd. Have you actually seen traces of this, or is it just
>> based on "guess it can be NULL sometimes, check it in all spots"?
>>
> 
> Thanks for the reply!
> I checked the previous commit and inferred that there may be some problems.
> I am not quite sure of this, and thus want to listen to your opinions :)

I'd invite you to look over each of them separately, and see if that path
could potentially lead to current->io_uring == NULL and thus being an
issue. I think that'd be a useful exercise, and you never know that you
might find :-)
diff mbox series

Patch

diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
index 2ac1cd8d23ea..8075c0880c7a 100644
--- a/io_uring/io_uring.c
+++ b/io_uring/io_uring.c
@@ -2406,7 +2406,8 @@  int io_submit_sqes(struct io_ring_ctx *ctx, unsigned int nr)
 		/* try again if it submitted nothing and can't allocate a req */
 		if (!ret && io_req_cache_empty(ctx))
 			ret = -EAGAIN;
-		current->io_uring->cached_refs += left;
+		if (likely(current->io_uring))
+			current->io_uring->cached_refs += left;
 	}
 
 	io_submit_state_end(ctx);
diff --git a/io_uring/io_uring.h b/io_uring/io_uring.h
index ab4b2a1c3b7e..398c7c2ba22b 100644
--- a/io_uring/io_uring.h
+++ b/io_uring/io_uring.h
@@ -362,6 +362,9 @@  static inline void io_get_task_refs(int nr)
 {
 	struct io_uring_task *tctx = current->io_uring;
 
+	if (unlikely(!tctx))
+		return;
+
 	tctx->cached_refs -= nr;
 	if (unlikely(tctx->cached_refs < 0))
 		io_task_refs_refill(tctx);
diff --git a/io_uring/tctx.c b/io_uring/tctx.c
index 4324b1cf1f6a..6574bbe82b5d 100644
--- a/io_uring/tctx.c
+++ b/io_uring/tctx.c
@@ -145,7 +145,8 @@  int __io_uring_add_tctx_node_from_submit(struct io_ring_ctx *ctx)
 	if (ret)
 		return ret;
 
-	current->io_uring->last = ctx;
+	if (likely(current->io_uring))
+		current->io_uring->last = ctx;
 	return 0;
 }
 
@@ -200,6 +201,9 @@  void io_uring_unreg_ringfd(void)
 	struct io_uring_task *tctx = current->io_uring;
 	int i;
 
+	if (unlikely(!tctx))
+		return;
+
 	for (i = 0; i < IO_RINGFD_REG_MAX; i++) {
 		if (tctx->registered_rings[i]) {
 			fput(tctx->registered_rings[i]);
@@ -259,6 +263,9 @@  int io_ringfd_register(struct io_ring_ctx *ctx, void __user *__arg,
 		return ret;
 
 	tctx = current->io_uring;
+	if (unlikely(!tctx))
+		return -EINVAL;
+
 	for (i = 0; i < nr_args; i++) {
 		int start, end;