aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-07-19 10:44:44 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2018-07-19 10:57:30 -0700
commit9be85a9b60677acc8f8c6da048a0c08e67e172f8 (patch)
tree2b4c9a8129ac8d3921196f553905a0008fd49d0c
parent31a16c0ccab9a4b69c79920244b9c623bee7bffe (diff)
downloaduemacs-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--Makefile5
-rw-r--r--efunc.h2
-rw-r--r--eval.c17
-rw-r--r--exec.c4
-rw-r--r--file.c3
-rw-r--r--util.c17
-rw-r--r--util.h1
7 files changed, 37 insertions, 12 deletions
diff --git a/Makefile b/Makefile
index ed9d81c..f93aa28 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/efunc.h b/efunc.h
index 6d0ffbc..4cc11cd 100644
--- a/efunc.h
+++ b/efunc.h
@@ -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);
diff --git a/eval.c b/eval.c
index fd4993b..a15bf6b 100644
--- a/eval.c
+++ b/eval.c
@@ -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
*
diff --git a/exec.c b/exec.c
index 2937966..e1db2d4 100644
--- a/exec.c
+++ b/exec.c
@@ -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;
}
diff --git a/file.c b/file.c
index 1feb97a..25aaba1 100644
--- a/file.c
+++ b/file.c
@@ -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);
diff --git a/util.c b/util.c
new file mode 100644
index 0000000..9028863
--- /dev/null
+++ b/util.c
@@ -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;
+}
+
+
diff --git a/util.h b/util.h
index 49f3649..73440b1 100644
--- a/util.h
+++ b/util.h
@@ -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_ */