shell/read: check that variable names are sane

function                                             old     new   delta
shell_builtin_read                                  1000    1055     +55
parse_command                                       1460    1463      +3
builtin_umask                                        121     123      +2
is_well_formed_var_name                               73      66      -7

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2010-01-13 18:22:35 +01:00
parent 03d81ef43a
commit 25d9b91d94
5 changed files with 26 additions and 24 deletions

View File

@ -1768,11 +1768,7 @@ static const struct {
const char *text; const char *text;
void (*func)(const char *) FAST_FUNC; void (*func)(const char *) FAST_FUNC;
} varinit_data[] = { } varinit_data[] = {
#if IFS_BROKEN
{ VSTRFIXED|VTEXTFIXED , defifsvar , NULL }, { VSTRFIXED|VTEXTFIXED , defifsvar , NULL },
#else
{ VSTRFIXED|VTEXTFIXED|VUNSET, "IFS\0" , NULL },
#endif
#if ENABLE_ASH_MAIL #if ENABLE_ASH_MAIL
{ VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL\0" , changemail }, { VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL\0" , changemail },
{ VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH\0", changemail }, { VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH\0", changemail },

View File

@ -39,6 +39,7 @@ shell_builtin_read(void FAST_FUNC (*setvar)(const char *name, const char *val),
unsigned end_ms; /* -t TIMEOUT */ unsigned end_ms; /* -t TIMEOUT */
int fd; /* -u FD */ int fd; /* -u FD */
int nchars; /* -n NUM */ int nchars; /* -n NUM */
char **pp;
char *buffer; char *buffer;
struct termios tty, old_tty; struct termios tty, old_tty;
const char *retval; const char *retval;
@ -46,6 +47,16 @@ shell_builtin_read(void FAST_FUNC (*setvar)(const char *name, const char *val),
int startword; int startword;
smallint backslash; smallint backslash;
pp = argv;
while (*pp) {
if (!is_well_formed_var_name(*pp, '\0')) {
/* Mimic bash message */
bb_error_msg("read: '%s': not a valid identifier", *pp);
return (const char *)(uintptr_t)1;
}
pp++;
}
nchars = 0; /* if != 0, -n is in effect */ nchars = 0; /* if != 0, -n is in effect */
if (opt_n) { if (opt_n) {
nchars = bb_strtou(opt_n, NULL, 10); nchars = bb_strtou(opt_n, NULL, 10);

View File

@ -893,16 +893,6 @@ static void cmdedit_update_prompt(void);
/* Utility functions /* Utility functions
*/ */
static int is_well_formed_var_name(const char *s, char terminator)
{
if (!s || !(isalpha(*s) || *s == '_'))
return 0;
s++;
while (isalnum(*s) || *s == '_')
s++;
return *s == terminator;
}
/* Replace each \x with x in place, return ptr past NUL. */ /* Replace each \x with x in place, return ptr past NUL. */
static char *unbackslash(char *src) static char *unbackslash(char *src)
{ {

View File

@ -19,8 +19,17 @@
#include "libbb.h" #include "libbb.h"
#include "shell_common.h" #include "shell_common.h"
#if IFS_BROKEN
const char defifsvar[] ALIGN1 = "IFS= \t\n"; const char defifsvar[] ALIGN1 = "IFS= \t\n";
#else
const char defifs[] ALIGN1 = " \t\n";
#endif int FAST_FUNC is_well_formed_var_name(const char *s, char terminator)
{
if (!s || !(isalpha(*s) || *s == '_'))
return 0;
do
s++;
while (isalnum(*s) || *s == '_');
return *s == terminator;
}

View File

@ -21,14 +21,10 @@
PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
#define IFS_BROKEN 1
#if IFS_BROKEN
extern const char defifsvar[]; /* "IFS= \t\n" */ extern const char defifsvar[]; /* "IFS= \t\n" */
#define defifs (defifsvar + 4) #define defifs (defifsvar + 4)
#else
extern const char defifs[]; /* " \t\n" */ int FAST_FUNC is_well_formed_var_name(const char *s, char terminator);
#endif
POP_SAVED_FUNCTION_VISIBILITY POP_SAVED_FUNCTION_VISIBILITY