2005-05-31 Dmitry V. Levin <ldv@altlinux.org>
Deal with memory management issues. * defs.h (tprint_iov): Update prototype. * desc.c (sys_epoll_wait) [HAVE_SYS_EPOLL_H]: Do not allocate epoll_event array of arbitrary size on the stack, to avoid stack overflow. * file.c (print_xattr_val): Check for integer overflow during malloc size calculation, to avoid heap corruption. * io.c (tprint_iov) [HAVE_SYS_UIO_H]: Check for integer overflow during malloc size calculation, to avoid heap corruption. Change iovec array handling to avoid heap memory allocation. * mem.c (get_nodes) [LINUX]: Check for integer overflow during size calculation and do not allocate array of arbitrary size on the stack, to avoid stack overflow. * net.c (printcmsghdr) [HAVE_SENDMSG]: Do not allocate array of arbitrary size on the stack, to avoid stack overflow. Do not trust cmsg.cmsg_len to avoid read beyond the end of allocated object. (printmsghdr) [HAVE_SENDMSG]: Update tprint_iov() usage. * process.c (sys_setgroups): Check for integer overflow during malloc size calculation, to avoid heap corruption. Change gid_t array handling to avoid heap memory allocation. (sys_getgroups): Likewise. (sys_setgroups32) [LINUX]: Likewise. (sys_getgroups32) [LINUX]: Likewise. * stream.c (sys_poll) [HAVE_SYS_POLL_H]: Check for integer overflow during malloc size calculation, to avoid heap corruption. Change pollfd array handling to avoid heap memory allocation. * system.c (sys_sysctl) [LINUX]: Check for integer overflow during malloc size calculation, to avoid heap corruption. * util.c (dumpiov) [HAVE_SYS_UIO_H]: Check for integer overflow during malloc size calculation, to avoid heap corruption. Fixes RH#159196.
This commit is contained in:
parent
b422e0d47d
commit
aa524c88c4
2
defs.h
2
defs.h
@ -458,7 +458,7 @@ extern void printtrailer P((struct tcb *));
|
||||
extern void tabto P((int));
|
||||
extern void call_summary P((FILE *));
|
||||
extern void printtv32 P((struct tcb*, long));
|
||||
extern void tprint_iov P((struct tcb *, int, long));
|
||||
extern void tprint_iov P((struct tcb *, unsigned long, unsigned long));
|
||||
|
||||
#ifdef LINUX
|
||||
extern int internal_clone P((struct tcb *));
|
||||
|
31
desc.c
31
desc.c
@ -680,20 +680,29 @@ struct tcb *tcp;
|
||||
tprintf("{}");
|
||||
else {
|
||||
#ifdef HAVE_SYS_EPOLL_H
|
||||
struct epoll_event evs[tcp->u_rval];
|
||||
if (umove(tcp, tcp->u_arg[1], evs) == 0) {
|
||||
unsigned long i;
|
||||
tprintf("{");
|
||||
for (i = 0; i < tcp->u_rval; ++i) {
|
||||
if (i > 0)
|
||||
tprintf(", ");
|
||||
print_epoll_event(&evs[i]);
|
||||
struct epoll_event ev, *start, *cur, *end;
|
||||
int failed = 0;
|
||||
|
||||
tprintf("{");
|
||||
start = (struct epoll_event *) tcp->u_arg[1];
|
||||
end = start + tcp->u_rval;
|
||||
for (cur = start; cur < end; ++cur) {
|
||||
if (cur > start)
|
||||
tprintf(", ");
|
||||
if (umove(tcp, (long) cur, &ev) == 0)
|
||||
print_epoll_event(&ev);
|
||||
else {
|
||||
tprintf("?");
|
||||
failed = 1;
|
||||
break;
|
||||
}
|
||||
tprintf("}");
|
||||
}
|
||||
else
|
||||
tprintf("}");
|
||||
if (failed)
|
||||
tprintf(" %#lx", (long) start);
|
||||
#else
|
||||
tprintf("{...}");
|
||||
#endif
|
||||
tprintf("{...}");
|
||||
}
|
||||
tprintf(", %ld, %ld", tcp->u_arg[2], tcp->u_arg[3]);
|
||||
}
|
||||
|
5
file.c
5
file.c
@ -2347,10 +2347,11 @@ print_xattr_val(tcp, failed, arg, insize, size)
|
||||
struct tcb *tcp;
|
||||
int failed;
|
||||
unsigned long arg;
|
||||
long insize, size;
|
||||
unsigned long insize, size;
|
||||
{
|
||||
if (!failed) {
|
||||
unsigned char *buf = malloc(4 * size + 1);
|
||||
unsigned long capacity = 4 * size + 1;
|
||||
unsigned char *buf = (capacity < size) ? NULL : malloc(capacity);
|
||||
if (buf == NULL || /* probably a bogus size argument */
|
||||
umoven(tcp, arg, size, (char *) &buf[3 * size]) < 0) {
|
||||
failed = 1;
|
||||
|
56
io.c
56
io.c
@ -78,38 +78,50 @@ struct tcb *tcp;
|
||||
void
|
||||
tprint_iov(tcp, len, addr)
|
||||
struct tcb * tcp;
|
||||
int len;
|
||||
long addr;
|
||||
unsigned long len;
|
||||
unsigned long addr;
|
||||
{
|
||||
struct iovec *iov;
|
||||
int i;
|
||||
|
||||
struct iovec iov;
|
||||
unsigned long size, cur, end, abbrev_end;
|
||||
int failed = 0;
|
||||
|
||||
if (!len) {
|
||||
tprintf("[]");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((iov = (struct iovec *) malloc(len * sizeof *iov)) == NULL) {
|
||||
fprintf(stderr, "No memory");
|
||||
size = len * sizeof(iov);
|
||||
end = addr + size;
|
||||
if (!verbose(tcp) || size / sizeof(iov) != len || end < addr) {
|
||||
tprintf("%#lx", addr);
|
||||
return;
|
||||
}
|
||||
if (umoven(tcp, addr,
|
||||
len * sizeof *iov, (char *) iov) < 0) {
|
||||
tprintf("%#lx", tcp->u_arg[1]);
|
||||
if (abbrev(tcp)) {
|
||||
abbrev_end = addr + max_strlen * sizeof(iov);
|
||||
if (abbrev_end < addr)
|
||||
abbrev_end = end;
|
||||
} else {
|
||||
tprintf("[");
|
||||
for (i = 0; i < len; i++) {
|
||||
if (i)
|
||||
tprintf(", ");
|
||||
tprintf("{");
|
||||
printstr(tcp, (long) iov[i].iov_base,
|
||||
iov[i].iov_len);
|
||||
tprintf(", %lu}", (unsigned long)iov[i].iov_len);
|
||||
}
|
||||
tprintf("]");
|
||||
abbrev_end = end;
|
||||
}
|
||||
free((char *) iov);
|
||||
tprintf("[");
|
||||
for (cur = addr; cur < end; cur += sizeof(iov)) {
|
||||
if (cur > addr)
|
||||
tprintf(", ");
|
||||
if (cur >= abbrev_end) {
|
||||
tprintf("...");
|
||||
break;
|
||||
}
|
||||
if (umoven(tcp, cur, sizeof iov, (char *) &iov) < 0) {
|
||||
tprintf("?");
|
||||
failed = 1;
|
||||
break;
|
||||
}
|
||||
tprintf("{");
|
||||
printstr(tcp, (long) iov.iov_base, iov.iov_len);
|
||||
tprintf(", %lu}", (unsigned long)iov.iov_len);
|
||||
}
|
||||
tprintf("]");
|
||||
if (failed)
|
||||
tprintf(" %#lx", addr);
|
||||
}
|
||||
|
||||
int
|
||||
|
53
mem.c
53
mem.c
@ -692,26 +692,43 @@ unsigned long ptr;
|
||||
unsigned long maxnodes;
|
||||
int err;
|
||||
{
|
||||
int nlongs = (maxnodes + 8 * sizeof(long) - 1) / (8 * sizeof(long));
|
||||
if (err || !abbrev(tcp) || nlongs > getpagesize() / sizeof(long)
|
||||
|| nlongs == 0) {
|
||||
long buf[nlongs];
|
||||
if (umoven(tcp, ptr, nlongs * sizeof(long),
|
||||
(char *) buf) < 0)
|
||||
tprintf(", %lx", ptr);
|
||||
else {
|
||||
int i;
|
||||
tprintf(", {");
|
||||
for (i = 0; i < nlongs; ++i) {
|
||||
if (i > 0)
|
||||
tprintf(", ");
|
||||
tprintf("%#0*lx", (int) sizeof(long) * 2 + 2,
|
||||
buf[i]);
|
||||
}
|
||||
tprintf("}");
|
||||
unsigned long nlongs, size, end;
|
||||
|
||||
nlongs = (maxnodes + 8 * sizeof(long) - 1) / (8 * sizeof(long));
|
||||
size = nlongs * sizeof(long);
|
||||
end = ptr + size;
|
||||
if (nlongs == 0 || ((err || verbose(tcp)) && (size * 8 == maxnodes)
|
||||
&& (end > ptr))) {
|
||||
unsigned long n, cur, abbrev_end;
|
||||
int failed = 0;
|
||||
|
||||
if (abbrev(tcp)) {
|
||||
abbrev_end = ptr + max_strlen * sizeof(long);
|
||||
if (abbrev_end < ptr)
|
||||
abbrev_end = end;
|
||||
} else {
|
||||
abbrev_end = end;
|
||||
}
|
||||
tprintf(", {");
|
||||
for (cur = ptr; cur < end; cur += sizeof(long)) {
|
||||
if (cur > ptr)
|
||||
tprintf(", ");
|
||||
if (cur >= abbrev_end) {
|
||||
tprintf("...");
|
||||
break;
|
||||
}
|
||||
if (umoven(tcp, cur, sizeof(n), (char *) &n) < 0) {
|
||||
tprintf("?");
|
||||
failed = 1;
|
||||
break;
|
||||
}
|
||||
tprintf("%#0*lx", (int) sizeof(long) * 2 + 2, n);
|
||||
}
|
||||
tprintf("}");
|
||||
if (failed)
|
||||
tprintf(" %#lx", ptr);
|
||||
} else
|
||||
tprintf(", %lx", ptr);
|
||||
tprintf(", %#lx", ptr);
|
||||
tprintf(", %lu", maxnodes);
|
||||
}
|
||||
|
||||
|
42
net.c
42
net.c
@ -1082,44 +1082,51 @@ struct tcb *tcp;
|
||||
unsigned long addr;
|
||||
unsigned long len;
|
||||
{
|
||||
union {
|
||||
char msg_control[len];
|
||||
struct cmsghdr cmsg;
|
||||
} u;
|
||||
if (umoven(tcp, addr, len, u.msg_control) < 0) {
|
||||
struct cmsghdr *cmsg = len < sizeof(struct cmsghdr) ?
|
||||
NULL : malloc(len);
|
||||
if (cmsg == NULL || umoven(tcp, addr, len, (char *) cmsg) < 0) {
|
||||
tprintf(", msg_control=%#lx", addr);
|
||||
free(cmsg);
|
||||
return;
|
||||
}
|
||||
|
||||
tprintf(", {cmsg_len=%zu, cmsg_level=", u.cmsg.cmsg_len);
|
||||
printxval(socketlayers, u.cmsg.cmsg_level, "SOL_???");
|
||||
tprintf(", {cmsg_len=%zu, cmsg_level=", cmsg->cmsg_len);
|
||||
printxval(socketlayers, cmsg->cmsg_level, "SOL_???");
|
||||
tprintf(", cmsg_type=");
|
||||
|
||||
if (u.cmsg.cmsg_level == SOL_SOCKET) {
|
||||
printxval(scmvals, u.cmsg.cmsg_type, "SCM_???");
|
||||
if (cmsg->cmsg_level == SOL_SOCKET) {
|
||||
unsigned long cmsg_len;
|
||||
|
||||
if (u.cmsg.cmsg_type == SCM_RIGHTS) {
|
||||
int *fds = (int *) CMSG_DATA (&u.cmsg);
|
||||
printxval(scmvals, cmsg->cmsg_type, "SCM_???");
|
||||
cmsg_len = (len < cmsg->cmsg_len) ? len : cmsg->cmsg_len;
|
||||
|
||||
if (cmsg->cmsg_type == SCM_RIGHTS
|
||||
&& CMSG_LEN(sizeof(int)) <= cmsg_len) {
|
||||
int *fds = (int *) CMSG_DATA (cmsg);
|
||||
int first = 1;
|
||||
|
||||
tprintf(", {");
|
||||
while ((char *) fds < (u.msg_control
|
||||
+ u.cmsg.cmsg_len)) {
|
||||
while ((char *) fds < ((char *) cmsg + cmsg_len)) {
|
||||
if (!first)
|
||||
tprintf(", ");
|
||||
tprintf("%d", *fds++);
|
||||
first = 0;
|
||||
}
|
||||
tprintf("}}");
|
||||
free(cmsg);
|
||||
return;
|
||||
}
|
||||
if (u.cmsg.cmsg_type == SCM_CREDENTIALS
|
||||
&& CMSG_LEN(sizeof(struct ucred)) <= u.cmsg.cmsg_len) {
|
||||
struct ucred *uc = (struct ucred *) CMSG_DATA (&u.cmsg);
|
||||
if (cmsg->cmsg_type == SCM_CREDENTIALS
|
||||
&& CMSG_LEN(sizeof(struct ucred)) <= cmsg_len) {
|
||||
struct ucred *uc = (struct ucred *) CMSG_DATA (cmsg);
|
||||
|
||||
tprintf("{pid=%ld, uid=%ld, gid=%ld}}",
|
||||
(long)uc->pid, (long)uc->uid, (long)uc->gid);
|
||||
free(cmsg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
free(cmsg);
|
||||
tprintf(", ...}");
|
||||
}
|
||||
|
||||
@ -1138,7 +1145,8 @@ long addr;
|
||||
printsock(tcp, (long)msg.msg_name, msg.msg_namelen);
|
||||
|
||||
tprintf(", msg_iov(%lu)=", (unsigned long)msg.msg_iovlen);
|
||||
tprint_iov(tcp, msg.msg_iovlen, (long) msg.msg_iov);
|
||||
tprint_iov(tcp, (unsigned long)msg.msg_iovlen,
|
||||
(unsigned long)msg.msg_iov);
|
||||
|
||||
#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
|
||||
tprintf(", msg_controllen=%lu", (unsigned long)msg.msg_controllen);
|
||||
|
254
process.c
254
process.c
@ -1225,34 +1225,53 @@ int
|
||||
sys_setgroups(tcp)
|
||||
struct tcb *tcp;
|
||||
{
|
||||
int i, len;
|
||||
GETGROUPS_T *gidset;
|
||||
|
||||
if (entering(tcp)) {
|
||||
unsigned long len, size, start, cur, end, abbrev_end;
|
||||
GETGROUPS_T gid;
|
||||
int failed = 0;
|
||||
|
||||
len = tcp->u_arg[0];
|
||||
tprintf("%u, ", len);
|
||||
if (len <= 0) {
|
||||
tprintf("%lu, ", len);
|
||||
if (len == 0) {
|
||||
tprintf("[]");
|
||||
return 0;
|
||||
}
|
||||
gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
|
||||
if (gidset == NULL) {
|
||||
fprintf(stderr, "sys_setgroups: out of memory\n");
|
||||
return -1;
|
||||
start = tcp->u_arg[1];
|
||||
if (start == 0) {
|
||||
tprintf("NULL");
|
||||
return 0;
|
||||
}
|
||||
if (!verbose(tcp))
|
||||
tprintf("%#lx", tcp->u_arg[1]);
|
||||
else if (umoven(tcp, tcp->u_arg[1],
|
||||
len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
|
||||
tprintf("[?]");
|
||||
else {
|
||||
tprintf("[");
|
||||
for (i = 0; i < len; i++)
|
||||
tprintf("%s%lu", i ? ", " : "",
|
||||
(unsigned long) gidset[i]);
|
||||
tprintf("]");
|
||||
size = len * sizeof(gid);
|
||||
end = start + size;
|
||||
if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
|
||||
tprintf("%#lx", start);
|
||||
return 0;
|
||||
}
|
||||
free((char *) gidset);
|
||||
if (abbrev(tcp)) {
|
||||
abbrev_end = start + max_strlen * sizeof(gid);
|
||||
if (abbrev_end < start)
|
||||
abbrev_end = end;
|
||||
} else {
|
||||
abbrev_end = end;
|
||||
}
|
||||
tprintf("[");
|
||||
for (cur = start; cur < end; cur += sizeof(gid)) {
|
||||
if (cur > start)
|
||||
tprintf(", ");
|
||||
if (cur >= abbrev_end) {
|
||||
tprintf("...");
|
||||
break;
|
||||
}
|
||||
if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
|
||||
tprintf("?");
|
||||
failed = 1;
|
||||
break;
|
||||
}
|
||||
tprintf("%lu", (unsigned long) gid);
|
||||
}
|
||||
tprintf("]");
|
||||
if (failed)
|
||||
tprintf(" %#lx", tcp->u_arg[1]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -1261,38 +1280,62 @@ int
|
||||
sys_getgroups(tcp)
|
||||
struct tcb *tcp;
|
||||
{
|
||||
int i, len;
|
||||
GETGROUPS_T *gidset;
|
||||
unsigned long len;
|
||||
|
||||
if (entering(tcp)) {
|
||||
len = tcp->u_arg[0];
|
||||
tprintf("%u, ", len);
|
||||
tprintf("%lu, ", len);
|
||||
} else {
|
||||
unsigned long size, start, cur, end, abbrev_end;
|
||||
GETGROUPS_T gid;
|
||||
int failed = 0;
|
||||
|
||||
len = tcp->u_rval;
|
||||
if (len <= 0) {
|
||||
if (len == 0) {
|
||||
tprintf("[]");
|
||||
return 0;
|
||||
}
|
||||
gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
|
||||
if (gidset == NULL) {
|
||||
fprintf(stderr, "sys_getgroups: out of memory\n");
|
||||
return -1;
|
||||
}
|
||||
if (!tcp->u_arg[1])
|
||||
start = tcp->u_arg[1];
|
||||
if (start == 0) {
|
||||
tprintf("NULL");
|
||||
else if (!verbose(tcp) || tcp->u_arg[0] == 0)
|
||||
tprintf("%#lx", tcp->u_arg[1]);
|
||||
else if (umoven(tcp, tcp->u_arg[1],
|
||||
len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
|
||||
tprintf("[?]");
|
||||
else {
|
||||
tprintf("[");
|
||||
for (i = 0; i < len; i++)
|
||||
tprintf("%s%lu", i ? ", " : "",
|
||||
(unsigned long) gidset[i]);
|
||||
tprintf("]");
|
||||
return 0;
|
||||
}
|
||||
free((char *)gidset);
|
||||
if (tcp->u_arg[0] == 0) {
|
||||
tprintf("%#lx", start);
|
||||
return 0;
|
||||
}
|
||||
size = len * sizeof(gid);
|
||||
end = start + size;
|
||||
if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
|
||||
size / sizeof(gid) != len || end < start) {
|
||||
tprintf("%#lx", start);
|
||||
return 0;
|
||||
}
|
||||
if (abbrev(tcp)) {
|
||||
abbrev_end = start + max_strlen * sizeof(gid);
|
||||
if (abbrev_end < start)
|
||||
abbrev_end = end;
|
||||
} else {
|
||||
abbrev_end = end;
|
||||
}
|
||||
tprintf("[");
|
||||
for (cur = start; cur < end; cur += sizeof(gid)) {
|
||||
if (cur > start)
|
||||
tprintf(", ");
|
||||
if (cur >= abbrev_end) {
|
||||
tprintf("...");
|
||||
break;
|
||||
}
|
||||
if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
|
||||
tprintf("?");
|
||||
failed = 1;
|
||||
break;
|
||||
}
|
||||
tprintf("%lu", (unsigned long) gid);
|
||||
}
|
||||
tprintf("]");
|
||||
if (failed)
|
||||
tprintf(" %#lx", tcp->u_arg[1]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -1302,34 +1345,53 @@ int
|
||||
sys_setgroups32(tcp)
|
||||
struct tcb *tcp;
|
||||
{
|
||||
int i, len;
|
||||
GETGROUPS32_T *gidset;
|
||||
|
||||
if (entering(tcp)) {
|
||||
unsigned long len, size, start, cur, end, abbrev_end;
|
||||
GETGROUPS32_T gid;
|
||||
int failed = 0;
|
||||
|
||||
len = tcp->u_arg[0];
|
||||
tprintf("%u, ", len);
|
||||
if (len <= 0) {
|
||||
tprintf("%lu, ", len);
|
||||
if (len == 0) {
|
||||
tprintf("[]");
|
||||
return 0;
|
||||
}
|
||||
gidset = (GETGROUPS32_T *) malloc(len * sizeof(GETGROUPS32_T));
|
||||
if (gidset == NULL) {
|
||||
fprintf(stderr, "sys_setgroups32: out of memory\n");
|
||||
return -1;
|
||||
start = tcp->u_arg[1];
|
||||
if (start == 0) {
|
||||
tprintf("NULL");
|
||||
return 0;
|
||||
}
|
||||
if (!verbose(tcp))
|
||||
tprintf("%#lx", tcp->u_arg[1]);
|
||||
else if (umoven(tcp, tcp->u_arg[1],
|
||||
len * sizeof(GETGROUPS32_T), (char *) gidset) < 0)
|
||||
tprintf("[?]");
|
||||
else {
|
||||
tprintf("[");
|
||||
for (i = 0; i < len; i++)
|
||||
tprintf("%s%lu", i ? ", " : "",
|
||||
(unsigned long) gidset[i]);
|
||||
tprintf("]");
|
||||
size = len * sizeof(gid);
|
||||
end = start + size;
|
||||
if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
|
||||
tprintf("%#lx", start);
|
||||
return 0;
|
||||
}
|
||||
free((char *) gidset);
|
||||
if (abbrev(tcp)) {
|
||||
abbrev_end = start + max_strlen * sizeof(gid);
|
||||
if (abbrev_end < start)
|
||||
abbrev_end = end;
|
||||
} else {
|
||||
abbrev_end = end;
|
||||
}
|
||||
tprintf("[");
|
||||
for (cur = start; cur < end; cur += sizeof(gid)) {
|
||||
if (cur > start)
|
||||
tprintf(", ");
|
||||
if (cur >= abbrev_end) {
|
||||
tprintf("...");
|
||||
break;
|
||||
}
|
||||
if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
|
||||
tprintf("?");
|
||||
failed = 1;
|
||||
break;
|
||||
}
|
||||
tprintf("%lu", (unsigned long) gid);
|
||||
}
|
||||
tprintf("]");
|
||||
if (failed)
|
||||
tprintf(" %#lx", tcp->u_arg[1]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -1338,38 +1400,58 @@ int
|
||||
sys_getgroups32(tcp)
|
||||
struct tcb *tcp;
|
||||
{
|
||||
int i, len;
|
||||
GETGROUPS32_T *gidset;
|
||||
unsigned long len;
|
||||
|
||||
if (entering(tcp)) {
|
||||
len = tcp->u_arg[0];
|
||||
tprintf("%u, ", len);
|
||||
tprintf("%lu, ", len);
|
||||
} else {
|
||||
unsigned long size, start, cur, end, abbrev_end;
|
||||
GETGROUPS32_T gid;
|
||||
int failed = 0;
|
||||
|
||||
len = tcp->u_rval;
|
||||
if (len <= 0) {
|
||||
if (len == 0) {
|
||||
tprintf("[]");
|
||||
return 0;
|
||||
}
|
||||
gidset = (GETGROUPS32_T *) malloc(len * sizeof(GETGROUPS32_T));
|
||||
if (gidset == NULL) {
|
||||
fprintf(stderr, "sys_getgroups32: out of memory\n");
|
||||
return -1;
|
||||
}
|
||||
if (!tcp->u_arg[1])
|
||||
start = tcp->u_arg[1];
|
||||
if (start == 0) {
|
||||
tprintf("NULL");
|
||||
else if (!verbose(tcp) || tcp->u_arg[0] == 0)
|
||||
tprintf("%#lx", tcp->u_arg[1]);
|
||||
else if (umoven(tcp, tcp->u_arg[1],
|
||||
len * sizeof(GETGROUPS32_T), (char *) gidset) < 0)
|
||||
tprintf("[?]");
|
||||
else {
|
||||
tprintf("[");
|
||||
for (i = 0; i < len; i++)
|
||||
tprintf("%s%lu", i ? ", " : "",
|
||||
(unsigned long) gidset[i]);
|
||||
tprintf("]");
|
||||
return 0;
|
||||
}
|
||||
free((char *)gidset);
|
||||
size = len * sizeof(gid);
|
||||
end = start + size;
|
||||
if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
|
||||
size / sizeof(gid) != len || end < start) {
|
||||
tprintf("%#lx", start);
|
||||
return 0;
|
||||
}
|
||||
if (abbrev(tcp)) {
|
||||
abbrev_end = start + max_strlen * sizeof(gid);
|
||||
if (abbrev_end < start)
|
||||
abbrev_end = end;
|
||||
} else {
|
||||
abbrev_end = end;
|
||||
}
|
||||
tprintf("[");
|
||||
for (cur = start; cur < end; cur += sizeof(gid)) {
|
||||
if (cur > start)
|
||||
tprintf(", ");
|
||||
if (cur >= abbrev_end) {
|
||||
tprintf("...");
|
||||
break;
|
||||
}
|
||||
if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
|
||||
tprintf("?");
|
||||
failed = 1;
|
||||
break;
|
||||
}
|
||||
tprintf("%lu", (unsigned long) gid);
|
||||
}
|
||||
tprintf("]");
|
||||
if (failed)
|
||||
tprintf(" %#lx", tcp->u_arg[1]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
106
stream.c
106
stream.c
@ -298,61 +298,69 @@ int
|
||||
sys_poll(tcp)
|
||||
struct tcb *tcp;
|
||||
{
|
||||
struct pollfd *pollp;
|
||||
struct pollfd fds;
|
||||
unsigned nfds;
|
||||
unsigned long size, start, cur, end, abbrev_end;
|
||||
int failed = 0;
|
||||
|
||||
if (exiting(tcp)) {
|
||||
int i;
|
||||
int nfds = tcp->u_arg[1];
|
||||
if (entering(tcp))
|
||||
return 0;
|
||||
|
||||
if (nfds <= 0) {
|
||||
tprintf("%#lx, %d, %ld\n",
|
||||
tcp->u_arg[0], nfds, tcp->u_arg[2]);
|
||||
return 0;
|
||||
}
|
||||
pollp = (struct pollfd *) malloc(nfds * sizeof(*pollp));
|
||||
if (pollp == NULL) {
|
||||
fprintf(stderr, "sys_poll: no memory\n");
|
||||
tprintf("%#lx, %d, %ld",
|
||||
tcp->u_arg[0], nfds, tcp->u_arg[2]);
|
||||
return 0;
|
||||
}
|
||||
if (umoven(tcp, tcp->u_arg[0],
|
||||
(nfds * sizeof(*pollp)), (char *) pollp) < 0) {
|
||||
tprintf("%#lx", tcp->u_arg[0]);
|
||||
}
|
||||
else {
|
||||
tprintf("[");
|
||||
for (i = 0; i < nfds; i++) {
|
||||
if (i)
|
||||
tprintf(", ");
|
||||
if (pollp[i].fd < 0) {
|
||||
tprintf("{fd=%d}", pollp[i].fd);
|
||||
continue;
|
||||
}
|
||||
tprintf("{fd=%d, events=", pollp[i].fd);
|
||||
printflags(pollflags, pollp[i].events,
|
||||
"POLL???");
|
||||
if (!syserror(tcp) && pollp[i].revents) {
|
||||
tprintf(", revents=");
|
||||
printflags(pollflags, pollp[i].revents,
|
||||
"POLL???");
|
||||
}
|
||||
tprintf("}");
|
||||
}
|
||||
tprintf("]");
|
||||
}
|
||||
tprintf(", %d, ", nfds);
|
||||
#ifdef INFTIM
|
||||
if (tcp->u_arg[2] == INFTIM)
|
||||
tprintf("INFTIM");
|
||||
else
|
||||
#endif
|
||||
tprintf("%ld", tcp->u_arg[2]);
|
||||
free(pollp);
|
||||
nfds = tcp->u_arg[1];
|
||||
size = sizeof(fds) * nfds;
|
||||
start = tcp->u_arg[0];
|
||||
end = start + size;
|
||||
if (nfds == 0 || size / sizeof(fds) != nfds || end < start) {
|
||||
tprintf("%#lx, %d, %ld",
|
||||
tcp->u_arg[0], nfds, tcp->u_arg[2]);
|
||||
return 0;
|
||||
}
|
||||
if (abbrev(tcp)) {
|
||||
abbrev_end = start + max_strlen * sizeof(fds);
|
||||
if (abbrev_end < start)
|
||||
abbrev_end = end;
|
||||
} else {
|
||||
abbrev_end = end;
|
||||
}
|
||||
tprintf("[");
|
||||
for (cur = start; cur < end; cur += sizeof(fds)) {
|
||||
if (cur > start)
|
||||
tprintf(", ");
|
||||
if (cur >= abbrev_end) {
|
||||
tprintf("...");
|
||||
break;
|
||||
}
|
||||
if (umoven(tcp, cur, sizeof fds, (char *) &fds) < 0) {
|
||||
tprintf("?");
|
||||
failed = 1;
|
||||
break;
|
||||
}
|
||||
if (fds.fd < 0) {
|
||||
tprintf("{fd=%d}", fds.fd);
|
||||
continue;
|
||||
}
|
||||
tprintf("{fd=%d, events=", fds.fd);
|
||||
printflags(pollflags, fds.events, "POLL???");
|
||||
if (!syserror(tcp) && fds.revents) {
|
||||
tprintf(", revents=");
|
||||
printflags(pollflags, fds.revents, "POLL???");
|
||||
}
|
||||
tprintf("}");
|
||||
}
|
||||
tprintf("]");
|
||||
if (failed)
|
||||
tprintf(" %#lx", start);
|
||||
tprintf(", %d, ", nfds);
|
||||
#ifdef INFTIM
|
||||
if (tcp->u_arg[2] == INFTIM)
|
||||
tprintf("INFTIM");
|
||||
else
|
||||
#endif
|
||||
tprintf("%ld", tcp->u_arg[2]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#else /* !HAVE_SYS_POLL_H */
|
||||
int
|
||||
sys_poll(tcp)
|
||||
|
29
system.c
29
system.c
@ -1813,23 +1813,25 @@ struct tcb *tcp;
|
||||
{
|
||||
struct __sysctl_args info;
|
||||
int *name;
|
||||
unsigned long size;
|
||||
|
||||
if (umove (tcp, tcp->u_arg[0], &info) < 0)
|
||||
return printargs(tcp);
|
||||
|
||||
name = malloc (sizeof (int) * info.nlen);
|
||||
size = sizeof (int) * (unsigned long) info.nlen;
|
||||
name = (size / sizeof (int) != info.nlen) ? NULL : malloc (size);
|
||||
if (name == NULL ||
|
||||
umoven(tcp, (unsigned long) info.name,
|
||||
sizeof (int) * info.nlen, (char *) name) < 0) {
|
||||
if (name != NULL)
|
||||
free(name);
|
||||
tprintf("{%p, %d, %p, %p, %p, %Zu}",
|
||||
info.name, info.nlen, info.oldval, info.oldlenp,
|
||||
info.newval, info.newlen);
|
||||
umoven(tcp, (unsigned long) info.name, size, (char *) name) < 0) {
|
||||
free(name);
|
||||
if (entering(tcp))
|
||||
tprintf("{%p, %d, %p, %p, %p, %Zu}",
|
||||
info.name, info.nlen, info.oldval,
|
||||
info.oldlenp, info.newval, info.newlen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (entering(tcp)) {
|
||||
int cnt = 0;
|
||||
int cnt = 0, max_cnt;
|
||||
|
||||
tprintf("{{");
|
||||
|
||||
@ -1919,13 +1921,16 @@ struct tcb *tcp;
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
while (cnt < info.nlen)
|
||||
max_cnt = abbrev(tcp) ? max_strlen : info.nlen;
|
||||
while (cnt < max_cnt)
|
||||
tprintf(", %x", name[cnt++]);
|
||||
if (cnt < info.nlen)
|
||||
tprintf(", ...");
|
||||
tprintf("}, %d, ", info.nlen);
|
||||
} else {
|
||||
size_t oldlen;
|
||||
umove(tcp, (size_t)info.oldlenp, &oldlen);
|
||||
if (info.nlen >= 2
|
||||
if (umove(tcp, (size_t)info.oldlenp, &oldlen) >= 0
|
||||
&& info.nlen >= 2
|
||||
&& ((name[0] == CTL_KERN
|
||||
&& (name[1] == KERN_OSRELEASE
|
||||
|| name[1] == KERN_OSTYPE
|
||||
|
12
util.c
12
util.c
@ -532,15 +532,15 @@ long addr;
|
||||
{
|
||||
struct iovec *iov;
|
||||
int i;
|
||||
unsigned long size;
|
||||
|
||||
|
||||
if ((iov = (struct iovec *) malloc(len * sizeof *iov)) == NULL) {
|
||||
fprintf(stderr, "dump: No memory");
|
||||
size = sizeof(*iov) * (unsigned long) len;
|
||||
if (size / sizeof(*iov) != len
|
||||
|| (iov = (struct iovec *) malloc(size)) == NULL) {
|
||||
fprintf(stderr, "out of memory\n");
|
||||
return;
|
||||
}
|
||||
if (umoven(tcp, addr,
|
||||
len * sizeof *iov, (char *) iov) >= 0) {
|
||||
|
||||
if (umoven(tcp, addr, size, (char *) iov) >= 0) {
|
||||
for (i = 0; i < len; i++) {
|
||||
/* include the buffer number to make it easy to
|
||||
* match up the trace with the source */
|
||||
|
Loading…
x
Reference in New Issue
Block a user