mirror of https://gitee.com/openkylin/linux.git
irda: prevent integer underflow in IRLMP_ENUMDEVICES
If the user-provided len is less than the expected offset, the IRLMP_ENUMDEVICES getsockopt will do a copy_to_user() with a very large size value. While this isn't be a security issue on x86 because it will get caught by the access_ok() check, it may leak large amounts of kernel heap on other architectures. In any event, this patch fixes it. Signed-off-by: Dan Rosenberg <drosenberg@vsecurity.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
1bde5ac493
commit
fdac1e0697
|
@ -2281,6 +2281,16 @@ static int irda_getsockopt(struct socket *sock, int level, int optname,
|
|||
|
||||
switch (optname) {
|
||||
case IRLMP_ENUMDEVICES:
|
||||
|
||||
/* Offset to first device entry */
|
||||
offset = sizeof(struct irda_device_list) -
|
||||
sizeof(struct irda_device_info);
|
||||
|
||||
if (len < offset) {
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Ask lmp for the current discovery log */
|
||||
discoveries = irlmp_get_discoveries(&list.len, self->mask.word,
|
||||
self->nslots);
|
||||
|
@ -2291,15 +2301,9 @@ static int irda_getsockopt(struct socket *sock, int level, int optname,
|
|||
}
|
||||
|
||||
/* Write total list length back to client */
|
||||
if (copy_to_user(optval, &list,
|
||||
sizeof(struct irda_device_list) -
|
||||
sizeof(struct irda_device_info)))
|
||||
if (copy_to_user(optval, &list, offset))
|
||||
err = -EFAULT;
|
||||
|
||||
/* Offset to first device entry */
|
||||
offset = sizeof(struct irda_device_list) -
|
||||
sizeof(struct irda_device_info);
|
||||
|
||||
/* Copy the list itself - watch for overflow */
|
||||
if (list.len > 2048) {
|
||||
err = -EINVAL;
|
||||
|
|
Loading…
Reference in New Issue