diff options
author | 2005-01-03 22:10:12 +0000 | |
---|---|---|
committer | 2005-01-03 22:10:12 +0000 | |
commit | 0b4202ba9e92a750e9a3009ea0b0b949ce004488 (patch) | |
tree | 650d9ef50ec2e1ed36990c52791988e19d5cc0a0 | |
parent | put keyboard on mux 1; miod ok (diff) | |
download | wireguard-openbsd-0b4202ba9e92a750e9a3009ea0b0b949ce004488.tar.xz wireguard-openbsd-0b4202ba9e92a750e9a3009ea0b0b949ce004488.zip |
limit the maximum length of RCS numbers to 64 nums and avoid
potential integer overflow in case of ridiculously large RCSNUMs
-rw-r--r-- | usr.bin/cvs/rcs.h | 7 | ||||
-rw-r--r-- | usr.bin/cvs/rcsnum.c | 35 |
2 files changed, 32 insertions, 10 deletions
diff --git a/usr.bin/cvs/rcs.h b/usr.bin/cvs/rcs.h index 2a1c17c3574..aa39b0a5eb3 100644 --- a/usr.bin/cvs/rcs.h +++ b/usr.bin/cvs/rcs.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rcs.h,v 1.4 2004/12/16 17:16:18 jfb Exp $ */ +/* $OpenBSD: rcs.h,v 1.5 2005/01/03 22:10:12 jfb Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -58,6 +58,11 @@ #define RCS_RD_DEAD 0x01 /* dead */ + +#define RCSNUM_MAXNUM USHRT_MAX +#define RCSNUM_MAXLEN 64 + + typedef struct rcs_num { u_int rn_len; u_int16_t *rn_id; diff --git a/usr.bin/cvs/rcsnum.c b/usr.bin/cvs/rcsnum.c index aa44243b5d8..693af871326 100644 --- a/usr.bin/cvs/rcsnum.c +++ b/usr.bin/cvs/rcsnum.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rcsnum.c,v 1.5 2004/12/10 19:19:11 jfb Exp $ */ +/* $OpenBSD: rcsnum.c,v 1.6 2005/01/03 22:10:12 jfb Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -179,39 +179,50 @@ rcsnum_cmp(const RCSNUM *n1, const RCSNUM *n2, u_int depth) int rcsnum_aton(const char *str, char **ep, RCSNUM *nump) { + u_int32_t val; const char *sp; void *tmp; if (nump->rn_id == NULL) { nump->rn_id = (u_int16_t *)malloc(sizeof(u_int16_t)); - if (nump->rn_id == NULL) + if (nump->rn_id == NULL) { + cvs_log(LP_ERRNO, "failed to allocate RCSNUM"); return (-1); + } } nump->rn_len = 0; - nump->rn_id[nump->rn_len] = 0; + nump->rn_id[0] = 0; for (sp = str;; sp++) { if (!isdigit(*sp) && (*sp != '.')) break; if (*sp == '.') { + if (nump->rn_len >= RCSNUM_MAXLEN - 1) { + cvs_log(LP_ERR, + "RCSNUM exceeds maximum length"); + goto rcsnum_aton_failed; + } + nump->rn_len++; tmp = realloc(nump->rn_id, (nump->rn_len + 1) * sizeof(u_int16_t)); if (tmp == NULL) { - free(nump->rn_id); - nump->rn_len = 0; - nump->rn_id = NULL; - return (-1); + goto rcsnum_aton_failed; } nump->rn_id = (u_int16_t *)tmp; nump->rn_id[nump->rn_len] = 0; continue; } - nump->rn_id[nump->rn_len] *= 10; - nump->rn_id[nump->rn_len] += *sp - 0x30; + val = (nump->rn_id[nump->rn_len] * 10) + (*sp - 0x30); + if (val > RCSNUM_MAXNUM) { + cvs_log(LP_ERR, "RCSNUM overflow"); + goto rcsnum_aton_failed; + } + + nump->rn_id[nump->rn_len] = val; } if (ep != NULL) @@ -219,4 +230,10 @@ rcsnum_aton(const char *str, char **ep, RCSNUM *nump) nump->rn_len++; return (nump->rn_len); + +rcsnum_aton_failed: + nump->rn_len = 0; + free(nump->rn_id); + nump->rn_id = NULL; + return (-1); } |