• Address concerns of Chris Palmer from the Android security team

– possible integer overflows in memory allocation, mostly
    ‣ multiplication: all are checked now
    ‣ addition: reviewed them, most were “proven” or guessed to be
      “almost” impossible to run over (e.g. when we have a string
      whose length is taken it is assumed that the length will be
      more than only a few bytes below SIZE_MAX, since code and
      stack have to fit); some are checked now (e.g. when one of
      the summands is an off_t); most of the unchecked ones are
      annotated now
    ⇒ cost (MirBSD/i386 static): +76 .text
    ⇒ cost (Debian sid/i386): +779 .text  -4 .data
  – on Linux targets, setuid() setresuid() setresgid() can fail
    with EAGAIN; check for that and, if so, warn once and retry
    infinitely (other targets to be added later once we know that
    they are “insane”)
    ⇒ cost (Debian sid/i386): +192 .text (includes .rodata)
• setmode.c: Do overflow checking for realloc() too; switch back
  from calloc() to a checked malloc() for simplification while there
• define -DIN_MKSH and let setmode.c look a tad nicer while here
This commit is contained in:
tg
2010-09-14 21:26:19 +00:00
parent 08862021ee
commit 667d792d6a
18 changed files with 204 additions and 96 deletions

22
funcs.c
View File

@ -25,7 +25,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.161 2010/09/05 19:51:33 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.162 2010/09/14 21:26:12 tg Exp $");
#if HAVE_KILLPG
/*
@ -208,6 +208,7 @@ do_realpath(const char *upath)
afree(tp, ATEMP);
}
/* ipath and upath are in memory at the same time -> unchecked */
Xinit(xs, xp, strlen(ip = ipath) + 1, ATEMP);
while (*ip) {
@ -277,8 +278,15 @@ do_realpath(const char *upath)
}
/* get symlink(7) target */
if (pathcnd)
if (pathcnd) {
#ifdef NO_PATH_MAX
if (notoktoadd(pathlen, 1)) {
errno = ENAMETOOLONG;
goto notfound;
}
#endif
ldest = aresize(ldest, pathlen + 1, ATEMP);
}
llen = readlink(Xstring(xs, xp), ldest, pathlen);
if (llen < 0)
/* oops... */
@ -397,7 +405,7 @@ c_cd(const char **wp)
}
} else if (!wp[2]) {
/* Two arguments - substitute arg1 in PWD for arg2 */
int ilen, olen, nlen, elen;
size_t ilen, olen, nlen, elen;
char *cp;
if (!current_wd[0]) {
@ -413,6 +421,12 @@ c_cd(const char **wp)
bi_errorf("bad substitution");
return (1);
}
/*-
* ilen = part of current_wd before wp[0]
* elen = part of current_wd after wp[0]
* because current_wd and wp[1] need to be in memory at the
* same time beforehand the addition can stay unchecked
*/
ilen = cp - current_wd;
olen = strlen(wp[0]);
nlen = strlen(wp[1]);
@ -2381,7 +2395,7 @@ c_set(const char **wp)
while (*++wp != NULL)
strdupx(*wp, *wp, &l->area);
l->argc = wp - owp - 1;
l->argv = alloc((l->argc + 2) * sizeof(char *), &l->area);
l->argv = alloc2(l->argc + 2, sizeof(char *), &l->area);
for (wp = l->argv; (*wp++ = *owp++) != NULL; )
;
}