Module Name: src Committed By: christos Date: Fri Oct 4 18:05:44 UTC 2024
Modified Files: src/usr.bin/ftp: cmds.c Log Message: Check bounds when copying to destination. Remove const where the const string ended up being overwritten. To generate a diff of this commit: cvs rdiff -u -r1.143 -r1.144 src/usr.bin/ftp/cmds.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.bin/ftp/cmds.c diff -u src/usr.bin/ftp/cmds.c:1.143 src/usr.bin/ftp/cmds.c:1.144 --- src/usr.bin/ftp/cmds.c:1.143 Wed Sep 25 12:53:58 2024 +++ src/usr.bin/ftp/cmds.c Fri Oct 4 14:05:43 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: cmds.c,v 1.143 2024/09/25 16:53:58 christos Exp $ */ +/* $NetBSD: cmds.c,v 1.144 2024/10/04 18:05:43 christos Exp $ */ /*- * Copyright (c) 1996-2021 The NetBSD Foundation, Inc. @@ -96,7 +96,7 @@ #if 0 static char sccsid[] = "@(#)cmds.c 8.6 (Berkeley) 10/9/94"; #else -__RCSID("$NetBSD: cmds.c,v 1.143 2024/09/25 16:53:58 christos Exp $"); +__RCSID("$NetBSD: cmds.c,v 1.144 2024/10/04 18:05:43 christos Exp $"); #endif #endif /* not lint */ @@ -147,10 +147,10 @@ __dead static void mintr(int); static void mabort(const char *); static void set_type(const char *); -static const char *doprocess(char *, size_t, const char *, int, int, int); -static const char *domap(char *, size_t, const char *); -static const char *docase(char *, size_t, const char *); -static const char *dotrans(char *, size_t, const char *); +static char *doprocess(char *, size_t, char *, int, int, int); +static char *domap(char *, size_t, const char *); +static char *docase(char *, size_t, const char *); +static char *dotrans(char *, size_t, const char *); /* * Confirm if "cmd" is to be performed upon "file". @@ -407,7 +407,7 @@ put(int argc, char *argv[]) const char *cmd; int loc = 0; char *locfile; - const char *remfile; + char *remfile; if (argc == 2) { argc++; @@ -437,8 +437,8 @@ put(int argc, char *argv[]) free(locfile); } -static const char * -doprocess(char *dst, size_t dlen, const char *src, +static char * +doprocess(char *dst, size_t dlen, char *src, int casef, int transf, int mapf) { if (casef) @@ -576,8 +576,7 @@ int getit(int argc, char *argv[], int restartit, const char *gmode) { int loc, rval; - char *remfile, *olocfile; - const char *locfile; + char *remfile, *olocfile, *locfile; char buf[MAXPATHLEN]; loc = rval = 0; @@ -684,8 +683,7 @@ mget(int argc, char *argv[]) { sigfunc oldintr; int ointer; - char *cp; - const char *tp; + char *cp, *tp; int volatile restartit; if (argc == 0 || @@ -1290,13 +1288,11 @@ void ls(int argc, char *argv[]) { const char *cmd; - char *remdir, *locbuf; - const char *locfile; + char *remdir, *locbuf, *locfile; int pagecmd, mlsdcmd; remdir = NULL; locbuf = NULL; - locfile = "-"; pagecmd = mlsdcmd = 0; /* * the only commands that start with `p' are @@ -1326,6 +1322,8 @@ ls(int argc, char *argv[]) remdir = argv[1]; if (argc > 2) locfile = argv[2]; + else + locfile = locbuf = ftp_strdup("-"); if (argc > 3 || ((pagecmd | mlsdcmd) && argc > 2)) { usage: if (pagecmd || mlsdcmd) @@ -1345,11 +1343,12 @@ ls(int argc, char *argv[]) if (EMPTYSTRING(p)) p = DEFAULTPAGER; len = strlen(p) + 2; + free(locbuf); locbuf = ftp_malloc(len); locbuf[0] = '|'; (void)strlcpy(locbuf + 1, p, len - 1); locfile = locbuf; - } else if ((strcmp(locfile, "-") != 0) && *locfile != '|') { + } else if (locfile != locbuf) { if ((locbuf = globulize(locfile)) == NULL || !confirm("output to local-file:", locbuf)) { code = -1; @@ -1920,7 +1919,7 @@ setcase(int argc, char *argv[]) * convert the given name to lower case if it's all upper case, into * a static buffer which is returned to the caller */ -static const char * +static char * docase(char *dst, size_t dlen, const char *src) { size_t i; @@ -1973,7 +1972,14 @@ setntrans(int argc, char *argv[]) (void)strlcpy(ntout, argv[2], sizeof(ntout)); } -static const char * +#define ADDC(x) \ + do { \ + *cp2++ = x; \ + if (cp2 - dst >= (ptrdiff_t)(dlen - 1)) \ + goto out; \ + } while (0) + +static char * dotrans(char *dst, size_t dlen, const char *src) { const char *cp1; @@ -1988,15 +1994,13 @@ dotrans(char *dst, size_t dlen, const ch if (*cp1 == ntin[i]) { found++; if (i < ostop) { - *cp2++ = ntout[i]; - if (cp2 - dst >= (ptrdiff_t)(dlen - 1)) - goto out; + ADDC(ntout[i]); } break; } } if (!found) { - *cp2++ = *cp1; + ADDC(*cp1); } } out: @@ -2037,8 +2041,8 @@ setnmap(int argc, char *argv[]) (void)strlcpy(mapout, cp, MAXPATHLEN); } -static const char * -domap(char *dst, size_t dlen __unused, const char *src) +static char * +domap(char *dst, size_t dlen, const char *src) { const char *cp1 = src; char *cp2 = mapin; @@ -2093,7 +2097,7 @@ domap(char *dst, size_t dlen __unused, c switch (*cp1) { case '\\': if (*(cp1 + 1)) { - *cp2++ = *++cp1; + ADDC(*++cp1); } break; case '[': @@ -2104,7 +2108,7 @@ LOOP: const char *cp3 = src; while (*cp3) { - *cp2++ = *cp3++; + ADDC(*cp3++); } match = 1; } @@ -2112,7 +2116,7 @@ LOOP: const char *cp3 = tp[toknum]; while (cp3 != te[toknum]) { - *cp2++ = *cp3++; + ADDC(*cp3++); } match = 1; } @@ -2129,7 +2133,7 @@ LOOP: const char *cp3 = src; while (*cp3) { - *cp2++ = *cp3++; + ADDC(*cp3++); } } else if (toks[toknum = @@ -2138,19 +2142,16 @@ LOOP: while (cp3 != te[toknum]) { - *cp2++ = *cp3++; + ADDC(*cp3++); } } } else if (*cp1) { - *cp2++ = *cp1++; + ADDC(*cp1++); } } if (!*cp1) { - fputs( - "nmap: unbalanced brackets.\n", - ttyout); - return (src); + goto unbalanced; } match = 1; cp1--; @@ -2162,10 +2163,7 @@ LOOP: } } if (!*cp1) { - fputs( - "nmap: unbalanced brackets.\n", - ttyout); - return (src); + goto unbalanced; } break; } @@ -2185,27 +2183,34 @@ LOOP: const char *cp3 = src; while (*cp3) { - *cp2++ = *cp3++; + ADDC(*cp3++); } } else if (toks[toknum = *cp1 - '1']) { const char *cp3 = tp[toknum]; while (cp3 != te[toknum]) { - *cp2++ = *cp3++; + ADDC(*cp3++); } } break; } /* FALLTHROUGH */ default: - *cp2++ = *cp1; + ADDC(*cp1); break; } cp1++; } +out: *cp2 = '\0'; - return *dst ? dst : src; + if (!*dst) + strlcpy(dst, src, dlen); + return dst; +unbalanced: + fputs("nmap: unbalanced brackets.\n", ttyout); + *dst = '\0'; + goto out; } void