diff options
author | Damien Miller <djm@cvs.openbsd.org> | 2006-03-25 01:13:24 +0000 |
---|---|---|
committer | Damien Miller <djm@cvs.openbsd.org> | 2006-03-25 01:13:24 +0000 |
commit | 9a8aaa01f21a60e2f5f372b9722e363b36254df9 (patch) | |
tree | 2f9a74072ee701d5c60ccf0b6c31f22ac1be3a57 /usr.bin | |
parent | 2deaa1649526d4ce68eed29e66d89d32fea75950 (diff) |
change OpenSSH's xrealloc() function from being xrealloc(p, new_size) to
xrealloc(p, new_nmemb, new_itemsize).
realloc is particularly prone to integer overflows because it is almost
always allocating "n * size" bytes, so this is a far safer API;
ok deraadt@
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/ssh/buffer.c | 2 | ||||
-rw-r--r-- | usr.bin/ssh/channels.c | 17 | ||||
-rw-r--r-- | usr.bin/ssh/deattack.c | 2 | ||||
-rw-r--r-- | usr.bin/ssh/misc.c | 2 | ||||
-rw-r--r-- | usr.bin/ssh/scp.c | 2 | ||||
-rw-r--r-- | usr.bin/ssh/session.c | 6 | ||||
-rw-r--r-- | usr.bin/ssh/sftp-client.c | 3 | ||||
-rw-r--r-- | usr.bin/ssh/sftp-server.c | 2 | ||||
-rw-r--r-- | usr.bin/ssh/ssh-agent.c | 2 | ||||
-rw-r--r-- | usr.bin/ssh/ssh-rsa.c | 2 | ||||
-rw-r--r-- | usr.bin/ssh/xmalloc.c | 10 | ||||
-rw-r--r-- | usr.bin/ssh/xmalloc.h | 4 |
12 files changed, 31 insertions, 23 deletions
diff --git a/usr.bin/ssh/buffer.c b/usr.bin/ssh/buffer.c index 08682e0f125..1666f742e7f 100644 --- a/usr.bin/ssh/buffer.c +++ b/usr.bin/ssh/buffer.c @@ -109,7 +109,7 @@ restart: if (newlen > BUFFER_MAX_LEN) fatal("buffer_append_space: alloc %u not supported", newlen); - buffer->buf = xrealloc(buffer->buf, newlen); + buffer->buf = xrealloc(buffer->buf, 1, newlen); buffer->alloc = newlen; goto restart; /* NOTREACHED */ diff --git a/usr.bin/ssh/channels.c b/usr.bin/ssh/channels.c index ce863f00e53..1c401ec2657 100644 --- a/usr.bin/ssh/channels.c +++ b/usr.bin/ssh/channels.c @@ -265,8 +265,8 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd, if (channels_alloc > 10000) fatal("channel_new: internal error: channels_alloc %d " "too big.", channels_alloc); - channels = xrealloc(channels, - (channels_alloc + 10) * sizeof(Channel *)); + channels = xrealloc(channels, channels_alloc + 10, + sizeof(Channel *)); channels_alloc += 10; debug2("channel: expanding %d", channels_alloc); for (i = found; i < channels_alloc; i++) @@ -1783,15 +1783,20 @@ void channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp, u_int *nallocp, int rekeying) { - u_int n, sz; + u_int n, sz, nfdset; n = MAX(*maxfdp, channel_max_fd); - sz = howmany(n+1, NFDBITS) * sizeof(fd_mask); + nfdset = howmany(n+1, NFDBITS); + /* Explicitly test here, because xrealloc isn't always called */ + if (nfdset && SIZE_T_MAX / nfdset < sizeof(fd_mask)) + fatal("channel_prepare_select: max_fd (%d) is too large", n); + sz = nfdset * sizeof(fd_mask); + /* perhaps check sz < nalloc/2 and shrink? */ if (*readsetp == NULL || sz > *nallocp) { - *readsetp = xrealloc(*readsetp, sz); - *writesetp = xrealloc(*writesetp, sz); + *readsetp = xrealloc(*readsetp, nfdset, sizeof(fd_mask)); + *writesetp = xrealloc(*writesetp, nfdset, sizeof(fd_mask)); *nallocp = sz; } *maxfdp = n; diff --git a/usr.bin/ssh/deattack.c b/usr.bin/ssh/deattack.c index 746ff5d43ad..ff9ca4dd542 100644 --- a/usr.bin/ssh/deattack.c +++ b/usr.bin/ssh/deattack.c @@ -97,7 +97,7 @@ detect_attack(u_char *buf, u_int32_t len) n = l; } else { if (l > n) { - h = (u_int16_t *) xrealloc(h, l * HASH_ENTRYSIZE); + h = (u_int16_t *)xrealloc(h, l, HASH_ENTRYSIZE); n = l; } } diff --git a/usr.bin/ssh/misc.c b/usr.bin/ssh/misc.c index d92ffe0462e..843897e8707 100644 --- a/usr.bin/ssh/misc.c +++ b/usr.bin/ssh/misc.c @@ -417,7 +417,7 @@ addargs(arglist *args, char *fmt, ...) } else if (args->num+2 >= nalloc) nalloc *= 2; - args->list = xrealloc(args->list, nalloc * sizeof(char *)); + args->list = xrealloc(args->list, nalloc, sizeof(char *)); args->nalloc = nalloc; args->list[args->num++] = cp; args->list[args->num] = NULL; diff --git a/usr.bin/ssh/scp.c b/usr.bin/ssh/scp.c index a6dd0e2fd6a..b61bc86557a 100644 --- a/usr.bin/ssh/scp.c +++ b/usr.bin/ssh/scp.c @@ -1171,7 +1171,7 @@ allocbuf(BUF *bp, int fd, int blksize) if (bp->buf == NULL) bp->buf = xmalloc(size); else - bp->buf = xrealloc(bp->buf, size); + bp->buf = xrealloc(bp->buf, 1, size); memset(bp->buf, 0, size); bp->cnt = size; return (bp); diff --git a/usr.bin/ssh/session.c b/usr.bin/ssh/session.c index 78758205763..0f86e8b95c6 100644 --- a/usr.bin/ssh/session.c +++ b/usr.bin/ssh/session.c @@ -728,7 +728,7 @@ child_set_env(char ***envp, u_int *envsizep, const char *name, if (envsize >= 1000) fatal("child_set_env: too many env vars"); envsize += 50; - env = (*envp) = xrealloc(env, envsize * sizeof(char *)); + env = (*envp) = xrealloc(env, envsize, sizeof(char *)); *envsizep = envsize; } /* Need to set the NULL pointer at end of array beyond the new slot. */ @@ -1573,8 +1573,8 @@ session_env_req(Session *s) for (i = 0; i < options.num_accept_env; i++) { if (match_pattern(name, options.accept_env[i])) { debug2("Setting env %d: %s=%s", s->num_env, name, val); - s->env = xrealloc(s->env, sizeof(*s->env) * - (s->num_env + 1)); + s->env = xrealloc(s->env, s->num_env + 1, + sizeof(*s->env)); s->env[s->num_env].name = name; s->env[s->num_env].val = val; s->num_env++; diff --git a/usr.bin/ssh/sftp-client.c b/usr.bin/ssh/sftp-client.c index 82ae32900b9..46f1ab554fd 100644 --- a/usr.bin/ssh/sftp-client.c +++ b/usr.bin/ssh/sftp-client.c @@ -389,8 +389,7 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int printflag, printf("%s\n", longname); if (dir) { - *dir = xrealloc(*dir, sizeof(**dir) * - (ents + 2)); + *dir = xrealloc(*dir, ents + 2, sizeof(**dir)); (*dir)[ents] = xmalloc(sizeof(***dir)); (*dir)[ents]->filename = xstrdup(filename); (*dir)[ents]->longname = xstrdup(longname); diff --git a/usr.bin/ssh/sftp-server.c b/usr.bin/ssh/sftp-server.c index 7ea3eda68c2..d2827204585 100644 --- a/usr.bin/ssh/sftp-server.c +++ b/usr.bin/ssh/sftp-server.c @@ -700,7 +700,7 @@ process_readdir(void) while ((dp = readdir(dirp)) != NULL) { if (count >= nstats) { nstats *= 2; - stats = xrealloc(stats, nstats * sizeof(Stat)); + stats = xrealloc(stats, nstats, sizeof(Stat)); } /* XXX OVERFLOW ? */ snprintf(pathname, sizeof pathname, "%s%s%s", path, diff --git a/usr.bin/ssh/ssh-agent.c b/usr.bin/ssh/ssh-agent.c index e9d30c181d2..1699a3ebbf4 100644 --- a/usr.bin/ssh/ssh-agent.c +++ b/usr.bin/ssh/ssh-agent.c @@ -795,7 +795,7 @@ new_socket(sock_type type, int fd) } old_alloc = sockets_alloc; new_alloc = sockets_alloc + 10; - sockets = xrealloc(sockets, new_alloc * sizeof(sockets[0])); + sockets = xrealloc(sockets, new_alloc, sizeof(sockets[0])); for (i = old_alloc; i < new_alloc; i++) sockets[i].type = AUTH_UNUSED; sockets_alloc = new_alloc; diff --git a/usr.bin/ssh/ssh-rsa.c b/usr.bin/ssh/ssh-rsa.c index ce4195fead9..55fb7ba5990 100644 --- a/usr.bin/ssh/ssh-rsa.c +++ b/usr.bin/ssh/ssh-rsa.c @@ -144,7 +144,7 @@ ssh_rsa_verify(const Key *key, const u_char *signature, u_int signaturelen, u_int diff = modlen - len; debug("ssh_rsa_verify: add padding: modlen %u > len %u", modlen, len); - sigblob = xrealloc(sigblob, modlen); + sigblob = xrealloc(sigblob, 1, modlen); memmove(sigblob + diff, sigblob, len); memset(sigblob, 0, diff); len = modlen; diff --git a/usr.bin/ssh/xmalloc.c b/usr.bin/ssh/xmalloc.c index 6d56781d921..d5d7b6bc5cd 100644 --- a/usr.bin/ssh/xmalloc.c +++ b/usr.bin/ssh/xmalloc.c @@ -35,7 +35,7 @@ xcalloc(size_t nmemb, size_t size) { void *ptr; - if (nmemb && size && SIZE_T_MAX / nmemb < size) + if (nmemb && size && SIZE_T_MAX / nmemb < size) fatal("xcalloc: nmemb * size > SIZE_T_MAX"); if (size == 0 || nmemb == 0) fatal("xcalloc: zero size"); @@ -47,10 +47,13 @@ xcalloc(size_t nmemb, size_t size) } void * -xrealloc(void *ptr, size_t new_size) +xrealloc(void *ptr, size_t nmemb, size_t size) { void *new_ptr; + size_t new_size = nmemb * size; + if (nmemb && size && SIZE_T_MAX / nmemb < size) + fatal("xrealloc: nmemb * size > SIZE_T_MAX"); if (new_size == 0) fatal("xrealloc: zero size"); if (ptr == NULL) @@ -58,7 +61,8 @@ xrealloc(void *ptr, size_t new_size) else new_ptr = realloc(ptr, new_size); if (new_ptr == NULL) - fatal("xrealloc: out of memory (new_size %lu bytes)", (u_long) new_size); + fatal("xrealloc: out of memory (new_size %lu bytes)", + (u_long) new_size); return new_ptr; } diff --git a/usr.bin/ssh/xmalloc.h b/usr.bin/ssh/xmalloc.h index b6d521a66db..ef29787bd61 100644 --- a/usr.bin/ssh/xmalloc.h +++ b/usr.bin/ssh/xmalloc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: xmalloc.h,v 1.10 2006/03/25 00:05:41 djm Exp $ */ +/* $OpenBSD: xmalloc.h,v 1.11 2006/03/25 01:13:23 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -21,7 +21,7 @@ void *xmalloc(size_t); void *xcalloc(size_t, size_t); -void *xrealloc(void *, size_t); +void *xrealloc(void *, size_t, size_t); void xfree(void *); char *xstrdup(const char *); int xasprintf(char **, const char *, ...) |