diff --git a/shell/CHANGELOG b/shell/CHANGELOG index a7380de27..2d1d2fa4a 100644 --- a/shell/CHANGELOG +++ b/shell/CHANGELOG @@ -1,2 +1,3 @@ ---- Changes since 1.650 ---- The output from commands is now limited to 100k by default, to reduce memory consumption in Webmin and in the browser if a large command is executed. +The run-time of a command is now limited to 24 hours by default, to prevent eternal commands like tail -f from continuing in the the background forever. diff --git a/shell/index.cgi b/shell/index.cgi index 913682cea..55bb4d398 100755 --- a/shell/index.cgi +++ b/shell/index.cgi @@ -70,28 +70,64 @@ if (!$in{'clear'}) { else { $cmd = "($cmd) 2>&1"; } - &open_execute_command(OUTPUT, $cmd, 1, 0); + $pid = &open_execute_command(OUTPUT, $cmd, 1, 0); $out = ""; $trunc = 0; $total = 0; - while() { - $total += length($_); + $timedout = 0; + $start = time(); + $max = $config{'max_runtime'}; + while(1) { + $elapsed = time() - $start; + if ($config{'max_runtime'}) { + # Wait for some output, up to timeout + if ($elapsed >= $max) { + $timedout = 1; + last; + } + local $rmask; + vec($rmask, fileno(OUTPUT), 1) = 1; + $sel = select($rmask, undef, undef, + $config{'max_runtime'} - $elapsed); + $elapsed = time() - $start; + if (!$sel || $sel < 0) { + # Select didn't find anything + if ($elapsed >= $max) { + $timedout = 1; + } + last; + } + } + local $buf; + $got = sysread(OUTPUT, $buf, 1024); + last if ($got <= 0); + $total += length($buf); if ($config{'max_output'} && length($out) < $config{'max_output'}) { - $out .= $_; + $out .= $buf; } else { $trunc = 1; } } + if ($timedout && $pid) { + kill('TERM', $pid); + } close(OUTPUT); &reset_environment() if ($config{'clear_envs'}); + if ($out && $out !~ /\n$/) { + $out .= "\n"; + } $out = &html_escape($out, 1); if ($trunc) { $out .= "".&text('index_trunced', &nice_size($config{'max_output'}), &nice_size($total))."

\n"; } + if ($timedout) { + $out .= "".&text('index_timedout', + $config{'max_runtime'})."

\n"; + } $history .= $out; } @previous = &unique(@previous, $fullcmd); diff --git a/shell/lang/en b/shell/lang/en index 7fb86dab6..0f19658a9 100644 --- a/shell/lang/en +++ b/shell/lang/en @@ -7,6 +7,7 @@ index_desc=Enter a shell command to execute in the text field below. The cd< index_pok=Execute previous command index_edit=Edit previous index_trunced=Total output of $2 was truncated at $1. +index_timedout=Command was terminated after running for $1 seconds. acl_user=Execute commands as user acl_user_def=Current Webmin user