From: Demi Marie Obenour Date: Sat, 3 Jun 2023 14:52:40 +0000 (-0400) Subject: dm ioctl: Avoid pointer arithmetic overflow X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=13f4a697f8b4feb705569f9336127e9e2f9ac596;p=linux.git dm ioctl: Avoid pointer arithmetic overflow Especially on 32-bit systems, it is possible for the pointer arithmetic to overflow and cause a userspace pointer to be dereferenced in the kernel. Signed-off-by: Demi Marie Obenour Reviewed-by: Mikulas Patocka Signed-off-by: Mike Snitzer --- diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index 3a6989b7817d6..e322fd490634f 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -1397,6 +1397,22 @@ static int next_target(struct dm_target_spec *last, uint32_t next, void *end, static_assert(__alignof__(struct dm_target_spec) <= 8, "struct dm_target_spec must not require more than 8-byte alignment"); + /* + * Number of bytes remaining, starting with last. This is always + * sizeof(struct dm_target_spec) or more, as otherwise *last was + * out of bounds already. + */ + size_t remaining = (char *)end - (char *)last; + + /* + * There must be room for both the next target spec and the + * NUL-terminator of the target itself. + */ + if (remaining - sizeof(struct dm_target_spec) <= next) { + DMERR("Target spec extends beyond end of parameters"); + return -EINVAL; + } + if (next % __alignof__(struct dm_target_spec)) { DMERR("Next dm_target_spec (offset %u) is not %zu-byte aligned", next, __alignof__(struct dm_target_spec));