diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-11-27 12:56:04 -0800 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-11-27 12:56:04 -0800 | 
| commit | 9223e74f9960778bd3edd39e15edd5532708b7fb (patch) | |
| tree | 51c070b3c91e33085f9a46c7a44cc5b9f7dfa1c7 | |
| parent | d021c3e56d48b0a435eab3b3ec99d4e8bf8df2d1 (diff) | |
| parent | af60470347de6ac2b9f0cc3703975a543a3de075 (diff) | |
Merge tag 'io_uring-5.10-2020-11-27' of git://git.kernel.dk/linux-block
Pull io_uring fixes from Jens Axboe:
 - Out of bounds fix for the cq size cap from earlier this release (Joseph)
 - iov_iter type check fix (Pavel)
 - Files grab + cancelation fix (Pavel)
* tag 'io_uring-5.10-2020-11-27' of git://git.kernel.dk/linux-block:
  io_uring: fix files grab/cancel race
  io_uring: fix ITER_BVEC check
  io_uring: fix shift-out-of-bounds when round up cq size
| -rw-r--r-- | fs/io_uring.c | 39 | 
1 files changed, 20 insertions, 19 deletions
diff --git a/fs/io_uring.c b/fs/io_uring.c index a8c136a1cf4e..1023f7b44cea 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -1313,22 +1313,6 @@ static bool io_grab_identity(struct io_kiocb *req)  			return false;  		req->work.flags |= IO_WQ_WORK_FSIZE;  	} - -	if (!(req->work.flags & IO_WQ_WORK_FILES) && -	    (def->work_flags & IO_WQ_WORK_FILES) && -	    !(req->flags & REQ_F_NO_FILE_TABLE)) { -		if (id->files != current->files || -		    id->nsproxy != current->nsproxy) -			return false; -		atomic_inc(&id->files->count); -		get_nsproxy(id->nsproxy); -		req->flags |= REQ_F_INFLIGHT; - -		spin_lock_irq(&ctx->inflight_lock); -		list_add(&req->inflight_entry, &ctx->inflight_list); -		spin_unlock_irq(&ctx->inflight_lock); -		req->work.flags |= IO_WQ_WORK_FILES; -	}  #ifdef CONFIG_BLK_CGROUP  	if (!(req->work.flags & IO_WQ_WORK_BLKCG) &&  	    (def->work_flags & IO_WQ_WORK_BLKCG)) { @@ -1370,6 +1354,21 @@ static bool io_grab_identity(struct io_kiocb *req)  		}  		spin_unlock(¤t->fs->lock);  	} +	if (!(req->work.flags & IO_WQ_WORK_FILES) && +	    (def->work_flags & IO_WQ_WORK_FILES) && +	    !(req->flags & REQ_F_NO_FILE_TABLE)) { +		if (id->files != current->files || +		    id->nsproxy != current->nsproxy) +			return false; +		atomic_inc(&id->files->count); +		get_nsproxy(id->nsproxy); +		req->flags |= REQ_F_INFLIGHT; + +		spin_lock_irq(&ctx->inflight_lock); +		list_add(&req->inflight_entry, &ctx->inflight_list); +		spin_unlock_irq(&ctx->inflight_lock); +		req->work.flags |= IO_WQ_WORK_FILES; +	}  	return true;  } @@ -3193,7 +3192,7 @@ static void io_req_map_rw(struct io_kiocb *req, const struct iovec *iovec,  	rw->free_iovec = iovec;  	rw->bytes_done = 0;  	/* can only be fixed buffers, no need to do anything */ -	if (iter->type == ITER_BVEC) +	if (iov_iter_is_bvec(iter))  		return;  	if (!iovec) {  		unsigned iov_off = 0; @@ -9252,14 +9251,16 @@ static int io_uring_create(unsigned entries, struct io_uring_params *p,  		 * to a power-of-two, if it isn't already. We do NOT impose  		 * any cq vs sq ring sizing.  		 */ -		p->cq_entries = roundup_pow_of_two(p->cq_entries); -		if (p->cq_entries < p->sq_entries) +		if (!p->cq_entries)  			return -EINVAL;  		if (p->cq_entries > IORING_MAX_CQ_ENTRIES) {  			if (!(p->flags & IORING_SETUP_CLAMP))  				return -EINVAL;  			p->cq_entries = IORING_MAX_CQ_ENTRIES;  		} +		p->cq_entries = roundup_pow_of_two(p->cq_entries); +		if (p->cq_entries < p->sq_entries) +			return -EINVAL;  	} else {  		p->cq_entries = 2 * p->sq_entries;  	}  | 
