Message ID | 20170219071522.GI29622@ZenIV.linux.org.uk (mailing list archive) |
---|---|
State | Accepted, archived |
Headers | show |
On Sun, Feb 19, 2017 at 07:15:27AM +0000, Al Viro wrote: > The root cause is unfixable without access to TARDIS and dose of > antipsychotics sufficient to prevent /dev/sg API creation. > > What happens is that write to /dev/sg is given a request with non-zero > ->iovec_count combined with zero ->dxfer_len. Or with ->dxferp pointing > to an array full of empty iovecs. > > AFAICS, the minimal fix would be something like this: > > YAMissingSanityCheck in /dev/sg > > write permission to /dev/sg shouldn't be equivalent to the ability to trigger > BUG_ON() while holding spinlocks... Looks fine to me: Reviewed-by: Christoph Hellwig <hch@lst.de> The other thing we really need to consider is to finally merge the SG_IO implementations for /dev/sg with the common block layer one.
On Sat, Feb 18, 2017 at 11:15 PM, Al Viro <viro@zeniv.linux.org.uk> wrote: > > AFAICS, the minimal fix would be something like this: Applied, along with getting rid of the BUG_ON() that made this bug much worse than it would have been without it. Linus
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index dbe5b4b95df0..121de0aaa6ad 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -1753,6 +1753,10 @@ sg_start_req(Sg_request *srp, unsigned char *cmd) return res; iov_iter_truncate(&i, hp->dxfer_len); + if (!iov_iter_count(&i)) { + kfree(iov); + return -EINVAL; + } res = blk_rq_map_user_iov(q, rq, md, &i, GFP_ATOMIC); kfree(iov);