address "env RANDOM=1=2=3 mksh" DoS by integrifying more
This commit is contained in:
4
check.t
4
check.t
@ -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: 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 $
|
||||
@ -25,7 +25,7 @@
|
||||
# http://www.research.att.com/~gsf/public/ifs.sh
|
||||
|
||||
expected-stdout:
|
||||
@(#)MIRBSD KSH R40 2011/06/30
|
||||
@(#)MIRBSD KSH R40 2011/07/02
|
||||
description:
|
||||
Check version of shell.
|
||||
stdin:
|
||||
|
37
main.c
37
main.c
@ -33,7 +33,7 @@
|
||||
#include <locale.h>
|
||||
#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;
|
||||
|
||||
@ -61,9 +61,7 @@ static const char initsubs[] =
|
||||
static const char *initcoms[] = {
|
||||
T_typeset, "-r", initvsn, NULL,
|
||||
T_typeset, "-x", "HOME", "PATH", "RANDOM", "SHELL", NULL,
|
||||
T_typeset, "-i10", "COLUMNS", "KSHEGID", "KSHGID", "KSHUID", "LINES",
|
||||
"OPTIND", "PGRP", "PPID", "RANDOM", "SECONDS", "TMOUT", "USER_ID",
|
||||
NULL,
|
||||
T_typeset, "-i10", "SECONDS", "TMOUT", NULL,
|
||||
T_alias,
|
||||
"integer=typeset -i",
|
||||
T_local_typeset,
|
||||
@ -92,6 +90,10 @@ static const char *initcoms[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *restr_com[] = {
|
||||
T_typeset, "-r", "PATH", "ENV", "SHELL", NULL
|
||||
};
|
||||
|
||||
static int initio_done;
|
||||
|
||||
/* top-level parsing and execution environment */
|
||||
@ -328,9 +330,9 @@ main(int argc, const char *argv[])
|
||||
while (*wp != NULL)
|
||||
wp++;
|
||||
}
|
||||
setint(global("COLUMNS"), 0);
|
||||
setint(global("LINES"), 0);
|
||||
setint(global("OPTIND"), 1);
|
||||
setint_n(global("COLUMNS"), 0);
|
||||
setint_n(global("LINES"), 0);
|
||||
setint_n(global("OPTIND"), 1);
|
||||
|
||||
kshuid = getuid();
|
||||
kshgid = getgid();
|
||||
@ -343,21 +345,21 @@ main(int argc, const char *argv[])
|
||||
(!ksheuid && !strchr(str_val(vp), '#')))
|
||||
/* setstr can't fail here */
|
||||
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;
|
||||
setint((vp = global("PPID")), (mksh_uari_t)kshppid);
|
||||
setint_n((vp = global("PPID")), (mksh_uari_t)kshppid);
|
||||
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;
|
||||
setint((vp = global("KSHUID")), (mksh_uari_t)kshuid);
|
||||
setint_n((vp = global("KSHUID")), (mksh_uari_t)kshuid);
|
||||
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;
|
||||
setint((vp = global("KSHGID")), (mksh_uari_t)kshgid);
|
||||
setint_n((vp = global("KSHGID")), (mksh_uari_t)kshgid);
|
||||
vp->flag |= INT_U;
|
||||
setint((vp = global("RANDOM")), rndsetup());
|
||||
setint_n((vp = global("RANDOM")), rndsetup());
|
||||
vp->flag |= INT_U;
|
||||
setint((vp_pipest = global("PIPESTATUS")), 0);
|
||||
setint_n((vp_pipest = global("PIPESTATUS")), 0);
|
||||
|
||||
/* Set this before parsing arguments */
|
||||
Flag(FPRIVILEGED) = kshuid != ksheuid || kshgid != kshegid;
|
||||
@ -540,11 +542,6 @@ main(int argc, const char *argv[])
|
||||
}
|
||||
|
||||
if (restricted) {
|
||||
static const char *restr_com[] = {
|
||||
T_typeset, "-r", "PATH",
|
||||
"ENV", "SHELL",
|
||||
NULL
|
||||
};
|
||||
shcomexec(restr_com);
|
||||
/* After typeset command... */
|
||||
Flag(FRESTRICTED) = 1;
|
||||
|
5
sh.h
5
sh.h
@ -151,9 +151,9 @@
|
||||
#endif
|
||||
|
||||
#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
|
||||
#define MKSH_VERSION "R40 2011/06/30"
|
||||
#define MKSH_VERSION "R40 2011/07/02"
|
||||
|
||||
#ifndef MKSH_INCLUDES_ONLY
|
||||
|
||||
@ -1796,6 +1796,7 @@ char *str_val(struct tbl *);
|
||||
int setstr(struct tbl *, const char *, int);
|
||||
struct tbl *setint_v(struct tbl *, struct tbl *, bool);
|
||||
void setint(struct tbl *, mksh_ari_t);
|
||||
void setint_n(struct tbl *, mksh_ari_t);
|
||||
struct tbl *typeset(const char *, Tflag, Tflag, int, int)
|
||||
MKSH_A_NONNULL((__nonnull__ (1)));
|
||||
void unset(struct tbl *, int);
|
||||
|
50
var.c
50
var.c
@ -26,7 +26,7 @@
|
||||
#include <sys/sysctl.h>
|
||||
#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
|
||||
@ -50,7 +50,6 @@ static void getspec(struct tbl *);
|
||||
static void setspec(struct tbl *);
|
||||
static void unsetspec(struct tbl *);
|
||||
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 *);
|
||||
|
||||
/*
|
||||
@ -401,20 +400,6 @@ str_val(struct tbl *vp)
|
||||
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 */
|
||||
int
|
||||
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)
|
||||
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)) {
|
||||
vq->flag &= ~ALLOC;
|
||||
vq->type = 0;
|
||||
afree(vq->val.s, vq->areap);
|
||||
}
|
||||
vq->val.i = num;
|
||||
if (vq->type == 0)
|
||||
/* default base */
|
||||
vq->type = base;
|
||||
vq->flag |= ISSET|INTEGER;
|
||||
if (vq->flag&SPECIAL)
|
||||
setspec(vq);
|
||||
return (vq);
|
||||
}
|
||||
|
||||
static char *
|
||||
@ -1140,7 +1132,7 @@ getspec(struct tbl *vp)
|
||||
return;
|
||||
}
|
||||
vp->flag &= ~SPECIAL;
|
||||
setint(vp, i);
|
||||
setint_n(vp, i);
|
||||
vp->flag |= SPECIAL;
|
||||
}
|
||||
|
||||
@ -1187,11 +1179,6 @@ setspec(struct tbl *vp)
|
||||
sethistfile(str_val(vp));
|
||||
return;
|
||||
#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 */
|
||||
case V_OPTIND:
|
||||
@ -1201,8 +1188,14 @@ setspec(struct tbl *vp)
|
||||
case V_RANDOM:
|
||||
case V_SECONDS:
|
||||
case V_LINENO:
|
||||
case V_TMOUT:
|
||||
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;
|
||||
break;
|
||||
default:
|
||||
@ -1246,6 +1239,9 @@ setspec(struct tbl *vp)
|
||||
/* The -1 is because line numbering starts at 1. */
|
||||
user_lineno = (unsigned int)i - current_lineno - 1;
|
||||
break;
|
||||
case V_TMOUT:
|
||||
ksh_tmout = i >= 0 ? i : 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user