| From fdac1e0697356ac212259f2147aa60c72e334861 Mon Sep 17 00:00:00 2001 |
| From: Dan Rosenberg <drosenberg@vsecurity.com> |
| Date: Wed, 22 Dec 2010 13:58:27 +0000 |
| Subject: irda: prevent integer underflow in IRLMP_ENUMDEVICES |
| |
| From: Dan Rosenberg <drosenberg@vsecurity.com> |
| |
| commit fdac1e0697356ac212259f2147aa60c72e334861 upstream. |
| |
| 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> |
| Cc: Moritz Muehlenhoff <jmm@debian.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| |
| --- |
| net/irda/af_irda.c | 16 +++++++++------- |
| 1 file changed, 9 insertions(+), 7 deletions(-) |
| |
| --- a/net/irda/af_irda.c |
| +++ b/net/irda/af_irda.c |
| @@ -2277,6 +2277,14 @@ static int __irda_getsockopt(struct sock |
| |
| switch (optname) { |
| case IRLMP_ENUMDEVICES: |
| + |
| + /* Offset to first device entry */ |
| + offset = sizeof(struct irda_device_list) - |
| + sizeof(struct irda_device_info); |
| + |
| + if (len < offset) |
| + return -EINVAL; |
| + |
| /* Ask lmp for the current discovery log */ |
| discoveries = irlmp_get_discoveries(&list.len, self->mask.word, |
| self->nslots); |
| @@ -2286,15 +2294,9 @@ static int __irda_getsockopt(struct sock |
| err = 0; |
| |
| /* 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) |
| { |