From d00a8d1e94456d45abbb7c94cd846661735277ab Mon Sep 17 00:00:00 2001 From: dholland Date: Mon, 29 Jun 2009 23:05:33 +0000 Subject: Fix two serious string-handling bugs (one exploitable, one probably exploitable) and also add proper checking/paranoia in several other places. --- hack/hack.do_name.c | 6 +++--- hack/hack.h | 4 ++-- hack/hack.invent.c | 17 ++++++++++++----- hack/hack.main.c | 17 +++++++++-------- hack/hack.rip.c | 6 +++--- hack/hack.topl.c | 20 ++++++++++++++------ hack/hack.unix.c | 12 ++++++------ 7 files changed, 49 insertions(+), 33 deletions(-) diff --git a/hack/hack.do_name.c b/hack/hack.do_name.c index 21ee4275..303330fd 100644 --- a/hack/hack.do_name.c +++ b/hack/hack.do_name.c @@ -1,4 +1,4 @@ -/* $NetBSD: hack.do_name.c,v 1.9 2009/06/07 20:13:18 dholland Exp $ */ +/* $NetBSD: hack.do_name.c,v 1.10 2009/06/29 23:05:33 dholland Exp $ */ /* * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, @@ -63,7 +63,7 @@ #include #ifndef lint -__RCSID("$NetBSD: hack.do_name.c,v 1.9 2009/06/07 20:13:18 dholland Exp $"); +__RCSID("$NetBSD: hack.do_name.c,v 1.10 2009/06/29 23:05:33 dholland Exp $"); #endif /* not lint */ #include @@ -279,7 +279,7 @@ xmonnam(struct monst *mtmp, int vb) gn = ghostnames[rn2(SIZE(ghostnames))]; if (!rn2(2)) (void) - strcpy((char *) mtmp->mextra, !rn2(5) ? plname : gn); + strlcpy((char *) mtmp->mextra, !rn2(5) ? plname : gn, mtmp->mxlth); } (void) snprintf(buf, sizeof(buf), "%s's ghost", gn); } diff --git a/hack/hack.h b/hack/hack.h index 825daa72..21a94c0c 100644 --- a/hack/hack.h +++ b/hack/hack.h @@ -1,4 +1,4 @@ -/* $NetBSD: hack.h,v 1.12 2009/06/07 21:04:54 dholland Exp $ */ +/* $NetBSD: hack.h,v 1.13 2009/06/29 23:05:33 dholland Exp $ */ /* * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, @@ -202,7 +202,7 @@ extern const char *const traps[]; extern char SAVEF[]; extern char fut_geno[60]; /* idem */ extern char genocided[60]; /* defined in Decl.c */ -extern char lock[]; +extern char lock[PL_NSIZ + 4]; extern const char mlarge[]; extern char morc; extern const char nul[]; diff --git a/hack/hack.invent.c b/hack/hack.invent.c index 8b1e7cc8..3d7d8377 100644 --- a/hack/hack.invent.c +++ b/hack/hack.invent.c @@ -1,4 +1,4 @@ -/* $NetBSD: hack.invent.c,v 1.12 2009/06/07 20:13:18 dholland Exp $ */ +/* $NetBSD: hack.invent.c,v 1.13 2009/06/29 23:05:33 dholland Exp $ */ /* * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, @@ -63,9 +63,10 @@ #include #ifndef lint -__RCSID("$NetBSD: hack.invent.c,v 1.12 2009/06/07 20:13:18 dholland Exp $"); +__RCSID("$NetBSD: hack.invent.c,v 1.13 2009/06/29 23:05:33 dholland Exp $"); #endif /* not lint */ +#include #include #include "hack.h" #include "extern.h" @@ -555,7 +556,7 @@ ggetobj(const char *word, int (*fn)(struct obj *), int max) char buf[BUFSZ]; char *ip; char sym; - int oletct = 0, iletct = 0; + unsigned oletct = 0, iletct = 0; boolean allflag = FALSE; char olets[20], ilets[20]; int (*ckfn)(struct obj *) = @@ -586,6 +587,7 @@ ggetobj(const char *word, int (*fn)(struct obj *), int max) if (invent) ilets[iletct++] = 'a'; ilets[iletct] = 0; + assert(iletct < sizeof(ilets)); } pline("What kinds of thing do you want to %s? [%s] ", word, ilets); @@ -614,6 +616,7 @@ ggetobj(const char *word, int (*fn)(struct obj *), int max) olets[oletct++] = sym; olets[oletct] = 0; } + assert(oletct < sizeof(olets)); } else pline("You don't have any %c's.", sym); } @@ -723,7 +726,7 @@ doinv(char *lets) { struct obj *otmp; char ilet; - int ct = 0; + unsigned ct = 0; char any[BUFSZ]; morc = 0; /* just to be sure */ @@ -746,6 +749,7 @@ doinv(char *lets) ilet = 'A'; } any[ct] = 0; + assert(ct < sizeof(any)); cornline(2, any); } @@ -755,7 +759,7 @@ dotypeinv(void) /* Changed to one type only, so he doesnt have to type cr */ char c, ilet; char stuff[BUFSZ]; - int stct; + unsigned stct; struct obj *otmp; boolean billx = inshop() && doinvbill(0); boolean unpd = FALSE; @@ -781,6 +785,7 @@ dotypeinv(void) if (billx) stuff[stct++] = 'x'; stuff[stct] = 0; + assert(stct < sizeof(stuff)); if (stct > 1) { pline("What type of object [%s] do you want an inventory of? ", @@ -817,6 +822,8 @@ dotypeinv(void) ilet = 'A'; } stuff[stct] = '\0'; + assert(stct < sizeof(stuff)); + if (stct == 0) pline("You have no such objects."); else diff --git a/hack/hack.main.c b/hack/hack.main.c index 28eec738..05bd88f9 100644 --- a/hack/hack.main.c +++ b/hack/hack.main.c @@ -1,4 +1,4 @@ -/* $NetBSD: hack.main.c,v 1.12 2009/06/07 20:13:18 dholland Exp $ */ +/* $NetBSD: hack.main.c,v 1.13 2009/06/29 23:05:33 dholland Exp $ */ /* * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, @@ -63,7 +63,7 @@ #include #ifndef lint -__RCSID("$NetBSD: hack.main.c,v 1.12 2009/06/07 20:13:18 dholland Exp $"); +__RCSID("$NetBSD: hack.main.c,v 1.13 2009/06/29 23:05:33 dholland Exp $"); #endif /* not lint */ #include @@ -300,7 +300,8 @@ main(int argc, char *argv[]) } *gp = 0; } else - (void) strcpy(genocided, sfoo); + (void) strlcpy(genocided, sfoo, + sizeof(genocided)); (void) strcpy(fut_geno, genocided); } } @@ -478,12 +479,12 @@ void glo(int foo) { /* construct the string xlock.n */ - char *tf; + size_t pos; - tf = lock; - while (*tf && *tf != '.') - tf++; - (void) sprintf(tf, ".%d", foo); + pos = 0; + while (lock[pos] && lock[pos] != '.') + pos++; + (void) snprintf(lock + pos, sizeof(lock) - pos, ".%d", foo); } /* diff --git a/hack/hack.rip.c b/hack/hack.rip.c index a27735ee..a0b11671 100644 --- a/hack/hack.rip.c +++ b/hack/hack.rip.c @@ -1,4 +1,4 @@ -/* $NetBSD: hack.rip.c,v 1.10 2009/06/07 20:13:18 dholland Exp $ */ +/* $NetBSD: hack.rip.c,v 1.11 2009/06/29 23:05:33 dholland Exp $ */ /* * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, @@ -63,7 +63,7 @@ #include #ifndef lint -__RCSID("$NetBSD: hack.rip.c,v 1.10 2009/06/07 20:13:18 dholland Exp $"); +__RCSID("$NetBSD: hack.rip.c,v 1.11 2009/06/29 23:05:33 dholland Exp $"); #endif /* not lint */ #include "hack.h" @@ -101,7 +101,7 @@ outrip(void) !strcmp(killer, "starvation") ? "" : strchr(vowels, *killer) ? " an" : " a"); center(8, buf); - (void) strcpy(buf, killer); + (void) strlcpy(buf, killer, sizeof(buf)); { int i1; if ((i1 = strlen(buf)) > 16) { diff --git a/hack/hack.topl.c b/hack/hack.topl.c index 80962902..138a1db2 100644 --- a/hack/hack.topl.c +++ b/hack/hack.topl.c @@ -1,4 +1,4 @@ -/* $NetBSD: hack.topl.c,v 1.10 2009/06/07 20:13:18 dholland Exp $ */ +/* $NetBSD: hack.topl.c,v 1.11 2009/06/29 23:05:33 dholland Exp $ */ /* * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, @@ -63,7 +63,7 @@ #include #ifndef lint -__RCSID("$NetBSD: hack.topl.c,v 1.10 2009/06/07 20:13:18 dholland Exp $"); +__RCSID("$NetBSD: hack.topl.c,v 1.11 2009/06/29 23:05:33 dholland Exp $"); #endif /* not lint */ #include @@ -212,7 +212,7 @@ vpline(const char *line, va_list ap) { char pbuf[BUFSZ]; char *bp = pbuf, *tl; - int n, n0; + int n, n0, tlpos, dead; if (!line || !*line) return; @@ -240,8 +240,9 @@ vpline(const char *line, va_list ap) if (flags.toplin == 1) more(); remember_topl(); + dead = 0; toplines[0] = 0; - while (n0) { + while (n0 && !dead) { if (n0 >= CO) { /* look for appropriate cut point */ n0 = 0; @@ -255,7 +256,14 @@ vpline(const char *line, va_list ap) if (!n0) n0 = CO - 2; } - (void) strncpy((tl = eos(toplines)), bp, n0); + tlpos = strlen(toplines); + tl = toplines + tlpos; + /* avoid overflow */ + if (tlpos + n0 > (int)sizeof(toplines) - 1) { + n0 = sizeof(toplines) - 1 - tlpos; + dead = 1; + } + (void) memcpy(tl, bp, n0); tl[n0] = 0; bp += n0; @@ -265,7 +273,7 @@ vpline(const char *line, va_list ap) n0 = strlen(bp); if (n0 && tl[0]) - (void) strcat(tl, "\n"); + (void) strlcat(toplines, "\n", sizeof(toplines)); } redotoplin(); } diff --git a/hack/hack.unix.c b/hack/hack.unix.c index 11cd9392..708e9f79 100644 --- a/hack/hack.unix.c +++ b/hack/hack.unix.c @@ -1,4 +1,4 @@ -/* $NetBSD: hack.unix.c,v 1.12 2009/06/07 20:13:18 dholland Exp $ */ +/* $NetBSD: hack.unix.c,v 1.13 2009/06/29 23:05:33 dholland Exp $ */ /* * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, @@ -63,7 +63,7 @@ #include #ifndef lint -__RCSID("$NetBSD: hack.unix.c,v 1.12 2009/06/07 20:13:18 dholland Exp $"); +__RCSID("$NetBSD: hack.unix.c,v 1.13 2009/06/29 23:05:33 dholland Exp $"); #endif /* not lint */ /* This file collects some Unix dependencies; hack.pager.c contains some more */ @@ -192,11 +192,11 @@ gethdate(char *name) if ((np = strchr(path, ':')) == NULL) np = path + strlen(path); /* point to end str */ if (np - path <= 1) /* %% */ - (void) strcpy(filename, name); + (void) strlcpy(filename, name, sizeof(filename)); else { - (void) strncpy(filename, path, np - path); - filename[np - path] = '/'; - (void) strcpy(filename + (np - path) + 1, name); + (void) snprintf(filename, sizeof(filename), + "%.*s/%s", + (int)(np - path), path, name); } if (stat(filename, &hbuf) == 0) return; -- cgit v1.2.3-56-ge451