More select decoding fixes
* desc.c (decode_select): Actually print arg[0] as int on entering syscall. When arg[0] is negative, do not attempt to fetch and decode descriptor sets on entering syscall, kernel will reject it anyway. On exiting syscall, stop checking descriptor sets as soon as all returned descriptors are found.
This commit is contained in:
parent
1f65c3cd2a
commit
f3696b3c8b
46
desc.c
46
desc.c
@ -486,31 +486,39 @@ decode_select(struct tcb *tcp, long *args, enum bitness_t bitness)
|
||||
const char *sep;
|
||||
long arg;
|
||||
|
||||
/* Kernel truncates arg[0] to int, we do the same */
|
||||
fdsize = (int)args[0];
|
||||
/* Kernel truncates arg[0] to int, we do the same. */
|
||||
nfds = (int) args[0];
|
||||
|
||||
/* Kernel rejects negative nfds, so we don't parse it either. */
|
||||
if (nfds < 0) {
|
||||
nfds = 0;
|
||||
fds = NULL;
|
||||
}
|
||||
/* Beware of select(2^31-1, NULL, NULL, NULL) and similar... */
|
||||
if (fdsize > 1024*1024)
|
||||
fdsize = 1024*1024;
|
||||
if (fdsize < 0)
|
||||
fdsize = 0;
|
||||
nfds = fdsize;
|
||||
fdsize = (((fdsize + 7) / 8) + sizeof(long)-1) & -sizeof(long);
|
||||
/* We had bugs a-la "while (j < args[0])" and "umoven(args[0])" below.
|
||||
if (nfds > 1024*1024)
|
||||
nfds = 1024*1024;
|
||||
|
||||
/*
|
||||
* We had bugs a-la "while (j < args[0])" and "umoven(args[0])" below.
|
||||
* Instead of args[0], use nfds for fd count, fdsize for array lengths.
|
||||
*/
|
||||
fdsize = (((nfds + 7) / 8) + sizeof(long)-1) & -sizeof(long);
|
||||
|
||||
if (entering(tcp)) {
|
||||
fds = malloc(fdsize);
|
||||
if (!fds)
|
||||
die_out_of_memory();
|
||||
tprintf("%ld", args[0]);
|
||||
tprintf("%d", (int) args[0]);
|
||||
|
||||
if (fdsize > 0) {
|
||||
fds = malloc(fdsize);
|
||||
if (!fds)
|
||||
die_out_of_memory();
|
||||
}
|
||||
for (i = 0; i < 3; i++) {
|
||||
arg = args[i+1];
|
||||
if (arg == 0) {
|
||||
tprints(", NULL");
|
||||
continue;
|
||||
}
|
||||
if (!verbose(tcp)) {
|
||||
if (!verbose(tcp) || !fds) {
|
||||
tprintf(", %#lx", arg);
|
||||
continue;
|
||||
}
|
||||
@ -536,8 +544,7 @@ decode_select(struct tcb *tcp, long *args, enum bitness_t bitness)
|
||||
static char outstr[1024];
|
||||
char *outptr;
|
||||
#define end_outstr (outstr + sizeof(outstr))
|
||||
const char *sep;
|
||||
long ready_fds;
|
||||
int ready_fds;
|
||||
|
||||
if (syserror(tcp))
|
||||
return 0;
|
||||
@ -554,7 +561,7 @@ decode_select(struct tcb *tcp, long *args, enum bitness_t bitness)
|
||||
|
||||
outptr = outstr;
|
||||
sep = "";
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (i = 0; i < 3 && ready_fds > 0; i++) {
|
||||
int first = 1;
|
||||
|
||||
arg = args[i+1];
|
||||
@ -577,13 +584,12 @@ decode_select(struct tcb *tcp, long *args, enum bitness_t bitness)
|
||||
outptr += sprintf(outptr, " %u", j);
|
||||
}
|
||||
}
|
||||
ready_fds--;
|
||||
if (--ready_fds == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (outptr != outstr)
|
||||
*outptr++ = ']';
|
||||
if (ready_fds == 0)
|
||||
break;
|
||||
}
|
||||
free(fds);
|
||||
/* This contains no useful information on SunOS. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user