Skip to content

Commit

Permalink
block: fix SG_[GS]ET_RESERVED_SIZE ioctl when max_sectors is huge
Browse files Browse the repository at this point in the history
SG_GET_RESERVED_SIZE and SG_SET_RESERVED_SIZE ioctls access a reserved
buffer in bytes as int type.  The value needs to be capped at the request
queue's max_sectors.  But integer overflow is not correctly handled in
the calculation when converting max_sectors from sectors to bytes.

Signed-off-by: Akinobu Mita <[email protected]>
Cc: Jens Axboe <[email protected]>
Cc: "James E.J. Bottomley" <[email protected]>
Cc: Douglas Gilbert <[email protected]>
Cc: [email protected]
Reviewed-by: Christoph Hellwig <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
  • Loading branch information
mita authored and axboe committed Jul 1, 2014
1 parent 63f2649 commit 9b4231b
Showing 1 changed file with 11 additions and 4 deletions.
15 changes: 11 additions & 4 deletions block/scsi_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,18 @@ static int sg_set_timeout(struct request_queue *q, int __user *p)
return err;
}

static int max_sectors_bytes(struct request_queue *q)
{
unsigned int max_sectors = queue_max_sectors(q);

max_sectors = min_t(unsigned int, max_sectors, INT_MAX >> 9);

return max_sectors << 9;
}

static int sg_get_reserved_size(struct request_queue *q, int __user *p)
{
unsigned val = min(q->sg_reserved_size, queue_max_sectors(q) << 9);
int val = min_t(int, q->sg_reserved_size, max_sectors_bytes(q));

return put_user(val, p);
}
Expand All @@ -98,10 +107,8 @@ static int sg_set_reserved_size(struct request_queue *q, int __user *p)

if (size < 0)
return -EINVAL;
if (size > (queue_max_sectors(q) << 9))
size = queue_max_sectors(q) << 9;

q->sg_reserved_size = size;
q->sg_reserved_size = min(size, max_sectors_bytes(q));
return 0;
}

Expand Down

0 comments on commit 9b4231b

Please sign in to comment.