Make out-of-memory handling more uniform
This fixes one real bug in dumpstr(). * defs.h: Declare die_out_of_memory(). * strace.c (die_out_of_memory): New function. (strace_popen): If allocation fails, call die_out_of_memory(). (main): Likewise. (expand_tcbtab): Likewise. (rebuild_pollv): Likewise. * count.c (count_syscall): Likewise. (call_summary_pers): Likewise. * desc.c (decode_select): Likewise. * file.c (sys_getdents): Likewise. (sys_getdents64): Likewise. (sys_getdirentries): Likewise. * pathtrace.c (pathtrace_match): Likewise. * syscall.c (qualify): Likewise. * util.c (printstr): Likewise. (dumpiov): Likewise. (dumpstr): Likewise. (fixvfork): Likewise. * mem.c (sys_mincore): Don't check free() parameter for NULL. Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
This commit is contained in:
parent
2fb4db3e7a
commit
1d46ba57a8
13
count.c
13
count.c
@ -55,11 +55,8 @@ count_syscall(struct tcb *tcp, struct timeval *tv)
|
||||
|
||||
if (!counts) {
|
||||
counts = calloc(nsyscalls, sizeof(*counts));
|
||||
if (!counts) {
|
||||
fprintf(stderr,
|
||||
"strace: out of memory for call counts\n");
|
||||
exit(1);
|
||||
}
|
||||
if (!counts)
|
||||
die_out_of_memory();
|
||||
}
|
||||
|
||||
counts[tcp->scno].calls++;
|
||||
@ -157,10 +154,8 @@ call_summary_pers(FILE *outf)
|
||||
char error_str[16];
|
||||
int *sorted_count = calloc(sizeof(int), nsyscalls);
|
||||
|
||||
if (!sorted_count) {
|
||||
fprintf(stderr, "strace: out of memory for call summary\n");
|
||||
return;
|
||||
}
|
||||
if (!sorted_count)
|
||||
die_out_of_memory();
|
||||
|
||||
call_cum = error_cum = tv_cum.tv_sec = tv_cum.tv_usec = 0;
|
||||
if (overhead.tv_sec == -1) {
|
||||
|
1
defs.h
1
defs.h
@ -580,6 +580,7 @@ void error_msg(const char *fmt, ...) __attribute__ ((format(printf, 1, 2)));
|
||||
void perror_msg(const char *fmt, ...) __attribute__ ((format(printf, 1, 2)));
|
||||
void error_msg_and_die(const char *fmt, ...) __attribute__ ((noreturn, format(printf, 1, 2)));
|
||||
void perror_msg_and_die(const char *fmt, ...) __attribute__ ((noreturn, format(printf, 1, 2)));
|
||||
void die_out_of_memory(void) __attribute__ ((noreturn));
|
||||
|
||||
extern void set_personality(int personality);
|
||||
extern const char *xlookup(const struct xlat *, int);
|
||||
|
15
desc.c
15
desc.c
@ -497,9 +497,9 @@ decode_select(struct tcb *tcp, long *args, enum bitness_t bitness)
|
||||
long arg;
|
||||
|
||||
if (entering(tcp)) {
|
||||
fds = (fd_set *) malloc(fdsize);
|
||||
if (fds == NULL)
|
||||
fprintf(stderr, "out of memory\n");
|
||||
fds = malloc(fdsize);
|
||||
if (!fds)
|
||||
die_out_of_memory();
|
||||
nfds = args[0];
|
||||
tprintf("%d", nfds);
|
||||
for (i = 0; i < 3; i++) {
|
||||
@ -508,7 +508,7 @@ decode_select(struct tcb *tcp, long *args, enum bitness_t bitness)
|
||||
tprintf(", NULL");
|
||||
continue;
|
||||
}
|
||||
if (fds == NULL || !verbose(tcp)) {
|
||||
if (!verbose(tcp)) {
|
||||
tprintf(", %#lx", arg);
|
||||
continue;
|
||||
}
|
||||
@ -546,8 +546,8 @@ decode_select(struct tcb *tcp, long *args, enum bitness_t bitness)
|
||||
}
|
||||
|
||||
fds = malloc(fdsize);
|
||||
if (fds == NULL)
|
||||
fprintf(stderr, "out of memory\n");
|
||||
if (!fds)
|
||||
die_out_of_memory();
|
||||
|
||||
tcp->auxstr = outstr;
|
||||
outptr = outstr;
|
||||
@ -556,8 +556,7 @@ decode_select(struct tcb *tcp, long *args, enum bitness_t bitness)
|
||||
int first = 1;
|
||||
|
||||
arg = args[i+1];
|
||||
if (fds == NULL || !arg ||
|
||||
umoven(tcp, arg, fdsize, (char *) fds) < 0)
|
||||
if (!arg || umoven(tcp, arg, fdsize, (char *) fds) < 0)
|
||||
continue;
|
||||
for (j = 0; j < args[0]; j++) {
|
||||
if (FD_ISSET(j, fds)) {
|
||||
|
21
file.c
21
file.c
@ -2422,11 +2422,8 @@ sys_getdents(struct tcb *tcp)
|
||||
}
|
||||
len = tcp->u_rval;
|
||||
buf = len ? malloc(len) : NULL;
|
||||
if (len && !buf) {
|
||||
tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
|
||||
fprintf(stderr, "out of memory\n");
|
||||
return 0;
|
||||
}
|
||||
if (len && !buf)
|
||||
die_out_of_memory();
|
||||
if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
|
||||
tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
|
||||
free(buf);
|
||||
@ -2507,11 +2504,8 @@ sys_getdents64(struct tcb *tcp)
|
||||
}
|
||||
len = tcp->u_rval;
|
||||
buf = len ? malloc(len) : NULL;
|
||||
if (len && !buf) {
|
||||
tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
|
||||
fprintf(stderr, "out of memory\n");
|
||||
return 0;
|
||||
}
|
||||
if (len && !buf)
|
||||
die_out_of_memory();
|
||||
if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
|
||||
tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
|
||||
free(buf);
|
||||
@ -2581,11 +2575,8 @@ sys_getdirentries(struct tcb *tcp)
|
||||
}
|
||||
len = tcp->u_rval;
|
||||
buf = malloc(len);
|
||||
if (buf == NULL) {
|
||||
tprintf("%#lx, %lu, %#lx", tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3]);
|
||||
fprintf(stderr, "out of memory\n");
|
||||
return 0;
|
||||
}
|
||||
if (!buf)
|
||||
die_out_of_memory();
|
||||
if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
|
||||
tprintf("%#lx, %lu, %#lx", tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3]);
|
||||
free(buf);
|
||||
|
9
mem.c
9
mem.c
@ -564,12 +564,12 @@ sys_mctl(struct tcb *tcp)
|
||||
int
|
||||
sys_mincore(struct tcb *tcp)
|
||||
{
|
||||
unsigned long i, len;
|
||||
char *vec = NULL;
|
||||
|
||||
if (entering(tcp)) {
|
||||
tprintf("%#lx, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
|
||||
} else {
|
||||
unsigned long i, len;
|
||||
char *vec = NULL;
|
||||
|
||||
len = tcp->u_arg[1];
|
||||
if (syserror(tcp) || tcp->u_arg[2] == 0 ||
|
||||
(vec = malloc(len)) == NULL ||
|
||||
@ -586,8 +586,7 @@ sys_mincore(struct tcb *tcp)
|
||||
}
|
||||
tprintf("]");
|
||||
}
|
||||
if (vec)
|
||||
free(vec);
|
||||
free(vec);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -290,10 +290,8 @@ pathtrace_match(struct tcb *tcp)
|
||||
& -sizeof(long));
|
||||
fds = malloc(fdsize);
|
||||
|
||||
if (fds == NULL) {
|
||||
fprintf(stderr, "out of memory\n");
|
||||
return 0;
|
||||
}
|
||||
if (!fds)
|
||||
die_out_of_memory();
|
||||
|
||||
for (i = 1; i <= 3; ++i) {
|
||||
if (args[i] == 0)
|
||||
|
35
strace.c
35
strace.c
@ -264,6 +264,15 @@ void perror_msg_and_die(const char *fmt, ...)
|
||||
die();
|
||||
}
|
||||
|
||||
void die_out_of_memory(void)
|
||||
{
|
||||
static bool recursed = 0;
|
||||
if (recursed)
|
||||
exit(1);
|
||||
recursed = 1;
|
||||
error_msg_and_die("Out of memory");
|
||||
}
|
||||
|
||||
#ifdef SVR4
|
||||
#ifdef MIPS
|
||||
void
|
||||
@ -383,7 +392,7 @@ strace_popen(const char *command)
|
||||
swap_uid();
|
||||
fp = fdopen(fds[1], "w");
|
||||
if (!fp)
|
||||
error_msg_and_die("Out of memory");
|
||||
die_out_of_memory();
|
||||
return fp;
|
||||
}
|
||||
|
||||
@ -947,11 +956,11 @@ main(int argc, char *argv[])
|
||||
/* Allocate the initial tcbtab. */
|
||||
tcbtabsize = argc; /* Surely enough for all -p args. */
|
||||
tcbtab = calloc(tcbtabsize, sizeof(tcbtab[0]));
|
||||
if (tcbtab == NULL)
|
||||
error_msg_and_die("Out of memory");
|
||||
if (!tcbtab)
|
||||
die_out_of_memory();
|
||||
tcp = calloc(tcbtabsize, sizeof(*tcp));
|
||||
if (tcp == NULL)
|
||||
error_msg_and_die("Out of memory");
|
||||
if (!tcp)
|
||||
die_out_of_memory();
|
||||
for (c = 0; c < tcbtabsize; c++)
|
||||
tcbtab[c] = tcp++;
|
||||
|
||||
@ -1078,9 +1087,8 @@ main(int argc, char *argv[])
|
||||
username = strdup(optarg);
|
||||
break;
|
||||
case 'E':
|
||||
if (putenv(optarg) < 0) {
|
||||
error_msg_and_die("Out of memory");
|
||||
}
|
||||
if (putenv(optarg) < 0)
|
||||
die_out_of_memory();
|
||||
break;
|
||||
default:
|
||||
usage(stderr, 1);
|
||||
@ -1090,7 +1098,7 @@ main(int argc, char *argv[])
|
||||
|
||||
acolumn_spaces = malloc(acolumn + 1);
|
||||
if (!acolumn_spaces)
|
||||
error_msg_and_die("Out of memory");
|
||||
die_out_of_memory();
|
||||
memset(acolumn_spaces, ' ', acolumn);
|
||||
acolumn_spaces[acolumn] = '\0';
|
||||
|
||||
@ -1240,8 +1248,8 @@ expand_tcbtab(void)
|
||||
int i = tcbtabsize;
|
||||
struct tcb *newtcbs = calloc(tcbtabsize, sizeof(newtcbs[0]));
|
||||
struct tcb **newtab = realloc(tcbtab, tcbtabsize * 2 * sizeof(tcbtab[0]));
|
||||
if (newtab == NULL || newtcbs == NULL)
|
||||
error_msg_and_die("Out of memory");
|
||||
if (!newtab || !newtcbs)
|
||||
die_out_of_memory();
|
||||
tcbtabsize *= 2;
|
||||
tcbtab = newtab;
|
||||
while (i < tcbtabsize)
|
||||
@ -1866,9 +1874,8 @@ rebuild_pollv(void)
|
||||
|
||||
free(pollv);
|
||||
pollv = malloc(nprocs * sizeof(pollv[0]));
|
||||
if (pollv == NULL) {
|
||||
error_msg_and_die("Out of memory");
|
||||
}
|
||||
if (!pollv)
|
||||
die_out_of_memory();
|
||||
|
||||
for (i = j = 0; i < tcbtabsize; i++) {
|
||||
struct tcb *tcp = tcbtab[i];
|
||||
|
@ -473,10 +473,8 @@ qualify(const char *s)
|
||||
qualify_one(i, opt->bitflag, !not, -1);
|
||||
}
|
||||
copy = strdup(s);
|
||||
if (!copy) {
|
||||
fprintf(stderr, "out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
if (!copy)
|
||||
die_out_of_memory();
|
||||
for (p = strtok(copy, ","); p; p = strtok(NULL, ",")) {
|
||||
if (opt->bitflag == QUAL_TRACE && (n = lookup_class(p)) > 0) {
|
||||
for (i = 0; i < nsyscalls0; i++)
|
||||
|
34
util.c
34
util.c
@ -619,14 +619,15 @@ printstr(struct tcb *tcp, long addr, int len)
|
||||
return;
|
||||
}
|
||||
/* Allocate static buffers if they are not allocated yet. */
|
||||
if (!str)
|
||||
if (!str) {
|
||||
str = malloc(max_strlen + 1);
|
||||
if (!outstr)
|
||||
if (!str)
|
||||
die_out_of_memory();
|
||||
}
|
||||
if (!outstr) {
|
||||
outstr = malloc(4 * max_strlen + sizeof "\"...\"");
|
||||
if (!str || !outstr) {
|
||||
fprintf(stderr, "out of memory\n");
|
||||
tprintf("%#lx", addr);
|
||||
return;
|
||||
if (!outstr)
|
||||
die_out_of_memory();
|
||||
}
|
||||
|
||||
if (len < 0) {
|
||||
@ -687,10 +688,9 @@ dumpiov(struct tcb *tcp, int len, long addr)
|
||||
unsigned long size;
|
||||
|
||||
size = sizeof_iov * (unsigned long) len;
|
||||
if (size / sizeof_iov != len
|
||||
if (size / sizeof_iov != len /* overflow? */
|
||||
|| (iov = malloc(size)) == NULL) {
|
||||
fprintf(stderr, "out of memory\n");
|
||||
return;
|
||||
die_out_of_memory();
|
||||
}
|
||||
if (umoven(tcp, addr, size, (char *) iov) >= 0) {
|
||||
for (i = 0; i < len; i++) {
|
||||
@ -715,18 +715,14 @@ dumpstr(struct tcb *tcp, long addr, int len)
|
||||
{
|
||||
static int strsize = -1;
|
||||
static unsigned char *str;
|
||||
static char outstr[80];
|
||||
char *s;
|
||||
int i, j;
|
||||
|
||||
if (strsize < len) {
|
||||
free(str);
|
||||
str = malloc(len);
|
||||
if (str == NULL) {
|
||||
fprintf(stderr, "out of memory\n");
|
||||
/* BUG! On next call we may use NULL str! */
|
||||
return;
|
||||
}
|
||||
if (!str)
|
||||
die_out_of_memory();
|
||||
strsize = len;
|
||||
}
|
||||
|
||||
@ -734,6 +730,8 @@ dumpstr(struct tcb *tcp, long addr, int len)
|
||||
return;
|
||||
|
||||
for (i = 0; i < len; i += 16) {
|
||||
char outstr[80];
|
||||
|
||||
s = outstr;
|
||||
sprintf(s, " | %05x ", i);
|
||||
s += 9;
|
||||
@ -1741,10 +1739,8 @@ fixvfork(struct tcb *tcp)
|
||||
return -1;
|
||||
}
|
||||
strtab = malloc((unsigned)ld.ld_symb_size);
|
||||
if (strtab == NULL) {
|
||||
fprintf(stderr, "out of memory\n");
|
||||
return -1;
|
||||
}
|
||||
if (!strtab)
|
||||
die_out_of_memory();
|
||||
if (umoven(tcp, (int)ld.ld_symbols+(int)N_TXTADDR(hdr),
|
||||
(int)ld.ld_symb_size, strtab) < 0)
|
||||
goto err;
|
||||
|
Loading…
x
Reference in New Issue
Block a user