address "env RANDOM=1=2=3 mksh" DoS by integrifying more

This commit is contained in:
tg
2011-07-02 17:57:41 +00:00
parent 64aade1a52
commit 0739fa74a0
4 changed files with 45 additions and 51 deletions

View File

@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/check.t,v 1.469 2011/06/30 13:48:09 tg Exp $ # $MirOS: src/bin/mksh/check.t,v 1.470 2011/07/02 17:57:37 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 R40 2011/06/30 @(#)MIRBSD KSH R40 2011/07/02
description: description:
Check version of shell. Check version of shell.
stdin: stdin:

37
main.c
View File

@ -33,7 +33,7 @@
#include <locale.h> #include <locale.h>
#endif #endif
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.193 2011/06/05 19:58:18 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/main.c,v 1.194 2011/07/02 17:57:39 tg Exp $");
extern char **environ; extern char **environ;
@ -61,9 +61,7 @@ static const char initsubs[] =
static const char *initcoms[] = { static const char *initcoms[] = {
T_typeset, "-r", initvsn, NULL, T_typeset, "-r", initvsn, NULL,
T_typeset, "-x", "HOME", "PATH", "RANDOM", "SHELL", NULL, T_typeset, "-x", "HOME", "PATH", "RANDOM", "SHELL", NULL,
T_typeset, "-i10", "COLUMNS", "KSHEGID", "KSHGID", "KSHUID", "LINES", T_typeset, "-i10", "SECONDS", "TMOUT", NULL,
"OPTIND", "PGRP", "PPID", "RANDOM", "SECONDS", "TMOUT", "USER_ID",
NULL,
T_alias, T_alias,
"integer=typeset -i", "integer=typeset -i",
T_local_typeset, T_local_typeset,
@ -92,6 +90,10 @@ static const char *initcoms[] = {
NULL NULL
}; };
static const char *restr_com[] = {
T_typeset, "-r", "PATH", "ENV", "SHELL", NULL
};
static int initio_done; static int initio_done;
/* top-level parsing and execution environment */ /* top-level parsing and execution environment */
@ -328,9 +330,9 @@ main(int argc, const char *argv[])
while (*wp != NULL) while (*wp != NULL)
wp++; wp++;
} }
setint(global("COLUMNS"), 0); setint_n(global("COLUMNS"), 0);
setint(global("LINES"), 0); setint_n(global("LINES"), 0);
setint(global("OPTIND"), 1); setint_n(global("OPTIND"), 1);
kshuid = getuid(); kshuid = getuid();
kshgid = getgid(); kshgid = getgid();
@ -343,21 +345,21 @@ main(int argc, const char *argv[])
(!ksheuid && !strchr(str_val(vp), '#'))) (!ksheuid && !strchr(str_val(vp), '#')))
/* setstr can't fail here */ /* setstr can't fail here */
setstr(vp, safe_prompt, KSH_RETURN_ERROR); setstr(vp, safe_prompt, KSH_RETURN_ERROR);
setint((vp = global("PGRP")), (mksh_uari_t)kshpgrp); setint_n((vp = global("PGRP")), (mksh_uari_t)kshpgrp);
vp->flag |= INT_U; vp->flag |= INT_U;
setint((vp = global("PPID")), (mksh_uari_t)kshppid); setint_n((vp = global("PPID")), (mksh_uari_t)kshppid);
vp->flag |= INT_U; vp->flag |= INT_U;
setint((vp = global("USER_ID")), (mksh_uari_t)ksheuid); setint_n((vp = global("USER_ID")), (mksh_uari_t)ksheuid);
vp->flag |= INT_U; vp->flag |= INT_U;
setint((vp = global("KSHUID")), (mksh_uari_t)kshuid); setint_n((vp = global("KSHUID")), (mksh_uari_t)kshuid);
vp->flag |= INT_U; vp->flag |= INT_U;
setint((vp = global("KSHEGID")), (mksh_uari_t)kshegid); setint_n((vp = global("KSHEGID")), (mksh_uari_t)kshegid);
vp->flag |= INT_U; vp->flag |= INT_U;
setint((vp = global("KSHGID")), (mksh_uari_t)kshgid); setint_n((vp = global("KSHGID")), (mksh_uari_t)kshgid);
vp->flag |= INT_U; vp->flag |= INT_U;
setint((vp = global("RANDOM")), rndsetup()); setint_n((vp = global("RANDOM")), rndsetup());
vp->flag |= INT_U; vp->flag |= INT_U;
setint((vp_pipest = global("PIPESTATUS")), 0); setint_n((vp_pipest = global("PIPESTATUS")), 0);
/* Set this before parsing arguments */ /* Set this before parsing arguments */
Flag(FPRIVILEGED) = kshuid != ksheuid || kshgid != kshegid; Flag(FPRIVILEGED) = kshuid != ksheuid || kshgid != kshegid;
@ -540,11 +542,6 @@ main(int argc, const char *argv[])
} }
if (restricted) { if (restricted) {
static const char *restr_com[] = {
T_typeset, "-r", "PATH",
"ENV", "SHELL",
NULL
};
shcomexec(restr_com); shcomexec(restr_com);
/* After typeset command... */ /* After typeset command... */
Flag(FRESTRICTED) = 1; Flag(FRESTRICTED) = 1;

5
sh.h
View File

@ -151,9 +151,9 @@
#endif #endif
#ifdef EXTERN #ifdef EXTERN
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.480 2011/06/30 13:48:13 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/sh.h,v 1.481 2011/07/02 17:57:40 tg Exp $");
#endif #endif
#define MKSH_VERSION "R40 2011/06/30" #define MKSH_VERSION "R40 2011/07/02"
#ifndef MKSH_INCLUDES_ONLY #ifndef MKSH_INCLUDES_ONLY
@ -1796,6 +1796,7 @@ char *str_val(struct tbl *);
int setstr(struct tbl *, const char *, int); int setstr(struct tbl *, const char *, int);
struct tbl *setint_v(struct tbl *, struct tbl *, bool); struct tbl *setint_v(struct tbl *, struct tbl *, bool);
void setint(struct tbl *, mksh_ari_t); void setint(struct tbl *, mksh_ari_t);
void setint_n(struct tbl *, mksh_ari_t);
struct tbl *typeset(const char *, Tflag, Tflag, int, int) struct tbl *typeset(const char *, Tflag, Tflag, int, int)
MKSH_A_NONNULL((__nonnull__ (1))); MKSH_A_NONNULL((__nonnull__ (1)));
void unset(struct tbl *, int); void unset(struct tbl *, int);

50
var.c
View File

@ -26,7 +26,7 @@
#include <sys/sysctl.h> #include <sys/sysctl.h>
#endif #endif
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.126 2011/06/21 21:50:26 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/var.c,v 1.127 2011/07/02 17:57:41 tg Exp $");
/*- /*-
* Variables * Variables
@ -50,7 +50,6 @@ static void getspec(struct tbl *);
static void setspec(struct tbl *); static void setspec(struct tbl *);
static void unsetspec(struct tbl *); static void unsetspec(struct tbl *);
static int getint(struct tbl *, mksh_ari_t *, bool); static int getint(struct tbl *, mksh_ari_t *, bool);
static mksh_ari_t intval(struct tbl *);
static const char *array_index_calc(const char *, bool *, uint32_t *); static const char *array_index_calc(const char *, bool *, uint32_t *);
/* /*
@ -401,20 +400,6 @@ str_val(struct tbl *vp)
return (s); return (s);
} }
/* get variable integer value, with error checking */
static mksh_ari_t
intval(struct tbl *vp)
{
mksh_ari_t num;
int base;
base = getint(vp, &num, false);
if (base == -1)
/* XXX check calls - is error here ok by POSIX? */
errorf("%s: %s", str_val(vp), "bad number");
return (num);
}
/* set variable to string value */ /* set variable to string value */
int int
setstr(struct tbl *vq, const char *s, int error_ok) setstr(struct tbl *vq, const char *s, int error_ok)
@ -571,19 +556,26 @@ setint_v(struct tbl *vq, struct tbl *vp, bool arith)
if ((base = getint(vp, &num, arith)) == -1) if ((base = getint(vp, &num, arith)) == -1)
return (NULL); return (NULL);
setint_n(vq, num);
if (vq->type == 0)
/* default base */
vq->type = base;
return (vq);
}
/* convert variable vq to integer variable, setting its value to num */
void
setint_n(struct tbl *vq, mksh_ari_t num)
{
if (!(vq->flag & INTEGER) && (vq->flag & ALLOC)) { if (!(vq->flag & INTEGER) && (vq->flag & ALLOC)) {
vq->flag &= ~ALLOC; vq->flag &= ~ALLOC;
vq->type = 0; vq->type = 0;
afree(vq->val.s, vq->areap); afree(vq->val.s, vq->areap);
} }
vq->val.i = num; vq->val.i = num;
if (vq->type == 0)
/* default base */
vq->type = base;
vq->flag |= ISSET|INTEGER; vq->flag |= ISSET|INTEGER;
if (vq->flag&SPECIAL) if (vq->flag&SPECIAL)
setspec(vq); setspec(vq);
return (vq);
} }
static char * static char *
@ -1140,7 +1132,7 @@ getspec(struct tbl *vp)
return; return;
} }
vp->flag &= ~SPECIAL; vp->flag &= ~SPECIAL;
setint(vp, i); setint_n(vp, i);
vp->flag |= SPECIAL; vp->flag |= SPECIAL;
} }
@ -1187,11 +1179,6 @@ setspec(struct tbl *vp)
sethistfile(str_val(vp)); sethistfile(str_val(vp));
return; return;
#endif #endif
case V_TMOUT:
/* AT&T ksh seems to do this (only listen if integer) */
if (vp->flag & INTEGER)
ksh_tmout = vp->val.i >= 0 ? vp->val.i : 0;
return;
/* common sub-cases */ /* common sub-cases */
case V_OPTIND: case V_OPTIND:
@ -1201,8 +1188,14 @@ setspec(struct tbl *vp)
case V_RANDOM: case V_RANDOM:
case V_SECONDS: case V_SECONDS:
case V_LINENO: case V_LINENO:
case V_TMOUT:
vp->flag &= ~SPECIAL; vp->flag &= ~SPECIAL;
i = intval(vp); if (getint(vp, &i, false) == -1) {
s = str_val(vp);
if (st != V_RANDOM)
errorf("%s: %s: %s", vp->name, "bad number", s);
i = hash(s);
}
vp->flag |= SPECIAL; vp->flag |= SPECIAL;
break; break;
default: default:
@ -1246,6 +1239,9 @@ setspec(struct tbl *vp)
/* The -1 is because line numbering starts at 1. */ /* The -1 is because line numbering starts at 1. */
user_lineno = (unsigned int)i - current_lineno - 1; user_lineno = (unsigned int)i - current_lineno - 1;
break; break;
case V_TMOUT:
ksh_tmout = i >= 0 ? i : 0;
break;
} }
} }