lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <web-37301778@cgp.agava.net>
From: demidov at gleg.net (Evgeny Demidov)
Subject: Re: Linux Kernel sctp_setsockopt() Integer Overflow

Hello,

>On Sat, 15 May 2004 23:07:00 +0200 (CEST)
> Jirka Kosina <jikos@...os.cz> wrote:
>On Sat, 15 May 2004, Michael Tokarev wrote:
>
>> But kmalloc(0) will return NULL, and the whole 
>>setsockopt
>> will finish with errno set to ENOMEM.
>> 
>> From 2.4 mm/slab.c:
>> void * kmalloc (size_t size, int flags)
>> {
>>         cache_sizes_t *csizep = cache_sizes;
>> 
>>         for (; csizep->cs_size; csizep++) {
>>                 if (size > csizep->cs_size)
>>                         continue;
>>                 return __kmem_cache_alloc(flags & 
>>GFP_DMA ?
>>                          csizep->cs_dmacachep : 
>>csizep->cs_cachep, flags);
>>         }
>>         return NULL;
>> }
>
>How did you come from the above snippet of the code to 
>the idea that
>kmalloc(0) returns NULL?
>
>It allocates the number of bytes equal to the closest 
>larger value of
>cache_sizes->cs_size entries ... so on typical system 
>this would be 
>something like 32 or 64 bytes, depending on the page size 
>(see 
>include/linux/kmalloc_sizes.h) ... and of course returns 
>pointer to this 
>data, which is definitely not NULL.
>

Nice advisory, there are couple of bugs like this one ;-), 
but I always thought that negative 'optlen' values are 
filtered out in sys_setsockopt (net/socket.c):

<snip>
asmlinkage long sys_setsockopt(int fd, int level, int 
optname, char *optval, int optlen)
{
         int err;
         struct socket *sock;

[!]     if (optlen < 0)
                 return -EINVAL;

         if ((sock = sockfd_lookup(fd, &err))!=NULL)
         {
                 if (level == SOL_SOCKET)
                         err=sock_setsockopt(sock,level,optname,optval,optlen);
                 else
                         err=sock->ops->setsockopt(sock, 
level, optname, optval, optlen);
                 sockfd_put(sock);
         }
         return err;
}

</snip>

Best regards
-Evgeny Demidov


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ