summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry V. Levin <ldv@altlinux.org>2013-11-05 23:00:22 +0000
committerDmitry V. Levin <ldv@altlinux.org>2013-11-05 23:35:37 +0000
commitc2982b5b72335205849265182b23866ffbe7a16c (patch)
tree03ef7530e7cfb5878f2ab68b8a62c0c929dc3a03
parentf3696b3c8bdd32b5621f0fa126c269f13c11bfc4 (diff)
downloadstrace-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.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/desc.c b/desc.c
index 3547d96..e18735c 100644
--- a/desc.c
+++ b/desc.c
@@ -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) {