From: Tilghman Lesher Date: Tue, 26 Apr 2011 19:18:46 +0000 (+0000) Subject: Fix the bounds-checking code. X-Git-Tag: 1.4.42-rc1~17 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dac18ad759a587c34abdba144f546a00d71a8f19;p=thirdparty%2Fasterisk.git Fix the bounds-checking code. The code that set the bit within the select bitfield was correct, but the bounds-checking code was not. The change to that line uses the new _bitsize macro for clarity. Also, FD_ZERO macro did not zero-out anything but the first word of the bitfield, so this could have caused problems with modules using that macro with the expanded bitfield. (closes issue #18773) Reported by: jamicque Patches: 20110423__issue18773.diff.txt uploaded by tilghman (license 14) Tested by: chris-mac git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@315501 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- diff --git a/include/asterisk/select.h b/include/asterisk/select.h index 5ba189a102..50e5b8befb 100644 --- a/include/asterisk/select.h +++ b/include/asterisk/select.h @@ -42,12 +42,14 @@ typedef struct { TYPEOF_FD_SET_FDS_BITS fds_bits[ast_FDMAX / 8 / SIZEOF_FD_SET_FDS_BITS]; /* 32768 bits */ } ast_fdset; +#define _bitsize(a) (sizeof(a) * 8) + #undef FD_ZERO #define FD_ZERO(a) \ do { \ TYPEOF_FD_SET_FDS_BITS *bytes = (TYPEOF_FD_SET_FDS_BITS *) a; \ int i; \ - for (i = 0; i < sizeof(*(a)) / SIZEOF_FD_SET_FDS_BITS; i++) { \ + for (i = 0; i < ast_FDMAX / _bitsize(TYPEOF_FD_SET_FDS_BITS); i++) { \ bytes[i] = 0; \ } \ } while (0) @@ -55,10 +57,12 @@ typedef struct { #define FD_SET(fd, fds) \ do { \ TYPEOF_FD_SET_FDS_BITS *bytes = (TYPEOF_FD_SET_FDS_BITS *) fds; \ - if (fd / sizeof(*bytes) + ((fd + 1) % sizeof(*bytes) ? 1 : 0) < sizeof(*(fds))) { \ - bytes[fd / (sizeof(*bytes) * 8)] |= ((TYPEOF_FD_SET_FDS_BITS) 1) << (fd % (sizeof(*bytes) * 8)); \ + /* 32bit: FD / 32 + ((FD + 1) % 32 ? 1 : 0) < 1024 */ \ + /* 64bit: FD / 64 + ((FD + 1) % 64 ? 1 : 0) < 512 */ \ + if (fd / _bitsize(*bytes) + ((fd + 1) % _bitsize(*bytes) ? 1 : 0) < sizeof(*(fds)) / SIZEOF_FD_SET_FDS_BITS) { \ + bytes[fd / _bitsize(*bytes)] |= ((TYPEOF_FD_SET_FDS_BITS) 1) << (fd % _bitsize(*bytes)); \ } else { \ - ast_log(LOG_ERROR, "FD %d exceeds the maximum size of ast_fdset!\n", fd); \ + fprintf(stderr, "FD %d exceeds the maximum size of ast_fdset!\n", fd); \ } \ } while (0) #endif /* HAVE_VARIABLE_FDSET */