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: 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
37
main.c
@ -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
5
sh.h
@ -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
50
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.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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user