diff --git a/src/avrdude.conf.in b/src/avrdude.conf.in index 9c582d65..9404bbb2 100644 --- a/src/avrdude.conf.in +++ b/src/avrdude.conf.in @@ -421,6 +421,7 @@ default_serial = "@DEFAULT_SER_PORT@"; default_spi = "@DEFAULT_SPI_PORT@"; # default_bitclock = 2.5; default_linuxgpio = "@DEFAULT_LINUXGPIO_PORT@"; +allow_subshells = no; @HAVE_PARPORT_BEGIN@ diff --git a/src/config.c b/src/config.c index e398608c..e0e388c1 100644 --- a/src/config.c +++ b/src/config.c @@ -41,6 +41,7 @@ const char *default_serial; const char *default_spi; double default_bitclock; char const *default_linuxgpio; +int allow_subshells; LISTID string_list; LISTID number_list; diff --git a/src/config_gram.y b/src/config_gram.y index 93379ca6..d862e204 100644 --- a/src/config_gram.y +++ b/src/config_gram.y @@ -73,6 +73,7 @@ static int pin_name; %token K_PAGE_SIZE %token K_ALIAS +%token K_ALLOW_SUBSHELLS %token K_BUFF %token K_CONNTYPE %token K_DEDICATED @@ -233,6 +234,11 @@ def : free_token($3); } | + K_ALLOW_SUBSHELLS TKN_EQUAL numexpr TKN_SEMI { + allow_subshells = $3->value.number; + free_token($3); + } | + K_DEFAULT_LINUXGPIO TKN_EQUAL TKN_STRING TKN_SEMI { default_linuxgpio = cache_string($3->value.string); free_token($3); diff --git a/src/developer_opts.c b/src/developer_opts.c index 363305bb..2c60b320 100644 --- a/src/developer_opts.c +++ b/src/developer_opts.c @@ -905,6 +905,7 @@ void dev_output_pgm_part(int dev_opt_c, const char *programmer, int dev_opt_p, c dev_info("default_spi = %s;\n", p = cfg_escape(default_spi)); free(p); dev_info("default_bitclock = %7.5f;\n", default_bitclock); dev_info("default_linuxgpio = %s;\n", p = cfg_escape(default_linuxgpio)); free(p); + dev_info("allow_subshells = %s;\n", allow_subshells? "yes": "no"); dev_info("\n#\n# PROGRAMMER DEFINITIONS\n#\n\n"); } diff --git a/src/doc/avrdude.texi b/src/doc/avrdude.texi index ce6afba0..091b5dfc 100644 --- a/src/doc/avrdude.texi +++ b/src/doc/avrdude.texi @@ -2701,6 +2701,15 @@ option. Assign the default bitclock value. Can be overridden using the @option{-B} option. +@item allow_subshells = @var{no}; +Whether or not AVRDUDE's interactive terminal is allowed to use subshell +@code{!} commands. This defaults to no for security reasons, eg, in the +rare case @code{avrdude -t} is set up with attached hardware to provide a +web service, remote ssh or a login on a PC instead of a shell, say, for +demo or training purposes. In almost all other cases this can be +overridden in the personal @code{avrddude.rc} or @code{.avrduderc} +configuration file with @var{yes}. + @end table diff --git a/src/lexer.l b/src/lexer.l index 1aae32ee..fdbeb53a 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -179,6 +179,7 @@ INF [Ii][Nn][Ff]([Ii][Nn][Ii][Tt][Yy])? } alias { yylval=NULL; return K_ALIAS; } +allow_subshells { yylval=NULL; return K_ALLOW_SUBSHELLS; } allowfullpagebitstream { yylval=NULL; ccap(); return K_ALLOWFULLPAGEBITSTREAM; } buff { yylval=NULL; ccap(); return K_BUFF; } chip_erase { yylval=new_token(K_CHIP_ERASE); ccap(); return K_CHIP_ERASE; } diff --git a/src/libavrdude.h b/src/libavrdude.h index 4b57845a..6ff02937 100644 --- a/src/libavrdude.h +++ b/src/libavrdude.h @@ -1136,14 +1136,15 @@ void walk_programmer_types(/*LISTID programmer_types,*/ walk_programmer_types_cb /* formerly config.h */ -extern LISTID part_list; -extern LISTID programmers; +extern LISTID part_list; +extern LISTID programmers; extern const char *default_programmer; extern const char *default_parallel; extern const char *default_serial; extern const char *default_spi; -extern double default_bitclock; -extern char const * default_linuxgpio; +extern double default_bitclock; +extern char const *default_linuxgpio; +extern int allow_subshells; /* This name is fixed, it's only here for symmetry with * default_parallel and default_serial. */ diff --git a/src/main.c b/src/main.c index cc741540..ecb0de82 100644 --- a/src/main.c +++ b/src/main.c @@ -573,6 +573,7 @@ int main(int argc, char * argv []) default_spi = ""; default_bitclock = 0.0; default_linuxgpio = ""; + allow_subshells = 0; init_config(); diff --git a/src/term.c b/src/term.c index 1a8383b4..0feafc3c 100644 --- a/src/term.c +++ b/src/term.c @@ -1675,7 +1675,7 @@ static int cmd_help(const PROGRAMMER *pgm, const AVRPART *p, int argc, char *arg term_out(cmd[i].desc, cmd[i].name); term_out("\n"); } - term_out("\n" + term_out(" ! : run the command in a subshell, eg, !ls\n\n" "For more details about a terminal command cmd type cmd -?\n\n" "Note that not all programmer derivatives support all commands. Flash and\n" "EEPROM type memories are normally read and written using a cache via paged\n" @@ -1896,6 +1896,21 @@ static int process_line(char *q, const PROGRAMMER *pgm, const AVRPART *p) { if (!*q || (*q == '#')) return 0; + if(*q == '!') { + if(allow_subshells) { + while(*++q && isspace((unsigned char) *q)) + continue; + errno = 0; + int shret = *q? system(q): 0; + if(errno) + pmsg_warning("system() call returned %d: %s\n", shret, strerror(errno)); + } else { + pmsg_warning("subshell commands are by default not allowed in the terminal\n"); + imsg_warning("allow_subshells = yes; in avrdude.rc or ~/.avrduderc changes this\n"); + } + return 0; + } + // Tokenize command line do { argc = 0; argv = NULL;