• 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:
parent
08862021ee
commit
667d792d6a
6
Build.sh
6
Build.sh
@ -1,5 +1,5 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.460 2010/09/14 21:15:09 tg Exp $'
|
srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.461 2010/09/14 21:26:04 tg Exp $'
|
||||||
#-
|
#-
|
||||||
# Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
|
# Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
|
||||||
# Thorsten Glaser <tg@mirbsd.org>
|
# Thorsten Glaser <tg@mirbsd.org>
|
||||||
@ -441,7 +441,7 @@ IRIX*)
|
|||||||
: ${HAVE_SETLOCALE_CTYPE=0}
|
: ${HAVE_SETLOCALE_CTYPE=0}
|
||||||
;;
|
;;
|
||||||
Linux)
|
Linux)
|
||||||
CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE"
|
CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE -DSETUID_CAN_FAIL_WITH_EAGAIN"
|
||||||
: ${HAVE_REVOKE=0}
|
: ${HAVE_REVOKE=0}
|
||||||
;;
|
;;
|
||||||
MidnightBSD)
|
MidnightBSD)
|
||||||
@ -1427,11 +1427,11 @@ addsrcs '!' HAVE_SETMODE setmode.c
|
|||||||
addsrcs '!' HAVE_STRLCPY strlcpy.c
|
addsrcs '!' HAVE_STRLCPY strlcpy.c
|
||||||
addsrcs USE_PRINTF_BUILTIN printf.c
|
addsrcs USE_PRINTF_BUILTIN printf.c
|
||||||
test 1 = "$USE_PRINTF_BUILTIN" && CPPFLAGS="$CPPFLAGS -DMKSH_PRINTF_BUILTIN"
|
test 1 = "$USE_PRINTF_BUILTIN" && CPPFLAGS="$CPPFLAGS -DMKSH_PRINTF_BUILTIN"
|
||||||
test 0 = "$HAVE_SETMODE" && CPPFLAGS="$CPPFLAGS -DHAVE_CONFIG_H -DCONFIG_H_FILENAME=\\\"sh.h\\\""
|
|
||||||
test 1 = "$HAVE_CAN_VERB" && CFLAGS="$CFLAGS -verbose"
|
test 1 = "$HAVE_CAN_VERB" && CFLAGS="$CFLAGS -verbose"
|
||||||
|
|
||||||
$e $bi$me: Finished configuration testing, now producing output.$ao
|
$e $bi$me: Finished configuration testing, now producing output.$ao
|
||||||
|
|
||||||
|
CPPFLAGS="$CPPFLAGS -DIN_MKSH"
|
||||||
files=
|
files=
|
||||||
objs=
|
objs=
|
||||||
sp=
|
sp=
|
||||||
|
4
Makefile
4
Makefile
@ -1,4 +1,4 @@
|
|||||||
# $MirOS: src/bin/mksh/Makefile,v 1.81 2010/08/24 15:19:53 tg Exp $
|
# $MirOS: src/bin/mksh/Makefile,v 1.82 2010/09/14 21:26:05 tg Exp $
|
||||||
#-
|
#-
|
||||||
# Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
|
# Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
|
||||||
# Thorsten Glaser <tg@mirbsd.org>
|
# Thorsten Glaser <tg@mirbsd.org>
|
||||||
@ -43,7 +43,7 @@ CPPFLAGS+= -DMKSH_ASSUME_UTF8 \
|
|||||||
-DHAVE_SETMODE=1 -DHAVE_SETRESUGID=1 -DHAVE_SETGROUPS=1 \
|
-DHAVE_SETMODE=1 -DHAVE_SETRESUGID=1 -DHAVE_SETGROUPS=1 \
|
||||||
-DHAVE_STRCASESTR=1 -DHAVE_STRLCPY=1 -DHAVE_FLOCK_DECL=1 \
|
-DHAVE_STRCASESTR=1 -DHAVE_STRLCPY=1 -DHAVE_FLOCK_DECL=1 \
|
||||||
-DHAVE_REVOKE_DECL=1 -DHAVE_SYS_SIGLIST_DECL=1 \
|
-DHAVE_REVOKE_DECL=1 -DHAVE_SYS_SIGLIST_DECL=1 \
|
||||||
-DHAVE_PERSISTENT_HISTORY=1
|
-DHAVE_PERSISTENT_HISTORY=1 -DIN_MKSH
|
||||||
COPTS+= -std=gnu99 -Wall
|
COPTS+= -std=gnu99 -Wall
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
|
4
check.t
4
check.t
@ -1,4 +1,4 @@
|
|||||||
# $MirOS: src/bin/mksh/check.t,v 1.391 2010/09/05 19:51:29 tg Exp $
|
# $MirOS: src/bin/mksh/check.t,v 1.392 2010/09/14 21:26:07 tg Exp $
|
||||||
# $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $
|
# $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $
|
||||||
# $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $
|
# $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $
|
||||||
# $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $
|
# $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $
|
||||||
@ -25,7 +25,7 @@
|
|||||||
# http://www.research.att.com/~gsf/public/ifs.sh
|
# http://www.research.att.com/~gsf/public/ifs.sh
|
||||||
|
|
||||||
expected-stdout:
|
expected-stdout:
|
||||||
@(#)MIRBSD KSH R39 2010/09/05
|
@(#)MIRBSD KSH R39 2010/09/14
|
||||||
description:
|
description:
|
||||||
Check version of shell.
|
Check version of shell.
|
||||||
stdin:
|
stdin:
|
||||||
|
24
edit.c
24
edit.c
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.200 2010/09/05 19:51:31 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.201 2010/09/14 21:26:09 tg Exp $");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* in later versions we might use libtermcap for this, but since external
|
* in later versions we might use libtermcap for this, but since external
|
||||||
@ -424,7 +424,7 @@ x_command_glob(int flags, const char *str, int slen, char ***wordsp)
|
|||||||
int i, path_order = 0;
|
int i, path_order = 0;
|
||||||
|
|
||||||
info = (struct path_order_info *)
|
info = (struct path_order_info *)
|
||||||
alloc(nwords * sizeof(struct path_order_info), ATEMP);
|
alloc2(nwords, sizeof(struct path_order_info), ATEMP);
|
||||||
for (i = 0; i < nwords; i++) {
|
for (i = 0; i < nwords; i++) {
|
||||||
info[i].word = words[i];
|
info[i].word = words[i];
|
||||||
info[i].base = x_basename(words[i], NULL);
|
info[i].base = x_basename(words[i], NULL);
|
||||||
@ -678,13 +678,15 @@ glob_table(const char *pat, XPtrV *wp, struct table *tp)
|
|||||||
static void
|
static void
|
||||||
glob_path(int flags, const char *pat, XPtrV *wp, const char *lpath)
|
glob_path(int flags, const char *pat, XPtrV *wp, const char *lpath)
|
||||||
{
|
{
|
||||||
const char *sp, *p;
|
const char *sp = lpath, *p;
|
||||||
char *xp, **words;
|
char *xp, **words;
|
||||||
int staterr, pathlen, patlen, oldsize, newsize, i, j;
|
size_t pathlen, patlen, oldsize, newsize, i, j;
|
||||||
|
int staterr;
|
||||||
XString xs;
|
XString xs;
|
||||||
|
|
||||||
patlen = strlen(pat) + 1;
|
patlen = strlen(pat);
|
||||||
sp = lpath;
|
checkoktoadd(patlen, 129 + X_EXTRA);
|
||||||
|
++patlen;
|
||||||
Xinit(xs, xp, patlen + 128, ATEMP);
|
Xinit(xs, xp, patlen + 128, ATEMP);
|
||||||
while (sp) {
|
while (sp) {
|
||||||
xp = Xstring(xs, xp);
|
xp = Xstring(xs, xp);
|
||||||
@ -2466,7 +2468,7 @@ x_init_emacs(void)
|
|||||||
ainit(AEDIT);
|
ainit(AEDIT);
|
||||||
x_nextcmd = -1;
|
x_nextcmd = -1;
|
||||||
|
|
||||||
x_tab = alloc(X_NTABS * sizeof(*x_tab), AEDIT);
|
x_tab = alloc2(X_NTABS, sizeof(*x_tab), AEDIT);
|
||||||
for (j = 0; j < X_TABSZ; j++)
|
for (j = 0; j < X_TABSZ; j++)
|
||||||
x_tab[0][j] = XFUNC_insert;
|
x_tab[0][j] = XFUNC_insert;
|
||||||
for (i = 1; i < X_NTABS; i++)
|
for (i = 1; i < X_NTABS; i++)
|
||||||
@ -2477,7 +2479,7 @@ x_init_emacs(void)
|
|||||||
= x_defbindings[i].xdb_func;
|
= x_defbindings[i].xdb_func;
|
||||||
|
|
||||||
#ifndef MKSH_SMALL
|
#ifndef MKSH_SMALL
|
||||||
x_atab = alloc(X_NTABS * sizeof(*x_atab), AEDIT);
|
x_atab = alloc2(X_NTABS, sizeof(*x_atab), AEDIT);
|
||||||
for (i = 1; i < X_NTABS; i++)
|
for (i = 1; i < X_NTABS; i++)
|
||||||
for (j = 0; j < X_TABSZ; j++)
|
for (j = 0; j < X_TABSZ; j++)
|
||||||
x_atab[i][j] = NULL;
|
x_atab[i][j] = NULL;
|
||||||
@ -3912,7 +3914,7 @@ vi_cmd(int argcnt, const char *cmd)
|
|||||||
{
|
{
|
||||||
static char alias[] = "_\0";
|
static char alias[] = "_\0";
|
||||||
struct tbl *ap;
|
struct tbl *ap;
|
||||||
int olen, nlen;
|
size_t olen, nlen;
|
||||||
char *p, *nbuf;
|
char *p, *nbuf;
|
||||||
|
|
||||||
/* lookup letter in alias list... */
|
/* lookup letter in alias list... */
|
||||||
@ -3929,6 +3931,10 @@ vi_cmd(int argcnt, const char *cmd)
|
|||||||
nlen = strlen(ap->val.s) + 1;
|
nlen = strlen(ap->val.s) + 1;
|
||||||
olen = !macro.p ? 2 :
|
olen = !macro.p ? 2 :
|
||||||
macro.len - (macro.p - macro.buf);
|
macro.len - (macro.p - macro.buf);
|
||||||
|
/*
|
||||||
|
* at this point, it's fairly reasonable that
|
||||||
|
* nlen + olen + 2 doesn't overflow
|
||||||
|
*/
|
||||||
nbuf = alloc(nlen + 1 + olen, APERM);
|
nbuf = alloc(nlen + 1 + olen, APERM);
|
||||||
memcpy(nbuf, ap->val.s, nlen);
|
memcpy(nbuf, ap->val.s, nlen);
|
||||||
nbuf[nlen++] = cmd[1];
|
nbuf[nlen++] = cmd[1];
|
||||||
|
6
eval.c
6
eval.c
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.92 2010/08/28 20:22:16 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.93 2010/09/14 21:26:10 tg Exp $");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* string expansion
|
* string expansion
|
||||||
@ -1562,6 +1562,10 @@ alt_expand(XPtrV *wp, char *start, char *exp_start, char *end, int fdo)
|
|||||||
char *news;
|
char *news;
|
||||||
int l1, l2, l3;
|
int l1, l2, l3;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* addition safe since these operate on
|
||||||
|
* one string (separate substrings)
|
||||||
|
*/
|
||||||
l1 = brace_start - start;
|
l1 = brace_start - start;
|
||||||
l2 = (p - 1) - field_start;
|
l2 = (p - 1) - field_start;
|
||||||
l3 = end - brace_end;
|
l3 = end - brace_end;
|
||||||
|
4
exec.c
4
exec.c
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.81 2010/09/05 19:51:32 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.82 2010/09/14 21:26:11 tg Exp $");
|
||||||
|
|
||||||
#ifndef MKSH_DEFAULT_EXECSHELL
|
#ifndef MKSH_DEFAULT_EXECSHELL
|
||||||
#define MKSH_DEFAULT_EXECSHELL "/bin/sh"
|
#define MKSH_DEFAULT_EXECSHELL "/bin/sh"
|
||||||
@ -101,7 +101,7 @@ execute(struct op *volatile t,
|
|||||||
flags &= ~XTIME;
|
flags &= ~XTIME;
|
||||||
|
|
||||||
if (t->ioact != NULL || t->type == TPIPE || t->type == TCOPROC) {
|
if (t->ioact != NULL || t->type == TPIPE || t->type == TCOPROC) {
|
||||||
e->savefd = alloc(NUFILE * sizeof(short), ATEMP);
|
e->savefd = alloc2(NUFILE, sizeof(short), ATEMP);
|
||||||
/* initialise to not redirected */
|
/* initialise to not redirected */
|
||||||
memset(e->savefd, 0, NUFILE * sizeof(short));
|
memset(e->savefd, 0, NUFILE * sizeof(short));
|
||||||
}
|
}
|
||||||
|
22
funcs.c
22
funcs.c
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#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
|
#if HAVE_KILLPG
|
||||||
/*
|
/*
|
||||||
@ -208,6 +208,7 @@ do_realpath(const char *upath)
|
|||||||
afree(tp, ATEMP);
|
afree(tp, ATEMP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ipath and upath are in memory at the same time -> unchecked */
|
||||||
Xinit(xs, xp, strlen(ip = ipath) + 1, ATEMP);
|
Xinit(xs, xp, strlen(ip = ipath) + 1, ATEMP);
|
||||||
|
|
||||||
while (*ip) {
|
while (*ip) {
|
||||||
@ -277,8 +278,15 @@ do_realpath(const char *upath)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* get symlink(7) target */
|
/* 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);
|
ldest = aresize(ldest, pathlen + 1, ATEMP);
|
||||||
|
}
|
||||||
llen = readlink(Xstring(xs, xp), ldest, pathlen);
|
llen = readlink(Xstring(xs, xp), ldest, pathlen);
|
||||||
if (llen < 0)
|
if (llen < 0)
|
||||||
/* oops... */
|
/* oops... */
|
||||||
@ -397,7 +405,7 @@ c_cd(const char **wp)
|
|||||||
}
|
}
|
||||||
} else if (!wp[2]) {
|
} else if (!wp[2]) {
|
||||||
/* Two arguments - substitute arg1 in PWD for arg2 */
|
/* Two arguments - substitute arg1 in PWD for arg2 */
|
||||||
int ilen, olen, nlen, elen;
|
size_t ilen, olen, nlen, elen;
|
||||||
char *cp;
|
char *cp;
|
||||||
|
|
||||||
if (!current_wd[0]) {
|
if (!current_wd[0]) {
|
||||||
@ -413,6 +421,12 @@ c_cd(const char **wp)
|
|||||||
bi_errorf("bad substitution");
|
bi_errorf("bad substitution");
|
||||||
return (1);
|
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;
|
ilen = cp - current_wd;
|
||||||
olen = strlen(wp[0]);
|
olen = strlen(wp[0]);
|
||||||
nlen = strlen(wp[1]);
|
nlen = strlen(wp[1]);
|
||||||
@ -2381,7 +2395,7 @@ c_set(const char **wp)
|
|||||||
while (*++wp != NULL)
|
while (*++wp != NULL)
|
||||||
strdupx(*wp, *wp, &l->area);
|
strdupx(*wp, *wp, &l->area);
|
||||||
l->argc = wp - owp - 1;
|
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; )
|
for (wp = l->argv; (*wp++ = *owp++) != NULL; )
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
21
histrap.c
21
histrap.c
@ -26,7 +26,7 @@
|
|||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.101 2010/08/28 20:22:18 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.102 2010/09/14 21:26:13 tg Exp $");
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* MirOS: This is the default mapping type, and need not be specified.
|
* MirOS: This is the default mapping type, and need not be specified.
|
||||||
@ -92,6 +92,8 @@ c_fc(const char **wp)
|
|||||||
sflag = true;
|
sflag = true;
|
||||||
else {
|
else {
|
||||||
size_t len = strlen(p);
|
size_t len = strlen(p);
|
||||||
|
|
||||||
|
/* almost certainly not overflowing */
|
||||||
editor = alloc(len + 4, ATEMP);
|
editor = alloc(len + 4, ATEMP);
|
||||||
memcpy(editor, p, len);
|
memcpy(editor, p, len);
|
||||||
memcpy(editor + len, " $_", 4);
|
memcpy(editor + len, " $_", 4);
|
||||||
@ -269,7 +271,17 @@ c_fc(const char **wp)
|
|||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
n = stat(tf->name, &statb) < 0 ? 128 : statb.st_size + 1;
|
if (stat(tf->name, &statb) < 0)
|
||||||
|
n = 128;
|
||||||
|
else {
|
||||||
|
if (notoktoadd(statb.st_size, 1 + X_EXTRA)) {
|
||||||
|
bi_errorf(T_intovfl,
|
||||||
|
(unsigned long)statb.st_size, '+',
|
||||||
|
1UL + X_EXTRA);
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
n = statb.st_size + 1;
|
||||||
|
}
|
||||||
Xinit(xs, xp, n, hist_source->areap);
|
Xinit(xs, xp, n, hist_source->areap);
|
||||||
while ((n = shf_read(xp, Xnleft(xs, xp), shf)) > 0) {
|
while ((n = shf_read(xp, Xnleft(xs, xp), shf)) > 0) {
|
||||||
xp += n;
|
xp += n;
|
||||||
@ -279,6 +291,7 @@ c_fc(const char **wp)
|
|||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
bi_errorf("can't %s temporary file %s: %s",
|
bi_errorf("can't %s temporary file %s: %s",
|
||||||
"read", tf->name, strerror(shf_errno(shf)));
|
"read", tf->name, strerror(shf_errno(shf)));
|
||||||
|
errout:
|
||||||
shf_close(shf);
|
shf_close(shf);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
@ -532,7 +545,7 @@ sethistsize(int n)
|
|||||||
cursize = n;
|
cursize = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
history = aresize(history, n * sizeof(char *), APERM);
|
history = aresize2(history, n, sizeof(char *), APERM);
|
||||||
|
|
||||||
histsize = n;
|
histsize = n;
|
||||||
histptr = history + cursize;
|
histptr = history + cursize;
|
||||||
@ -583,7 +596,7 @@ init_histvec(void)
|
|||||||
{
|
{
|
||||||
if (history == (char **)NULL) {
|
if (history == (char **)NULL) {
|
||||||
histsize = HISTORYSIZE;
|
histsize = HISTORYSIZE;
|
||||||
history = alloc(histsize * sizeof(char *), APERM);
|
history = alloc2(histsize, sizeof(char *), APERM);
|
||||||
histptr = history - 1;
|
histptr = history - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
13
lalloc.c
13
lalloc.c
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/lalloc.c,v 1.12 2010/08/28 20:22:19 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/lalloc.c,v 1.13 2010/09/14 21:26:14 tg Exp $");
|
||||||
|
|
||||||
/* build with CPPFLAGS+= -DUSE_REALLOC_MALLOC=0 on ancient systems */
|
/* build with CPPFLAGS+= -DUSE_REALLOC_MALLOC=0 on ancient systems */
|
||||||
#if defined(USE_REALLOC_MALLOC) && (USE_REALLOC_MALLOC == 0)
|
#if defined(USE_REALLOC_MALLOC) && (USE_REALLOC_MALLOC == 0)
|
||||||
@ -67,6 +67,15 @@ findptr(ALLOC_ITEM **lpp, char *ptr, Area *ap)
|
|||||||
return (ap);
|
return (ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
aresize2(void *ptr, size_t fac1, size_t fac2, Area *ap)
|
||||||
|
{
|
||||||
|
if (fac1 && fac2 && (SIZE_MAX / fac1 < fac2))
|
||||||
|
internal_errorf(T_intovfl, (unsigned long)fac1, '*',
|
||||||
|
(unsigned long)fac2);
|
||||||
|
return (aresize(ptr, fac1 * fac2, ap));
|
||||||
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
aresize(void *ptr, size_t numb, Area *ap)
|
aresize(void *ptr, size_t numb, Area *ap)
|
||||||
{
|
{
|
||||||
@ -80,7 +89,7 @@ aresize(void *ptr, size_t numb, Area *ap)
|
|||||||
pp->next = lp->next;
|
pp->next = lp->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((numb >= SIZE_MAX - ALLOC_SIZE) ||
|
if (notoktoadd(numb, ALLOC_SIZE) ||
|
||||||
(lp = remalloc(lp, numb + ALLOC_SIZE)) == NULL
|
(lp = remalloc(lp, numb + ALLOC_SIZE)) == NULL
|
||||||
#ifndef MKSH_SMALL
|
#ifndef MKSH_SMALL
|
||||||
|| ALLOC_ISUNALIGNED(lp)
|
|| ALLOC_ISUNALIGNED(lp)
|
||||||
|
12
lex.c
12
lex.c
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.120 2010/08/28 20:22:20 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.121 2010/09/14 21:26:14 tg Exp $");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* states while lexing word
|
* states while lexing word
|
||||||
@ -1446,7 +1446,7 @@ getsc_line(Source *s)
|
|||||||
int linelen;
|
int linelen;
|
||||||
|
|
||||||
linelen = Xlength(s->xs, xp);
|
linelen = Xlength(s->xs, xp);
|
||||||
XcheckN(s->xs, xp, fc_e_n + /* NUL */ 1);
|
XcheckN(s->xs, xp, Tn_fc_e_ + /* NUL */ 1);
|
||||||
/* reload after potential realloc */
|
/* reload after potential realloc */
|
||||||
cp = Xstring(s->xs, xp);
|
cp = Xstring(s->xs, xp);
|
||||||
/* change initial '!' into space */
|
/* change initial '!' into space */
|
||||||
@ -1454,10 +1454,10 @@ getsc_line(Source *s)
|
|||||||
/* NUL terminate the current string */
|
/* NUL terminate the current string */
|
||||||
*xp = '\0';
|
*xp = '\0';
|
||||||
/* move the actual string forward */
|
/* move the actual string forward */
|
||||||
memmove(cp + fc_e_n, cp, linelen + /* NUL */ 1);
|
memmove(cp + Tn_fc_e_, cp, linelen + /* NUL */ 1);
|
||||||
xp += fc_e_n;
|
xp += Tn_fc_e_;
|
||||||
/* prepend it with "fc -e -" */
|
/* prepend it with "fc -e -" */
|
||||||
memcpy(cp, fc_e_, fc_e_n);
|
memcpy(cp, T_fc_e_, Tn_fc_e_);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
s->start = s->str = cp;
|
s->start = s->str = cp;
|
||||||
@ -1749,7 +1749,7 @@ getsc_bn(void)
|
|||||||
static Lex_state *
|
static Lex_state *
|
||||||
push_state_(State_info *si, Lex_state *old_end)
|
push_state_(State_info *si, Lex_state *old_end)
|
||||||
{
|
{
|
||||||
Lex_state *news = alloc(STATE_BSIZE * sizeof(Lex_state), ATEMP);
|
Lex_state *news = alloc2(STATE_BSIZE, sizeof(Lex_state), ATEMP);
|
||||||
|
|
||||||
news[0].ls_info.base = old_end;
|
news[0].ls_info.base = old_end;
|
||||||
si->base = &news[0];
|
si->base = &news[0];
|
||||||
|
21
main.c
21
main.c
@ -33,7 +33,7 @@
|
|||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.171 2010/09/14 21:00:13 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.172 2010/09/14 21:26:14 tg Exp $");
|
||||||
|
|
||||||
extern char **environ;
|
extern char **environ;
|
||||||
|
|
||||||
@ -84,7 +84,7 @@ static const char *initcoms[] = {
|
|||||||
"history=fc -l",
|
"history=fc -l",
|
||||||
"nameref=typeset -n",
|
"nameref=typeset -n",
|
||||||
"nohup=nohup ",
|
"nohup=nohup ",
|
||||||
r_fc_e_,
|
T_r_fc_e_,
|
||||||
"source=PATH=$PATH:. command .",
|
"source=PATH=$PATH:. command .",
|
||||||
"login=exec login",
|
"login=exec login",
|
||||||
NULL,
|
NULL,
|
||||||
@ -119,7 +119,7 @@ mksh_init(int argc, const char *argv[])
|
|||||||
struct tbl *vp;
|
struct tbl *vp;
|
||||||
struct stat s_stdin;
|
struct stat s_stdin;
|
||||||
#if !defined(_PATH_DEFPATH) && defined(_CS_PATH)
|
#if !defined(_PATH_DEFPATH) && defined(_CS_PATH)
|
||||||
size_t k;
|
ssize_t k;
|
||||||
char *cp;
|
char *cp;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -181,7 +181,7 @@ mksh_init(int argc, const char *argv[])
|
|||||||
def_path = _PATH_DEFPATH;
|
def_path = _PATH_DEFPATH;
|
||||||
#else
|
#else
|
||||||
#ifdef _CS_PATH
|
#ifdef _CS_PATH
|
||||||
if ((k = confstr(_CS_PATH, NULL, 0)) != (size_t)-1 && k > 0 &&
|
if ((k = confstr(_CS_PATH, NULL, 0)) > 0 &&
|
||||||
confstr(_CS_PATH, cp = alloc(k + 1, APERM), k + 1) == k + 1)
|
confstr(_CS_PATH, cp = alloc(k + 1, APERM), k + 1) == k + 1)
|
||||||
def_path = cp;
|
def_path = cp;
|
||||||
else
|
else
|
||||||
@ -1266,6 +1266,7 @@ maketemp(Area *ap, Temp_type type, struct temp **tlist)
|
|||||||
pathname = tempnam(dir, "mksh.");
|
pathname = tempnam(dir, "mksh.");
|
||||||
len = ((pathname == NULL) ? 0 : strlen(pathname)) + 1;
|
len = ((pathname == NULL) ? 0 : strlen(pathname)) + 1;
|
||||||
#endif
|
#endif
|
||||||
|
/* reasonably sure that this will not overflow */
|
||||||
tp = alloc(sizeof(struct temp) + len, ap);
|
tp = alloc(sizeof(struct temp) + len, ap);
|
||||||
tp->name = (char *)&tp[1];
|
tp->name = (char *)&tp[1];
|
||||||
#if !HAVE_MKSTEMP
|
#if !HAVE_MKSTEMP
|
||||||
@ -1313,7 +1314,7 @@ texpand(struct table *tp, size_t nsize)
|
|||||||
struct tbl *tblp, **pp;
|
struct tbl *tblp, **pp;
|
||||||
struct tbl **ntblp, **otblp = tp->tbls;
|
struct tbl **ntblp, **otblp = tp->tbls;
|
||||||
|
|
||||||
ntblp = alloc(nsize * sizeof(struct tbl *), tp->areap);
|
ntblp = alloc2(nsize, sizeof(struct tbl *), tp->areap);
|
||||||
for (i = 0; i < nsize; i++)
|
for (i = 0; i < nsize; i++)
|
||||||
ntblp[i] = NULL;
|
ntblp[i] = NULL;
|
||||||
tp->size = nsize;
|
tp->size = nsize;
|
||||||
@ -1392,7 +1393,7 @@ struct tbl *
|
|||||||
ktenter(struct table *tp, const char *n, uint32_t h)
|
ktenter(struct table *tp, const char *n, uint32_t h)
|
||||||
{
|
{
|
||||||
struct tbl **pp, *p;
|
struct tbl **pp, *p;
|
||||||
int len;
|
size_t len;
|
||||||
|
|
||||||
if (tp->size == 0)
|
if (tp->size == 0)
|
||||||
texpand(tp, INIT_TBLS);
|
texpand(tp, INIT_TBLS);
|
||||||
@ -1407,8 +1408,9 @@ ktenter(struct table *tp, const char *n, uint32_t h)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* create new tbl entry */
|
/* create new tbl entry */
|
||||||
len = strlen(n) + 1;
|
len = strlen(n);
|
||||||
p = alloc(offsetof(struct tbl, name[0]) + len, tp->areap);
|
checkoktoadd(len, offsetof(struct tbl, name[0]) + 1);
|
||||||
|
p = alloc(offsetof(struct tbl, name[0]) + ++len, tp->areap);
|
||||||
p->flag = 0;
|
p->flag = 0;
|
||||||
p->type = 0;
|
p->type = 0;
|
||||||
p->areap = tp->areap;
|
p->areap = tp->areap;
|
||||||
@ -1456,7 +1458,8 @@ ktsort(struct table *tp)
|
|||||||
size_t i;
|
size_t i;
|
||||||
struct tbl **p, **sp, **dp;
|
struct tbl **p, **sp, **dp;
|
||||||
|
|
||||||
p = alloc((tp->size + 1) * sizeof(struct tbl *), ATEMP);
|
/* tp->size + 1 will not overflow */
|
||||||
|
p = alloc2(tp->size + 1, sizeof(struct tbl *), ATEMP);
|
||||||
sp = tp->tbls; /* source */
|
sp = tp->tbls; /* source */
|
||||||
dp = p; /* dest */
|
dp = p; /* dest */
|
||||||
i = (size_t)tp->size;
|
i = (size_t)tp->size;
|
||||||
|
38
misc.c
38
misc.c
@ -29,7 +29,7 @@
|
|||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.146 2010/09/14 21:15:10 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.147 2010/09/14 21:26:15 tg Exp $");
|
||||||
|
|
||||||
unsigned char chtypes[UCHAR_MAX + 1]; /* type bits for unsigned char */
|
unsigned char chtypes[UCHAR_MAX + 1]; /* type bits for unsigned char */
|
||||||
|
|
||||||
@ -45,6 +45,25 @@ static const unsigned char *cclass(const unsigned char *, int);
|
|||||||
static void chvt(const char *);
|
static void chvt(const char *);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef SETUID_CAN_FAIL_WITH_EAGAIN
|
||||||
|
/* we don't need to check for other codes, EPERM won't happen */
|
||||||
|
#define DO_SETUID(func, argvec) do { \
|
||||||
|
bool messaged = false; \
|
||||||
|
\
|
||||||
|
while (/* CONSTCOND */ 1) \
|
||||||
|
if (!(func argvec) || errno != EAGAIN) \
|
||||||
|
break; \
|
||||||
|
else if (!messaged) { \
|
||||||
|
warningf(true, "%s failed with EAGAIN," \
|
||||||
|
" probably due to a too low process" \
|
||||||
|
" limit; retrying infinitely", #func); \
|
||||||
|
messaged = true; \
|
||||||
|
} \
|
||||||
|
} while (/* CONSTCOND */ 0)
|
||||||
|
#else
|
||||||
|
#define DO_SETUID(func, argvec) func argvec
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fast character classes
|
* Fast character classes
|
||||||
*/
|
*/
|
||||||
@ -82,12 +101,15 @@ initctypes(void)
|
|||||||
|
|
||||||
/* called from XcheckN() to grow buffer */
|
/* called from XcheckN() to grow buffer */
|
||||||
char *
|
char *
|
||||||
Xcheck_grow_(XString *xsp, const char *xp, unsigned int more)
|
Xcheck_grow_(XString *xsp, const char *xp, size_t more)
|
||||||
{
|
{
|
||||||
const char *old_beg = xsp->beg;
|
const char *old_beg = xsp->beg;
|
||||||
|
|
||||||
xsp->len += more > xsp->len ? more : xsp->len;
|
if (more < xsp->len)
|
||||||
xsp->beg = aresize(xsp->beg, xsp->len + 8, xsp->areap);
|
more = xsp->len;
|
||||||
|
/* (xsp->len + X_EXTRA) never overflows */
|
||||||
|
checkoktoadd(more, xsp->len + X_EXTRA);
|
||||||
|
xsp->beg = aresize(xsp->beg, (xsp->len += more) + X_EXTRA, xsp->areap);
|
||||||
xsp->end = xsp->beg + xsp->len;
|
xsp->end = xsp->beg + xsp->len;
|
||||||
return (xsp->beg + (xp - old_beg));
|
return (xsp->beg + (xp - old_beg));
|
||||||
}
|
}
|
||||||
@ -222,14 +244,16 @@ change_flag(enum sh_flag f, int what, unsigned int newval)
|
|||||||
#if HAVE_SETRESUGID
|
#if HAVE_SETRESUGID
|
||||||
gid_t kshegid = getgid();
|
gid_t kshegid = getgid();
|
||||||
|
|
||||||
setresgid(kshegid, kshegid, kshegid);
|
DO_SETUID(setresgid, (kshegid, kshegid, kshegid));
|
||||||
#if HAVE_SETGROUPS
|
#if HAVE_SETGROUPS
|
||||||
|
/* setgroups doesn't EAGAIN on Linux */
|
||||||
setgroups(1, &kshegid);
|
setgroups(1, &kshegid);
|
||||||
#endif
|
#endif
|
||||||
setresuid(ksheuid, ksheuid, ksheuid);
|
DO_SETUID(setresuid, (ksheuid, ksheuid, ksheuid));
|
||||||
#else
|
#else
|
||||||
|
/* seteuid, setegid, setgid don't EAGAIN on Linux */
|
||||||
seteuid(ksheuid = kshuid = getuid());
|
seteuid(ksheuid = kshuid = getuid());
|
||||||
setuid(ksheuid);
|
DO_SETUID(setuid, (ksheuid));
|
||||||
setegid(kshegid = kshgid = getgid());
|
setegid(kshegid = kshgid = getgid());
|
||||||
setgid(kshegid);
|
setgid(kshegid);
|
||||||
#endif
|
#endif
|
||||||
|
44
setmode.c
44
setmode.c
@ -33,14 +33,10 @@
|
|||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(HAVE_CONFIG_H) && (HAVE_CONFIG_H != 0)
|
#ifdef IN_MKSH
|
||||||
/* usually when packaged with third-party software */
|
#include "sh.h"
|
||||||
#ifdef CONFIG_H_FILENAME
|
#undef SETMODE_DEBUG
|
||||||
#include CONFIG_H_FILENAME
|
|
||||||
#else
|
#else
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
@ -55,20 +51,36 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
__SCCSID("@(#)setmode.c 8.2 (Berkeley) 3/25/94");
|
#endif
|
||||||
__RCSID("$MirOS: src/bin/mksh/setmode.c,v 1.14 2009/06/10 18:12:48 tg Rel $");
|
|
||||||
__RCSID("$miros: src/lib/libc/gen/setmode.c,v 1.12 2009/06/10 18:12:42 tg Exp $");
|
__SCCSID("@(#)setmode.c 8.2 (Berkeley) 3/25/94");
|
||||||
|
__RCSID("$MirOS: src/bin/mksh/setmode.c,v 1.15 2010/09/14 21:26:16 tg Exp $");
|
||||||
|
__RCSID("$miros: src/lib/libc/gen/setmode.c,v 1.14 2010/09/14 21:26:04 tg Exp $");
|
||||||
|
|
||||||
|
#ifdef IN_MKSH
|
||||||
|
|
||||||
/* for mksh */
|
|
||||||
#ifdef ksh_isdigit
|
#ifdef ksh_isdigit
|
||||||
#undef isdigit
|
#undef isdigit
|
||||||
#define isdigit ksh_isdigit
|
#define isdigit ksh_isdigit
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
#ifndef S_ISTXT
|
#ifndef S_ISTXT
|
||||||
#define S_ISTXT 0001000
|
#define S_ISTXT 0001000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef SIZE_MAX
|
||||||
|
#ifdef SIZE_T_MAX
|
||||||
|
#define SIZE_MAX SIZE_T_MAX
|
||||||
|
#else
|
||||||
|
#define SIZE_MAX ((size_t)-1)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define SET_LEN 6 /* initial # of bitcmd struct to malloc */
|
#define SET_LEN 6 /* initial # of bitcmd struct to malloc */
|
||||||
#define SET_LEN_INCR 4 /* # of bitcmd structs to add as needed */
|
#define SET_LEN_INCR 4 /* # of bitcmd structs to add as needed */
|
||||||
|
|
||||||
@ -165,12 +177,15 @@ getmode(const void *bbox, mode_t omode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define notoktomul(a, b) ((a) && (b) && (SIZE_MAX / (a) < (b)))
|
||||||
|
|
||||||
#define ADDCMD(a, b, c, d) \
|
#define ADDCMD(a, b, c, d) \
|
||||||
if (set >= endset) { \
|
if (set >= endset) { \
|
||||||
BITCMD *newset; \
|
BITCMD *newset; \
|
||||||
setlen += SET_LEN_INCR; \
|
setlen += SET_LEN_INCR; \
|
||||||
newset = realloc(saveset, sizeof(BITCMD) * setlen); \
|
if (notoktomul(setlen, sizeof(BITCMD)) || \
|
||||||
if (newset == NULL) { \
|
(newset = realloc(saveset, setlen * \
|
||||||
|
sizeof(BITCMD))) == NULL) { \
|
||||||
free(saveset); \
|
free(saveset); \
|
||||||
return (NULL); \
|
return (NULL); \
|
||||||
} \
|
} \
|
||||||
@ -210,7 +225,8 @@ setmode(const char *p)
|
|||||||
|
|
||||||
setlen = SET_LEN + 2;
|
setlen = SET_LEN + 2;
|
||||||
|
|
||||||
if ((set = calloc(sizeof(BITCMD), setlen)) == NULL)
|
if (notoktomul(setlen, sizeof(BITCMD)) ||
|
||||||
|
(set = malloc(setlen * sizeof(BITCMD))) == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
saveset = set;
|
saveset = set;
|
||||||
endset = set + (setlen - 2);
|
endset = set + (setlen - 2);
|
||||||
|
36
sh.h
36
sh.h
@ -154,9 +154,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef EXTERN
|
#ifdef EXTERN
|
||||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.413 2010/09/14 21:15:11 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.414 2010/09/14 21:26:16 tg Exp $");
|
||||||
#endif
|
#endif
|
||||||
#define MKSH_VERSION "R39 2010/09/05"
|
#define MKSH_VERSION "R39 2010/09/14"
|
||||||
|
|
||||||
#ifndef MKSH_INCLUDES_ONLY
|
#ifndef MKSH_INCLUDES_ONLY
|
||||||
|
|
||||||
@ -630,10 +630,11 @@ extern const struct shoption options[];
|
|||||||
/* null value for variable; comparision pointer for unset */
|
/* null value for variable; comparision pointer for unset */
|
||||||
EXTERN char null[] I__("");
|
EXTERN char null[] I__("");
|
||||||
/* helpers for string pooling */
|
/* helpers for string pooling */
|
||||||
#define T_synerr "syntax error"
|
EXTERN const char T_intovfl[] I__("integer overflow %lu %c %lu prevented");
|
||||||
EXTERN const char r_fc_e_[] I__("r=fc -e -");
|
EXTERN const char T_synerr[] I__("syntax error");
|
||||||
#define fc_e_ (r_fc_e_ + 2) /* "fc -e -" */
|
EXTERN const char T_r_fc_e_[] I__("r=fc -e -");
|
||||||
#define fc_e_n 7 /* strlen(fc_e_) */
|
#define T_fc_e_ (T_r_fc_e_ + 2) /* "fc -e -" */
|
||||||
|
#define Tn_fc_e_ 7 /* strlen(T_fc_e_) */
|
||||||
EXTERN const char T_local_typeset[] I__("local=typeset");
|
EXTERN const char T_local_typeset[] I__("local=typeset");
|
||||||
#define T__typeset (T_local_typeset + 5) /* "=typeset" */
|
#define T__typeset (T_local_typeset + 5) /* "=typeset" */
|
||||||
#define T_typeset (T_local_typeset + 6) /* "typeset" */
|
#define T_typeset (T_local_typeset + 6) /* "typeset" */
|
||||||
@ -1223,7 +1224,7 @@ typedef char *XStringP;
|
|||||||
#define XcheckN(xs, xp, n) do { \
|
#define XcheckN(xs, xp, n) do { \
|
||||||
int more = ((xp) + (n)) - (xs).end; \
|
int more = ((xp) + (n)) - (xs).end; \
|
||||||
if (more > 0) \
|
if (more > 0) \
|
||||||
(xp) = Xcheck_grow_(&(xs), (xp), more); \
|
(xp) = Xcheck_grow_(&(xs), (xp), (size_t)more); \
|
||||||
} while (/* CONSTCOND */ 0)
|
} while (/* CONSTCOND */ 0)
|
||||||
|
|
||||||
/* check for overflow, expand string */
|
/* check for overflow, expand string */
|
||||||
@ -1244,7 +1245,7 @@ typedef char *XStringP;
|
|||||||
#define Xsavepos(xs, xp) ((xp) - (xs).beg)
|
#define Xsavepos(xs, xp) ((xp) - (xs).beg)
|
||||||
#define Xrestpos(xs, xp, n) ((xs).beg + (n))
|
#define Xrestpos(xs, xp, n) ((xs).beg + (n))
|
||||||
|
|
||||||
char *Xcheck_grow_(XString *, const char *, unsigned int);
|
char *Xcheck_grow_(XString *, const char *, size_t);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* expandable vector of generic pointers
|
* expandable vector of generic pointers
|
||||||
@ -1257,7 +1258,7 @@ typedef struct XPtrV {
|
|||||||
|
|
||||||
#define XPinit(x, n) do { \
|
#define XPinit(x, n) do { \
|
||||||
void **vp__; \
|
void **vp__; \
|
||||||
vp__ = alloc((n) * sizeof(void *), ATEMP); \
|
vp__ = alloc2((n), sizeof(void *), ATEMP); \
|
||||||
(x).cur = (x).beg = vp__; \
|
(x).cur = (x).beg = vp__; \
|
||||||
(x).end = vp__ + (n); \
|
(x).end = vp__ + (n); \
|
||||||
} while (/* CONSTCOND */ 0)
|
} while (/* CONSTCOND */ 0)
|
||||||
@ -1265,8 +1266,8 @@ typedef struct XPtrV {
|
|||||||
#define XPput(x, p) do { \
|
#define XPput(x, p) do { \
|
||||||
if ((x).cur >= (x).end) { \
|
if ((x).cur >= (x).end) { \
|
||||||
size_t n = XPsize(x); \
|
size_t n = XPsize(x); \
|
||||||
(x).beg = aresize((x).beg, \
|
(x).beg = aresize2((x).beg, \
|
||||||
n * 2 * sizeof(void *), ATEMP); \
|
n, 2 * sizeof(void *), ATEMP); \
|
||||||
(x).cur = (x).beg + n; \
|
(x).cur = (x).beg + n; \
|
||||||
(x).end = (x).cur + n; \
|
(x).end = (x).cur + n; \
|
||||||
} \
|
} \
|
||||||
@ -1275,7 +1276,7 @@ typedef struct XPtrV {
|
|||||||
|
|
||||||
#define XPptrv(x) ((x).beg)
|
#define XPptrv(x) ((x).beg)
|
||||||
#define XPsize(x) ((x).cur - (x).beg)
|
#define XPsize(x) ((x).cur - (x).beg)
|
||||||
#define XPclose(x) aresize((x).beg, XPsize(x) * sizeof(void *), ATEMP)
|
#define XPclose(x) aresize2((x).beg, XPsize(x), sizeof(void *), ATEMP)
|
||||||
#define XPfree(x) afree((x).beg, ATEMP)
|
#define XPfree(x) afree((x).beg, ATEMP)
|
||||||
|
|
||||||
#define IDENT 64
|
#define IDENT 64
|
||||||
@ -1392,12 +1393,21 @@ EXTERN int histsize; /* history size */
|
|||||||
/* user and system time of last j_waitjed job */
|
/* user and system time of last j_waitjed job */
|
||||||
EXTERN struct timeval j_usrtime, j_systime;
|
EXTERN struct timeval j_usrtime, j_systime;
|
||||||
|
|
||||||
|
#define notoktoadd(val, cnst) ((val) > (SIZE_MAX - (cnst)))
|
||||||
|
#define checkoktoadd(val, cnst) do { \
|
||||||
|
if (notoktoadd((val), (cnst))) \
|
||||||
|
internal_errorf(T_intovfl, (unsigned long)(val), \
|
||||||
|
'+', (unsigned long)(cnst)); \
|
||||||
|
} while (/* CONSTCOND */ 0)
|
||||||
|
|
||||||
/* lalloc.c */
|
/* lalloc.c */
|
||||||
void ainit(Area *);
|
void ainit(Area *);
|
||||||
void afreeall(Area *);
|
void afreeall(Area *);
|
||||||
/* these cannot fail and can take NULL (not for ap) */
|
/* these cannot fail and can take NULL (not for ap) */
|
||||||
#define alloc(n, ap) aresize(NULL, (n), (ap))
|
#define alloc(n, ap) aresize(NULL, (n), (ap))
|
||||||
|
#define alloc2(m, n, ap) aresize2(NULL, (m), (n), (ap))
|
||||||
void *aresize(void *, size_t, Area *);
|
void *aresize(void *, size_t, Area *);
|
||||||
|
void *aresize2(void *, size_t, size_t, Area *);
|
||||||
void afree(void *, Area *); /* can take NULL */
|
void afree(void *, Area *); /* can take NULL */
|
||||||
/* edit.c */
|
/* edit.c */
|
||||||
#ifndef MKSH_SMALL
|
#ifndef MKSH_SMALL
|
||||||
|
13
shf.c
13
shf.c
@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.39 2010/08/28 20:22:23 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.40 2010/09/14 21:26:17 tg Exp $");
|
||||||
|
|
||||||
/* flags to shf_emptybuf() */
|
/* flags to shf_emptybuf() */
|
||||||
#define EB_READSW 0x01 /* about to switch to reading */
|
#define EB_READSW 0x01 /* about to switch to reading */
|
||||||
@ -47,7 +47,8 @@ struct shf *
|
|||||||
shf_open(const char *name, int oflags, int mode, int sflags)
|
shf_open(const char *name, int oflags, int mode, int sflags)
|
||||||
{
|
{
|
||||||
struct shf *shf;
|
struct shf *shf;
|
||||||
int bsize = sflags & SHF_UNBUF ? (sflags & SHF_RD ? 1 : 0) : SHF_BSIZE;
|
int bsize = /* at most 512 */
|
||||||
|
sflags & SHF_UNBUF ? (sflags & SHF_RD ? 1 : 0) : SHF_BSIZE;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
/* Done before open so if alloca fails, fd won't be lost. */
|
/* Done before open so if alloca fails, fd won't be lost. */
|
||||||
@ -85,7 +86,8 @@ shf_open(const char *name, int oflags, int mode, int sflags)
|
|||||||
struct shf *
|
struct shf *
|
||||||
shf_fdopen(int fd, int sflags, struct shf *shf)
|
shf_fdopen(int fd, int sflags, struct shf *shf)
|
||||||
{
|
{
|
||||||
int bsize = sflags & SHF_UNBUF ? (sflags & SHF_RD ? 1 : 0) : SHF_BSIZE;
|
int bsize = /* at most 512 */
|
||||||
|
sflags & SHF_UNBUF ? (sflags & SHF_RD ? 1 : 0) : SHF_BSIZE;
|
||||||
|
|
||||||
/* use fcntl() to figure out correct read/write flags */
|
/* use fcntl() to figure out correct read/write flags */
|
||||||
if (sflags & SHF_GETFL) {
|
if (sflags & SHF_GETFL) {
|
||||||
@ -142,7 +144,8 @@ shf_fdopen(int fd, int sflags, struct shf *shf)
|
|||||||
struct shf *
|
struct shf *
|
||||||
shf_reopen(int fd, int sflags, struct shf *shf)
|
shf_reopen(int fd, int sflags, struct shf *shf)
|
||||||
{
|
{
|
||||||
int bsize = sflags & SHF_UNBUF ? (sflags & SHF_RD ? 1 : 0) : SHF_BSIZE;
|
int bsize = /* at most 512 */
|
||||||
|
sflags & SHF_UNBUF ? (sflags & SHF_RD ? 1 : 0) : SHF_BSIZE;
|
||||||
|
|
||||||
/* use fcntl() to figure out correct read/write flags */
|
/* use fcntl() to figure out correct read/write flags */
|
||||||
if (sflags & SHF_GETFL) {
|
if (sflags & SHF_GETFL) {
|
||||||
@ -344,7 +347,7 @@ shf_emptybuf(struct shf *shf, int flags)
|
|||||||
!(shf->flags & SHF_ALLOCB))
|
!(shf->flags & SHF_ALLOCB))
|
||||||
return (EOF);
|
return (EOF);
|
||||||
/* allocate more space for buffer */
|
/* allocate more space for buffer */
|
||||||
nbuf = aresize(shf->buf, 2 * shf->wbsize, shf->areap);
|
nbuf = aresize2(shf->buf, 2, shf->wbsize, shf->areap);
|
||||||
shf->rp = nbuf + (shf->rp - shf->buf);
|
shf->rp = nbuf + (shf->rp - shf->buf);
|
||||||
shf->wp = nbuf + (shf->wp - shf->buf);
|
shf->wp = nbuf + (shf->wp - shf->buf);
|
||||||
shf->rbsize += shf->wbsize;
|
shf->rbsize += shf->wbsize;
|
||||||
|
10
syn.c
10
syn.c
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.51 2010/08/28 20:22:23 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.52 2010/09/14 21:26:18 tg Exp $");
|
||||||
|
|
||||||
struct nesting_state {
|
struct nesting_state {
|
||||||
int start_token; /* token than began nesting (eg, FOR) */
|
int start_token; /* token than began nesting (eg, FOR) */
|
||||||
@ -231,7 +231,8 @@ get_command(int cf)
|
|||||||
XPtrV args, vars;
|
XPtrV args, vars;
|
||||||
struct nesting_state old_nesting;
|
struct nesting_state old_nesting;
|
||||||
|
|
||||||
iops = alloc((NUFILE + 1) * sizeof(struct ioword *), ATEMP);
|
/* NUFILE is small enough to leave this addition unchecked */
|
||||||
|
iops = alloc2((NUFILE + 1), sizeof(struct ioword *), ATEMP);
|
||||||
XPinit(args, 16);
|
XPinit(args, 16);
|
||||||
XPinit(vars, 16);
|
XPinit(vars, 16);
|
||||||
|
|
||||||
@ -476,7 +477,7 @@ get_command(int cf)
|
|||||||
t->ioact = NULL;
|
t->ioact = NULL;
|
||||||
} else {
|
} else {
|
||||||
iops[iopn++] = NULL;
|
iops[iopn++] = NULL;
|
||||||
iops = aresize(iops, iopn * sizeof(struct ioword *), ATEMP);
|
iops = aresize2(iops, iopn, sizeof(struct ioword *), ATEMP);
|
||||||
t->ioact = iops;
|
t->ioact = iops;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -656,12 +657,13 @@ function_body(char *name,
|
|||||||
if ((t->left = get_command(CONTIN)) == NULL) {
|
if ((t->left = get_command(CONTIN)) == NULL) {
|
||||||
char *tv;
|
char *tv;
|
||||||
/*
|
/*
|
||||||
* Probably something like foo() followed by eof or ;.
|
* Probably something like foo() followed by EOF or ';'.
|
||||||
* This is accepted by sh and ksh88.
|
* This is accepted by sh and ksh88.
|
||||||
* To make "typeset -f foo" work reliably (so its output can
|
* To make "typeset -f foo" work reliably (so its output can
|
||||||
* be used as input), we pretend there is a colon here.
|
* be used as input), we pretend there is a colon here.
|
||||||
*/
|
*/
|
||||||
t->left = newtp(TCOM);
|
t->left = newtp(TCOM);
|
||||||
|
/* (2 * sizeof(char *)) is small enough */
|
||||||
t->left->args = alloc(2 * sizeof(char *), ATEMP);
|
t->left->args = alloc(2 * sizeof(char *), ATEMP);
|
||||||
t->left->args[0] = tv = alloc(3, ATEMP);
|
t->left->args[0] = tv = alloc(3, ATEMP);
|
||||||
tv[0] = CHAR;
|
tv[0] = CHAR;
|
||||||
|
8
tree.c
8
tree.c
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.31 2010/08/28 20:22:24 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.32 2010/09/14 21:26:19 tg Exp $");
|
||||||
|
|
||||||
#define INDENT 4
|
#define INDENT 4
|
||||||
|
|
||||||
@ -454,7 +454,7 @@ tcopy(struct op *t, Area *ap)
|
|||||||
else {
|
else {
|
||||||
for (tw = (const char **)t->vars; *tw++ != NULL; )
|
for (tw = (const char **)t->vars; *tw++ != NULL; )
|
||||||
;
|
;
|
||||||
rw = r->vars = alloc((tw - (const char **)t->vars + 1) *
|
rw = r->vars = alloc2(tw - (const char **)t->vars + 1,
|
||||||
sizeof(*tw), ap);
|
sizeof(*tw), ap);
|
||||||
for (tw = (const char **)t->vars; *tw != NULL; )
|
for (tw = (const char **)t->vars; *tw != NULL; )
|
||||||
*rw++ = wdcopy(*tw++, ap);
|
*rw++ = wdcopy(*tw++, ap);
|
||||||
@ -466,7 +466,7 @@ tcopy(struct op *t, Area *ap)
|
|||||||
else {
|
else {
|
||||||
for (tw = t->args; *tw++ != NULL; )
|
for (tw = t->args; *tw++ != NULL; )
|
||||||
;
|
;
|
||||||
r->args = (const char **)(rw = alloc((tw - t->args + 1) *
|
r->args = (const char **)(rw = alloc2(tw - t->args + 1,
|
||||||
sizeof(*tw), ap));
|
sizeof(*tw), ap));
|
||||||
for (tw = t->args; *tw != NULL; )
|
for (tw = t->args; *tw != NULL; )
|
||||||
*rw++ = wdcopy(*tw++, ap);
|
*rw++ = wdcopy(*tw++, ap);
|
||||||
@ -636,7 +636,7 @@ iocopy(struct ioword **iow, Area *ap)
|
|||||||
|
|
||||||
for (ior = iow; *ior++ != NULL; )
|
for (ior = iow; *ior++ != NULL; )
|
||||||
;
|
;
|
||||||
ior = alloc((ior - iow + 1) * sizeof(struct ioword *), ap);
|
ior = alloc2(ior - iow + 1, sizeof(struct ioword *), ap);
|
||||||
|
|
||||||
for (i = 0; iow[i] != NULL; i++) {
|
for (i = 0; iow[i] != NULL; i++) {
|
||||||
struct ioword *p, *q;
|
struct ioword *p, *q;
|
||||||
|
14
var.c
14
var.c
@ -26,7 +26,7 @@
|
|||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.112 2010/08/28 20:22:24 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.113 2010/09/14 21:26:19 tg Exp $");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Variables
|
* Variables
|
||||||
@ -649,10 +649,13 @@ exportprep(struct tbl *vp, const char *val)
|
|||||||
{
|
{
|
||||||
char *xp;
|
char *xp;
|
||||||
char *op = (vp->flag&ALLOC) ? vp->val.s : NULL;
|
char *op = (vp->flag&ALLOC) ? vp->val.s : NULL;
|
||||||
int namelen = strlen(vp->name);
|
size_t namelen, vallen;
|
||||||
int vallen = strlen(val) + 1;
|
|
||||||
|
namelen = strlen(vp->name);
|
||||||
|
vallen = strlen(val) + 1;
|
||||||
|
|
||||||
vp->flag |= ALLOC;
|
vp->flag |= ALLOC;
|
||||||
|
/* since name+val are both in memory this can go unchecked */
|
||||||
xp = alloc(namelen + 1 + vallen, vp->areap);
|
xp = alloc(namelen + 1 + vallen, vp->areap);
|
||||||
memcpy(vp->val.s = xp, vp->name, namelen);
|
memcpy(vp->val.s = xp, vp->name, namelen);
|
||||||
xp += namelen;
|
xp += namelen;
|
||||||
@ -1317,9 +1320,10 @@ arraysearch(struct tbl *vp, uint32_t val)
|
|||||||
news = curr;
|
news = curr;
|
||||||
} else
|
} else
|
||||||
news = NULL;
|
news = NULL;
|
||||||
len = strlen(vp->name) + 1;
|
|
||||||
if (!news) {
|
if (!news) {
|
||||||
news = alloc(offsetof(struct tbl, name[0]) + len, vp->areap);
|
len = strlen(vp->name);
|
||||||
|
checkoktoadd(len, 1 + offsetof(struct tbl, name[0]));
|
||||||
|
news = alloc(offsetof(struct tbl, name[0]) + ++len, vp->areap);
|
||||||
memcpy(news->name, vp->name, len);
|
memcpy(news->name, vp->name, len);
|
||||||
}
|
}
|
||||||
news->flag = (vp->flag & ~(ALLOC|DEFINED|ISSET|SPECIAL)) | AINDEX;
|
news->flag = (vp->flag & ~(ALLOC|DEFINED|ISSET|SPECIAL)) | AINDEX;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user