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

dm: Check for device sector overflow if CONFIG_LBDAF is not set

Reference to a device in device-mapper table contains offset in sectors.

If the sector_t is 32bit integer (CONFIG_LBDAF is not set), then
several device-mapper targets can overflow this offset and validity
check is then performed on a wrong offset and a wrong table is activated.

See for example (on 32bit without CONFIG_LBDAF) this overflow:

# dmsetup create test --table "0 2048 linear /dev/sdg 4294967297"
# dmsetup table test
0 2048 linear 8:96 1

This patch adds explicit check for overflow if the offset is sector_t type.

Signed-off-by: Milan Broz <gmazyland@gmail.com>
Reviewed-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>

authored by

Milan Broz and committed by
Mike Snitzer
ef87bfc2 8d683dcd

+7 -6
+1 -1
drivers/md/dm-crypt.c
··· 2781 2781 } 2782 2782 2783 2783 ret = -EINVAL; 2784 - if (sscanf(argv[4], "%llu%c", &tmpll, &dummy) != 1) { 2784 + if (sscanf(argv[4], "%llu%c", &tmpll, &dummy) != 1 || tmpll != (sector_t)tmpll) { 2785 2785 ti->error = "Invalid device sector"; 2786 2786 goto bad; 2787 2787 }
+1 -1
drivers/md/dm-delay.c
··· 141 141 unsigned long long tmpll; 142 142 char dummy; 143 143 144 - if (sscanf(argv[1], "%llu%c", &tmpll, &dummy) != 1) { 144 + if (sscanf(argv[1], "%llu%c", &tmpll, &dummy) != 1 || tmpll != (sector_t)tmpll) { 145 145 ti->error = "Invalid device sector"; 146 146 return -EINVAL; 147 147 }
+1 -1
drivers/md/dm-flakey.c
··· 213 213 devname = dm_shift_arg(&as); 214 214 215 215 r = -EINVAL; 216 - if (sscanf(dm_shift_arg(&as), "%llu%c", &tmpll, &dummy) != 1) { 216 + if (sscanf(dm_shift_arg(&as), "%llu%c", &tmpll, &dummy) != 1 || tmpll != (sector_t)tmpll) { 217 217 ti->error = "Invalid device sector"; 218 218 goto bad; 219 219 }
+1 -1
drivers/md/dm-linear.c
··· 45 45 } 46 46 47 47 ret = -EINVAL; 48 - if (sscanf(argv[1], "%llu%c", &tmp, &dummy) != 1) { 48 + if (sscanf(argv[1], "%llu%c", &tmp, &dummy) != 1 || tmp != (sector_t)tmp) { 49 49 ti->error = "Invalid device sector"; 50 50 goto bad; 51 51 }
+2 -1
drivers/md/dm-raid1.c
··· 943 943 char dummy; 944 944 int ret; 945 945 946 - if (sscanf(argv[1], "%llu%c", &offset, &dummy) != 1) { 946 + if (sscanf(argv[1], "%llu%c", &offset, &dummy) != 1 || 947 + offset != (sector_t)offset) { 947 948 ti->error = "Invalid offset"; 948 949 return -EINVAL; 949 950 }
+1 -1
drivers/md/dm-unstripe.c
··· 78 78 goto err; 79 79 } 80 80 81 - if (sscanf(argv[4], "%llu%c", &start, &dummy) != 1) { 81 + if (sscanf(argv[4], "%llu%c", &start, &dummy) != 1 || start != (sector_t)start) { 82 82 ti->error = "Invalid striped device offset"; 83 83 goto err; 84 84 }