>>someone should write a safe_system() to replace such calls with, that does
>It'd be AI-complete. How do you know what's dangerous & what's not?
>I'd rather not have people thinking safe_system() is safe when it
>really isn't.
Back in February in comp.security.unix, someone posted msh.c, a minimal
shell program that recognizes I/O redirection but ignores any other shell
metacharacters. Not exactly what was asked for, but a step in the right
direction...
Article 2706 of comp.security.unix:
Path: turtle.mrj.com!uunet!s850.mwc.edu!hearst.acc.Virginia.EDU!darwin.sura.net!howland.reston.ans.net!EU.net!sun4nl!news.nic.surfnet.nl!tuegate.tue.nl!news.win.tue.nl!wzv.win.tue.nl!wzv.win.tue.nl!not-for-mail
From: wietse @
wzv .
win .
tue .
nl (Wietse Venema)
Newsgroups: nasa.infosystems.www,comp.infosystems.www,larc.users.mosaic,comp.security.unix
Subject: Re: Be Careful!! Common security vulnerability w/Fill out forms...
Date: 21 Feb 1994 19:30:12 +0100
Organization: Eindhoven University of Technology, The Netherlands
Lines: 174
Message-ID: <2kaujk$7df @
wzv .
win .
tue .
nl>
References: <BIANCO .
94Feb21084657 @
MiSTy .
larc .
nasa .
gov>
NNTP-Posting-Host: wzv.win.tue.nl
Xref: turtle.mrj.com comp.infosystems.www:7232 comp.security.unix:2706
bianco @
MiSTy .
larc .
nasa .
gov (David Bianco) writes:
>What if you set the DISPLAY to:
>
> dew.cs.odu.edu:0.0 `xterm -display dew.cs.odu.edu:0.0`
That's why we run gopher, www etc. inside a jail (a restricted file
system subtree and "nobody" privilege), with only a minimal shell.
Wietse
/*
* sh.c - Minimal shell, for use with popen(3) or system(3) only. Recognizes
* I/O redirection, but rejects commands with any other shell metacharacters.
*
* Wietse Venema (wswietse @
win .
tue .
nl) 921013: initial version without any
* shell metacharacter support.
*
* Wietse Venema (wswietse @
win .
tue .
nl) 921014: added <, > and >> because
* gopherd needs redirection.
*/
/* Library stuff */
#include <stdio.h>
#include <string.h>
extern char *malloc();
/* Local stuff */
static int parse();
static char *strndup();
static char *special();
static char *redirect();
/* Character classification stuff. */
static char metach[] = "$[]<>*?&^|`;{}()'\"\\";
static char blnks[] = " \t\r\n";
static char meta_or_blnks[] = " \t\r\n$[]<>*?&^|`;{}()'\"\\";
static char *myname; /* for diagnostics */
main(argc, argv)
int argc;
char **argv;
{
char *args[BUFSIZ]; /* generated command-line vector */
/* Allow the form "sh -c command" only. */
myname = argv[0];
if (argc != 3 || strcmp(argv[1], "-c") != 0) {
fprintf(stderr, "usage: %s -c 'command'\n", myname);
exit(1);
}
/* Convert argv[2] to command-line vector. */
if (parse(argv[2], args, BUFSIZ) == 0) {
fprintf(stderr, "%s: empty command\n", myname);
exit(1);
}
/* Run the command or give up. */
execvp(args[0], args);
perror(args[0]);
exit(1);
}
/* parse - build argument vector */
static int parse(src, args, maxarg)
char *src;
char **args;
int maxarg;
{
int argno = 0;
int len;
while (*src) {
/* Sanity check. */
if (argno >= maxarg - 1) {
fprintf(stderr, "%s: too many arguments\n", myname);
exit(1);
}
/* Skip leading whitespace. */
src += strspn(src, blnks);
/* Process next token. */
if (strchr(metach, *src)) { /* special */
src = special(src);
} else { /* regular word */
len = strcspn(src, meta_or_blnks);
args[argno++] = strndup(src, len);
src += len;
}
}
args[argno] = 0;
return (argno);
}
/* special - handle operators etc. */
static char *special(src)
char *src;
{
switch (*src) {
case '>':
if (src[1] == '>') {
return (redirect(src + 2, stdout, "a"));
} else {
return (redirect(src + 1, stdout, "w"));
}
/* NOTREACHED */
case '<':
return (redirect(src + 1, stdin, "r"));
default:
fprintf(stderr, "%s: unsupported operator: ``%c''\n", myname, *src);
exit(1);
/* NOTREACHED */
}
}
/* redirect - redirect input/output from/to file */
static char *redirect(src, strm, mode)
char *src;
FILE *strm;
char *mode;
{
char *path;
int len;
/* Skip whitespace. */
src += strspn(src, blnks);
/* Next token should be regular word. */
if ((len = strcspn(src, meta_or_blnks)) == 0) {
fprintf(stderr, "%s: filename expected, got: %s\n", myname, src);
exit(1);
}
path = strndup(src, len);
src += len;
/* Redirect or bust. */
if (freopen(path, mode, strm) == 0) {
perror(path);
exit(1);
}
return (src);
}
/* strndup - make copy of string */
static char *strndup(str, len)
char *str;
int len;
{
char *dst;
if ((dst = malloc(len + 1)) == 0)
fprintf(stderr, "%s: out of memory\n", myname);
dst[len] = 0;
return (strncpy(dst, str, len));
}
--
Ken Mayer
kmayer @
mrj .
com
|
|