diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-07-19 10:44:44 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-07-19 10:57:30 -0700 |
commit | 9be85a9b60677acc8f8c6da048a0c08e67e172f8 (patch) | |
tree | 2b4c9a8129ac8d3921196f553905a0008fd49d0c | |
parent | 31a16c0ccab9a4b69c79920244b9c623bee7bffe (diff) | |
download | uemacs-9be85a9b60677acc8f8c6da048a0c08e67e172f8.tar.gz |
Do some valgrind cleanup
Joerg Scheurich reported that there's a buffer overflow in readin() for
long path component names. He's not wrong.
When fixing that, and then checking there's nothing else obviously wrong
with valgrind, I also noticed it complains about overlapping strcpy().
So add a hacky version of strscpy(), which (a) handles overlapping, and
(b) has the proper strscpy() semantics.
Just say no to strncpy and strlcpy, both of which are terminally broken
interfaces.
And stop stripping the binary. The time when the size of the uemacs
binary was a big deal is long past, and it made valgrind harder.
Reported-by: Joerg Scheurich <mufti11@web.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | efunc.h | 2 | ||||
-rw-r--r-- | eval.c | 17 | ||||
-rw-r--r-- | exec.c | 4 | ||||
-rw-r--r-- | file.c | 3 | ||||
-rw-r--r-- | util.c | 17 | ||||
-rw-r--r-- | util.h | 1 |
7 files changed, 37 insertions, 12 deletions
@@ -20,13 +20,13 @@ SRC=ansi.c basic.c bind.c buffer.c crypt.c display.c eval.c exec.c \ file.c fileio.c ibmpc.c input.c isearch.c line.c lock.c main.c \ pklock.c posix.c random.c region.c search.c spawn.c tcap.c \ termio.c vmsvt.c vt52.c window.c word.c names.c globals.c version.c \ - usage.c wrapper.c utf8.c + usage.c wrapper.c utf8.c util.c OBJ=ansi.o basic.o bind.o buffer.o crypt.o display.o eval.o exec.o \ file.o fileio.o ibmpc.o input.o isearch.o line.o lock.o main.o \ pklock.o posix.o random.o region.o search.o spawn.o tcap.o \ termio.o vmsvt.o vt52.o window.o word.o names.o globals.o version.o \ - usage.o wrapper.o utf8.o + usage.o wrapper.o utf8.o util.o HDR=ebind.h edef.h efunc.h epath.h estruct.h evar.h util.h version.h @@ -72,7 +72,6 @@ clean: $(Q) rm -f $(PROGRAM) core lintout makeout tags makefile.bak *.o install: $(PROGRAM) - strip $(PROGRAM) cp em ${BINDIR} cp emacs.hlp ${LIBDIR} cp emacs.rc ${LIBDIR}/.emacsrc @@ -338,7 +338,7 @@ extern void findvar(char *var, struct variable_description *vd, int size); extern int svar(struct variable_description *var, char *value); extern char *itoa(int i); extern int gettyp(char *token); -extern char *getval(char *token); +extern char *getval(char *token, char *result, int size); extern int stol(char *val); extern char *ltos(int val); extern char *mkupper(char *str); @@ -113,7 +113,7 @@ char *gtfun(char *fname) case UFSGREAT: return ltos(strcmp(arg1, arg2) > 0); case UFIND: - return strcpy(result, getval(arg1)); + return getval(arg1, result, sizeof(result)); case UFAND: return ltos(stol(arg1) && stol(arg2)); case UFOR: @@ -496,7 +496,7 @@ fvar: if (strcmp(&var[1], "ind") == 0) { /* grab token, and eval it */ execstr = token(execstr, var, size); - strcpy(var, getval(var)); + getval(var, var, size); goto fvar; } } @@ -765,7 +765,7 @@ int gettyp(char *token) * * char *token; token to evaluate */ -char *getval(char *token) +static char *internal_getval(char *token) { int status; /* error return */ struct buffer *bp; /* temp buffer pointer */ @@ -778,7 +778,7 @@ char *getval(char *token) return ""; case TKARG: /* interactive argument */ - strcpy(token, getval(&token[1])); + getval(token+1, token, -1); distmp = discmd; /* echo it always! */ discmd = TRUE; status = getstring(token, buf, NSTRING, ctoec('\n')); @@ -790,7 +790,7 @@ char *getval(char *token) case TKBUF: /* buffer contents fetch */ /* grab the right buffer */ - strcpy(token, getval(&token[1])); + getval(token+1, token, -1); bp = bfind(token, FALSE, 0); if (bp == NULL) return errorm; @@ -847,6 +847,13 @@ char *getval(char *token) return errorm; } +char *getval(char *token, char *dst, int size) +{ + char *res = internal_getval(token); + mystrscpy(dst, res, size); + return dst; +} + /* * convert a string to a numeric logical * @@ -99,7 +99,7 @@ int docmd(char *cline) /* process leadin argument */ if (gettyp(tkn) != TKCMD) { f = TRUE; - strcpy(tkn, getval(tkn)); + getval(tkn, tkn, sizeof(tkn)); n = atoi(tkn); /* and now get the command to execute */ @@ -237,7 +237,7 @@ int nextarg(char *prompt, char *buffer, int size, int terminator) execstr = token(execstr, buffer, size); /* evaluate it */ - strcpy(buffer, getval(buffer)); + getval(buffer, buffer, size); return TRUE; } @@ -14,6 +14,7 @@ #include "edef.h" #include "efunc.h" #include "line.h" +#include "util.h" #if defined(PKCODE) /* Max number of lines from one file. */ @@ -246,7 +247,7 @@ int readin(char *fname, int lockfl) if ((s = bclear(bp)) != TRUE) /* Might be old. */ return s; bp->b_flag &= ~(BFINVS | BFCHG); - strcpy(bp->b_fname, fname); + mystrscpy(bp->b_fname, fname, NFILEN); /* let a user macro get hold of things...if he wants */ execute(META | SPEC | 'R', FALSE, 1); @@ -0,0 +1,17 @@ +#include "util.h" + +/* Safe zeroing, no complaining about overlap */ +void mystrscpy(char *dst, const char *src, int size) +{ + if (!size) + return; + while (--size) { + char c = *src++; + if (!c) + break; + *dst++ = c; + } + *dst = 0; +} + + @@ -2,5 +2,6 @@ #define UTIL_H_ #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) +void mystrscpy(char *dst, const char *src, int size); #endif /* UTIL_H_ */ |