Bug#754955: marked as done (libsnmp-dev: File descriptors larger than FD_SETSIZE crash the init_snmp() function)
Your message dated Sun, 13 Oct 2019 10:00:23 + with message-id and subject line Bug#754955: fixed in net-snmp 5.8+dfsg-1 has caused the Debian Bug report #754955, regarding libsnmp-dev: File descriptors larger than FD_SETSIZE crash the init_snmp() function to be marked as done. This means that you claim that the problem has been dealt with. If this is not the case it is now your responsibility to reopen the Bug report if necessary, and/or fix the problem forthwith. (NB: If you are a system administrator and have no idea what this message is talking about, this may indicate a serious mail system misconfiguration somewhere. Please contact ow...@bugs.debian.org immediately.) -- 754955: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=754955 Debian Bug Tracking System Contact ow...@bugs.debian.org with problems --- Begin Message --- Package: libsnmp-dev Version: 5.7.2.1~dfsg-5 Severity: important Tags: patch Dear Maintainer, I was debugging a sub agent running on a thread started by a larger application. If the process used up more file descriptors than FD_SETSIZE before starting the thread which was running the sub agent, the sub agent crashed on the init_snmp() function. This should not be a problem since versions over NetSNMP 5.5 can and should use netsnmp_large_fd_set struct to deal with large file descriptors. Debugging the issue I've found that the functions used to manipulate the large file descriptor sets ( netsnmp_large_fd_setfd(), netsnmp_large_fd_clr(), netsnmp_large_fd_is_set(), netsnmp_large_fd_set_resize() ) use the macros FD_SET, FD_CLR, FD_ISSET. These macros should be size independent, however in newer versions of libc library they have an inbuilt buffer overflow protection which tests agains the FD_SETSIZE, when manipulating a file descriptor from the set. Also the functions snmp_synch_response_cb() and snmp_sess_synch_response() still use the standard fd_set struct, wich causes an infinite loop if the response is expected on a file descriptor larger than FD_SETSIZE. This is aready fixed in upstream PATCH 3394386, I've just used the fix. Attached a suggested patch. -- System Information: Debian Release: jessie/sid APT prefers trusty-updates APT policy: (500, 'trusty-updates'), (500, 'trusty-security'), (500, 'trusty'), (100, 'trusty-backports') Architecture: amd64 (x86_64) Foreign Architectures: i386 Kernel: Linux 3.13.0-30-generic (SMP w/4 CPU cores) Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Versions of packages libsnmp-dev depends on: ii libc6-dev2.19-0ubuntu6 ii libsensors4-dev 1:3.3.4-2ubuntu1 ii libsnmp305.7.2.1~dfsg-5 ii libssl-dev 1.0.1f-1ubuntu2.4 ii libwrap0-dev 7.6.q-25 ii procps 1:3.3.9-1ubuntu2 libsnmp-dev recommends no packages. libsnmp-dev suggests no packages. commit 530958fd97c34ebb213f4fb82746af126b00eb14 Author: Petr Zajicek Date: Tue Jul 15 15:20:21 2014 +0200 Bug 36980: Improved netsnmp_large_fd_set struct support in sub agents. Changes to be committed: modified: snmplib/large_fd_set.c modified: snmplib/snmp_client.c diff --git a/snmplib/large_fd_set.c b/snmplib/large_fd_set.c index 32f57b3..ffe37f8 100644 --- a/snmplib/large_fd_set.c +++ b/snmplib/large_fd_set.c @@ -79,6 +79,10 @@ netsnmp_large_fd_is_set(SOCKET fd, netsnmp_large_fd_set * fdset) #else +const unsigned int number_of_bits = (8 * (int) sizeof (__fd_mask)); +inline unsigned int pos_in_array( int fd ) { return fd / number_of_bits; } +inline __fd_mask get_mask_for_fd( int fd ) { return (__fd_mask) ( 1UL << (fd % number_of_bits) ); } + void netsnmp_large_fd_setfd(int fd, netsnmp_large_fd_set * fdset) { @@ -87,7 +91,7 @@ netsnmp_large_fd_setfd(int fd, netsnmp_large_fd_set * fdset) while (fd >= (int)fdset->lfs_setsize) netsnmp_large_fd_set_resize(fdset, 2 * (fdset->lfs_setsize + 1)); -FD_SET(fd, fdset->lfs_setptr); +((__fd_mask*)(fdset->lfs_setptr))[ pos_in_array( fd ) ] |= get_mask_for_fd( fd ); } void @@ -96,7 +100,9 @@ netsnmp_large_fd_clr(int fd, netsnmp_large_fd_set * fdset) netsnmp_assert(fd >= 0); if ((unsigned)fd < fdset->lfs_setsize) -FD_CLR(fd, fdset->lfs_setptr); +{ +((__fd_mask*)(fdset->lfs_setptr))[ pos_in_array( fd ) ] &= ~get_mask_for_fd( fd ); +} } int @@ -104,7 +110,10 @@ netsnmp_large_fd_is_set(int fd, netsnmp_large_fd_set * fdset) { netsnmp_assert(fd >= 0); -return (unsigned)fd < fdset->lfs_setsize && FD_ISSET(fd, fdset->lfs_setptr); +if( (unsigned)fd > fdset->lfs_setsize ) +return 0; + +return ((__fd_mask*)(fdset->lfs_setptr))[ pos_in_array( fd ) ] & get_mask_for_fd( fd ); } #endif @@ -182,7 +191,7 @@ netsnmp_large_fd_set_resize(netsnmp_large_fd_set * fdset, int setsize) * resized *fdset but that were not defined in the original *fdset. */ for (i = fdset->lfs_setsize; i < setsize; i++) -
Bug#754955: marked as done (libsnmp-dev: File descriptors larger than FD_SETSIZE crash the init_snmp() function)
Your message dated Wed, 7 Mar 2018 21:49:10 +1100 with message-id <20180307104910.ga18...@enc.com.au> and subject line Re: libsnmp-dev: File descriptors larger than FD_SETSIZE crash the init_snmp() function has caused the Debian Bug report #754955, regarding libsnmp-dev: File descriptors larger than FD_SETSIZE crash the init_snmp() function to be marked as done. This means that you claim that the problem has been dealt with. If this is not the case it is now your responsibility to reopen the Bug report if necessary, and/or fix the problem forthwith. (NB: If you are a system administrator and have no idea what this message is talking about, this may indicate a serious mail system misconfiguration somewhere. Please contact ow...@bugs.debian.org immediately.) -- 754955: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=754955 Debian Bug Tracking System Contact ow...@bugs.debian.org with problems --- Begin Message --- Package: libsnmp-dev Version: 5.7.2.1~dfsg-5 Severity: important Tags: patch Dear Maintainer, I was debugging a sub agent running on a thread started by a larger application. If the process used up more file descriptors than FD_SETSIZE before starting the thread which was running the sub agent, the sub agent crashed on the init_snmp() function. This should not be a problem since versions over NetSNMP 5.5 can and should use netsnmp_large_fd_set struct to deal with large file descriptors. Debugging the issue I've found that the functions used to manipulate the large file descriptor sets ( netsnmp_large_fd_setfd(), netsnmp_large_fd_clr(), netsnmp_large_fd_is_set(), netsnmp_large_fd_set_resize() ) use the macros FD_SET, FD_CLR, FD_ISSET. These macros should be size independent, however in newer versions of libc library they have an inbuilt buffer overflow protection which tests agains the FD_SETSIZE, when manipulating a file descriptor from the set. Also the functions snmp_synch_response_cb() and snmp_sess_synch_response() still use the standard fd_set struct, wich causes an infinite loop if the response is expected on a file descriptor larger than FD_SETSIZE. This is aready fixed in upstream PATCH 3394386, I've just used the fix. Attached a suggested patch. -- System Information: Debian Release: jessie/sid APT prefers trusty-updates APT policy: (500, 'trusty-updates'), (500, 'trusty-security'), (500, 'trusty'), (100, 'trusty-backports') Architecture: amd64 (x86_64) Foreign Architectures: i386 Kernel: Linux 3.13.0-30-generic (SMP w/4 CPU cores) Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Versions of packages libsnmp-dev depends on: ii libc6-dev2.19-0ubuntu6 ii libsensors4-dev 1:3.3.4-2ubuntu1 ii libsnmp305.7.2.1~dfsg-5 ii libssl-dev 1.0.1f-1ubuntu2.4 ii libwrap0-dev 7.6.q-25 ii procps 1:3.3.9-1ubuntu2 libsnmp-dev recommends no packages. libsnmp-dev suggests no packages. commit 530958fd97c34ebb213f4fb82746af126b00eb14 Author: Petr ZajicekDate: Tue Jul 15 15:20:21 2014 +0200 Bug 36980: Improved netsnmp_large_fd_set struct support in sub agents. Changes to be committed: modified: snmplib/large_fd_set.c modified: snmplib/snmp_client.c diff --git a/snmplib/large_fd_set.c b/snmplib/large_fd_set.c index 32f57b3..ffe37f8 100644 --- a/snmplib/large_fd_set.c +++ b/snmplib/large_fd_set.c @@ -79,6 +79,10 @@ netsnmp_large_fd_is_set(SOCKET fd, netsnmp_large_fd_set * fdset) #else +const unsigned int number_of_bits = (8 * (int) sizeof (__fd_mask)); +inline unsigned int pos_in_array( int fd ) { return fd / number_of_bits; } +inline __fd_mask get_mask_for_fd( int fd ) { return (__fd_mask) ( 1UL << (fd % number_of_bits) ); } + void netsnmp_large_fd_setfd(int fd, netsnmp_large_fd_set * fdset) { @@ -87,7 +91,7 @@ netsnmp_large_fd_setfd(int fd, netsnmp_large_fd_set * fdset) while (fd >= (int)fdset->lfs_setsize) netsnmp_large_fd_set_resize(fdset, 2 * (fdset->lfs_setsize + 1)); -FD_SET(fd, fdset->lfs_setptr); +((__fd_mask*)(fdset->lfs_setptr))[ pos_in_array( fd ) ] |= get_mask_for_fd( fd ); } void @@ -96,7 +100,9 @@ netsnmp_large_fd_clr(int fd, netsnmp_large_fd_set * fdset) netsnmp_assert(fd >= 0); if ((unsigned)fd < fdset->lfs_setsize) -FD_CLR(fd, fdset->lfs_setptr); +{ +((__fd_mask*)(fdset->lfs_setptr))[ pos_in_array( fd ) ] &= ~get_mask_for_fd( fd ); +} } int @@ -104,7 +110,10 @@ netsnmp_large_fd_is_set(int fd, netsnmp_large_fd_set * fdset) { netsnmp_assert(fd >= 0); -return (unsigned)fd < fdset->lfs_setsize && FD_ISSET(fd, fdset->lfs_setptr); +if( (unsigned)fd > fdset->lfs_setsize ) +return 0; + +return ((__fd_mask*)(fdset->lfs_setptr))[ pos_in_array( fd ) ] & get_mask_for_fd( fd ); } #endif @@ -182,7 +191,7 @@ netsnmp_large_fd_set_resize(netsnmp_large_fd_set * fdset, int setsize) * resized *fdset but that were not defined in the