Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

block: Fix WARNING in _copy_from_iter

Syzkaller reports a warning in _copy_from_iter because an
iov_iter is supposedly used in the wrong direction. The reason
is that syzcaller managed to generate a request with
a transfer direction of SG_DXFER_TO_FROM_DEV. This instructs
the kernel to copy user buffers into the kernel, read into
the copied buffers and then copy the data back to user space.

Thus the iovec is used in both directions.

Detect this situation in the block layer and construct a new
iterator with the correct direction for the copy-in.

Reported-by: syzbot+a532b03fdfee2c137666@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/lkml/0000000000009b92c10604d7a5e9@google.com/t/
Reported-by: syzbot+63dec323ac56c28e644f@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/lkml/0000000000003faaa105f6e7c658@google.com/T/
Signed-off-by: Christian A. Ehrhardt <lk@c--e.de>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Link: https://lore.kernel.org/r/20240121202634.275068-1-lk@c--e.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Christian A. Ehrhardt and committed by
Jens Axboe
13f3956e 7777f47f

+10 -3
+10 -3
block/blk-map.c
··· 205 205 /* 206 206 * success 207 207 */ 208 - if ((iov_iter_rw(iter) == WRITE && 209 - (!map_data || !map_data->null_mapped)) || 210 - (map_data && map_data->from_user)) { 208 + if (iov_iter_rw(iter) == WRITE && 209 + (!map_data || !map_data->null_mapped)) { 211 210 ret = bio_copy_from_iter(bio, iter); 211 + if (ret) 212 + goto cleanup; 213 + } else if (map_data && map_data->from_user) { 214 + struct iov_iter iter2 = *iter; 215 + 216 + /* This is the copy-in part of SG_DXFER_TO_FROM_DEV. */ 217 + iter2.data_source = ITER_SOURCE; 218 + ret = bio_copy_from_iter(bio, &iter2); 212 219 if (ret) 213 220 goto cleanup; 214 221 } else {