decode_select(struct tcb *tcp, long *args, enum bitness_t bitness)
{
int i, j, nfds;
- unsigned int fdsize = ((((args[0] + 7) / 8) + sizeof(long) - 1)
- & -sizeof(long));
+ unsigned nfds, fdsize;
fd_set *fds;
const char *sep;
long arg;
+ fdsize = args[0];
+ /* Beware of select(2^31-1, NULL, NULL, NULL) and similar... */
+ if (args[0] > 1024*1024)
+ fdsize = 1024*1024;
+ if (args[0] < 0)
+ fdsize = 0;
+ fdsize = (((fdsize + 7) / 8) + sizeof(long)-1) & -sizeof(long);
+
if (entering(tcp)) {
fds = malloc(fdsize);
if (!fds)
return 0;
}
len = tcp->u_rval;
+ /* Beware of insanely large or negative values in tcp->u_rval */
+ if (tcp->u_rval > 1024*1024)
+ len = 1024*1024;
+ if (tcp->u_rval < 0)
+ len = 0;
buf = len ? malloc(len) : NULL;
if (len && !buf)
die_out_of_memory();
tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
return 0;
}
+
len = tcp->u_rval;
+ /* Beware of insanely large or negative tcp->u_rval */
+ if (tcp->u_rval > 1024*1024)
+ len = 1024*1024;
+ if (tcp->u_rval < 0)
+ len = 0;
buf = len ? malloc(len) : NULL;
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);
tprintf("%#lx, %lu, %#lx", tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3]);
return 0;
}
+
len = tcp->u_rval;
+ /* Beware of insanely large or negative tcp->u_rval */
+ if (tcp->u_rval > 1024*1024)
+ len = 1024*1024;
+ if (tcp->u_rval < 0)
+ len = 0;
buf = malloc(len);
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);
s->sys_func == sys_oldselect ||
s->sys_func == sys_pselect6)
{
- int i, j, nfds;
+ int i, j;
+ unsigned nfds;
long *args, oldargs[5];
unsigned fdsize;
fd_set *fds;
args = tcp->u_arg;
nfds = args[0];
+ /* Beware of select(2^31-1, NULL, NULL, NULL) and similar... */
+ if (args[0] > 1024*1024)
+ nfds = 1024*1024;
+ if (args[0] < 0)
+ nfds = 0;
fdsize = ((((nfds + 7) / 8) + sizeof(long) - 1)
& -sizeof(long));
fds = malloc(fdsize);
-
if (!fds)
die_out_of_memory();
#define iov_iov_len(i) iov[i].iov_len
#endif
int i;
- unsigned long size;
+ unsigned size;
- size = sizeof_iov * (unsigned long) len;
- if (size / sizeof_iov != len /* overflow? */
+ size = sizeof_iov * len;
+ /* Assuming no sane program has millions of iovs */
+ if ((unsigned)len > 1024*1024 /* insane or negative size? */
|| (iov = malloc(size)) == NULL) {
- die_out_of_memory();
+ fprintf(stderr, "Out of memory\n");
+ return;
}
if (umoven(tcp, addr, size, (char *) iov) >= 0) {
for (i = 0; i < len; i++) {
iov_iov_len(i));
}
}
- free((char *) iov);
+ free(iov);
#undef sizeof_iov
#undef iov_iov_base
#undef iov_iov_len
if (strsize < len) {
free(str);
str = malloc(len);
- if (!str)
- die_out_of_memory();
+ if (!str) {
+ strsize = -1;
+ fprintf(stderr, "Out of memory\n");
+ return;
+ }
strsize = len;
}