diff options
author | Dmitry V. Levin <ldv@altlinux.org> | 2013-11-05 23:00:22 +0000 |
---|---|---|
committer | Dmitry V. Levin <ldv@altlinux.org> | 2013-11-05 23:35:37 +0000 |
commit | c2982b5b72335205849265182b23866ffbe7a16c (patch) | |
tree | 03ef7530e7cfb5878f2ab68b8a62c0c929dc3a03 | |
parent | f3696b3c8bdd32b5621f0fa126c269f13c11bfc4 (diff) | |
download | strace-c2982b5b72335205849265182b23866ffbe7a16c.tar.gz strace-c2982b5b72335205849265182b23866ffbe7a16c.tar.bz2 strace-c2982b5b72335205849265182b23866ffbe7a16c.tar.xz |
Fix select decoding for glibc in _FORTIFY_SOURCE mode
glibc in _FORTIFY_SOURCE mode raises SIGABRT when descriptor greater
or equal to FD_SETSIZE is passed to FD_ISSET. Select family syscalls,
however, can legitimately accept such descriptors. To overcome this
limitation, we have to replace FD_ISSET with an equivalent that imposes
no such restrictions.
* desc.c (fd_isset): New function.
(decode_select): Use it instead of FD_ISSET.
-rw-r--r-- | desc.c | 12 |
1 files changed, 10 insertions, 2 deletions
@@ -478,6 +478,14 @@ sys_getdtablesize(struct tcb *tcp) #endif static int +fd_isset(int d, fd_set *fds) +{ + const int bpl = 8 * sizeof(long); + long *s = (long *) fds; + return !!(s[d / bpl] & (1L << (d % bpl))); +} + +static int decode_select(struct tcb *tcp, long *args, enum bitness_t bitness) { int i, j; @@ -528,7 +536,7 @@ decode_select(struct tcb *tcp, long *args, enum bitness_t bitness) } tprints(", ["); for (j = 0, sep = ""; j < nfds; j++) { - if (FD_ISSET(j, fds)) { + if (fd_isset(j, fds)) { tprints(sep); printfd(tcp, j); sep = " "; @@ -568,7 +576,7 @@ decode_select(struct tcb *tcp, long *args, enum bitness_t bitness) if (!arg || umoven(tcp, arg, fdsize, (char *) fds) < 0) continue; for (j = 0; j < nfds; j++) { - if (FD_ISSET(j, fds)) { + if (fd_isset(j, fds)) { /* +2 chars needed at the end: ']',NUL */ if (outptr < end_outstr - (sizeof(", except [") + sizeof(int)*3 + 2)) { if (first) { |