aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorDave Young <dyoung@redhat.com>2012-02-08 16:07:19 -0500
committerJens Axboe <axboe@kernel.dk>2012-02-08 16:07:19 -0500
commit306df0716aa285d378cc948fafed53c6ed895fe6 (patch)
treec32e636516980e9f2708022e314f370a13198ecd /drivers/block
parent5abebfdd02450fa1349daacf242e70b3736581e3 (diff)
loop: zero fill bio instead of return -EIO for partial read
commit 8268f5a741 ("deny partial write for loop dev fd") tried to fix the loop device partial read information leak problem. But it changed the semantics of read behavior. When we read beyond the end of the device we should get 0 bytes, which is normal behavior, we should not just return -EIO Instead of returning -EIO, zero out the bio to avoid information leak in case of partail read. Signed-off-by: Dave Young <dyoung@redhat.com> Reviewed-by: Jeff Moyer <jmoyer@redhat.com> Tested-by: Jeff Moyer <jmoyer@redhat.com> Cc: Dmitry Monakhov <dmonakhov@sw.ru> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/loop.c24
1 files changed, 13 insertions, 11 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index f00257782fcc..cd504353b278 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -356,14 +356,14 @@ lo_direct_splice_actor(struct pipe_inode_info *pipe, struct splice_desc *sd)
356 return __splice_from_pipe(pipe, sd, lo_splice_actor); 356 return __splice_from_pipe(pipe, sd, lo_splice_actor);
357} 357}
358 358
359static int 359static ssize_t
360do_lo_receive(struct loop_device *lo, 360do_lo_receive(struct loop_device *lo,
361 struct bio_vec *bvec, int bsize, loff_t pos) 361 struct bio_vec *bvec, int bsize, loff_t pos)
362{ 362{
363 struct lo_read_data cookie; 363 struct lo_read_data cookie;
364 struct splice_desc sd; 364 struct splice_desc sd;
365 struct file *file; 365 struct file *file;
366 long retval; 366 ssize_t retval;
367 367
368 cookie.lo = lo; 368 cookie.lo = lo;
369 cookie.page = bvec->bv_page; 369 cookie.page = bvec->bv_page;
@@ -379,26 +379,28 @@ do_lo_receive(struct loop_device *lo,
379 file = lo->lo_backing_file; 379 file = lo->lo_backing_file;
380 retval = splice_direct_to_actor(file, &sd, lo_direct_splice_actor); 380 retval = splice_direct_to_actor(file, &sd, lo_direct_splice_actor);
381 381
382 if (retval < 0) 382 return retval;
383 return retval;
384 if (retval != bvec->bv_len)
385 return -EIO;
386 return 0;
387} 383}
388 384
389static int 385static int
390lo_receive(struct loop_device *lo, struct bio *bio, int bsize, loff_t pos) 386lo_receive(struct loop_device *lo, struct bio *bio, int bsize, loff_t pos)
391{ 387{
392 struct bio_vec *bvec; 388 struct bio_vec *bvec;
393 int i, ret = 0; 389 ssize_t s;
390 int i;
394 391
395 bio_for_each_segment(bvec, bio, i) { 392 bio_for_each_segment(bvec, bio, i) {
396 ret = do_lo_receive(lo, bvec, bsize, pos); 393 s = do_lo_receive(lo, bvec, bsize, pos);
397 if (ret < 0) 394 if (s < 0)
395 return s;
396
397 if (s != bvec->bv_len) {
398 zero_fill_bio(bio);
398 break; 399 break;
400 }
399 pos += bvec->bv_len; 401 pos += bvec->bv_len;
400 } 402 }
401 return ret; 403 return 0;
402} 404}
403 405
404static int do_bio_filebacked(struct loop_device *lo, struct bio *bio) 406static int do_bio_filebacked(struct loop_device *lo, struct bio *bio)