Make shell execution a bit more reliable

Previously you would not get feedback when quotes are not terminated or
when the command is too long. Fix this by putting stderr redirection in
the shell command, before eval.
This commit is contained in:
Peter Wu 2016-01-04 13:03:30 +01:00
parent 7ef3448209
commit 396409d3fa
2 changed files with 18 additions and 9 deletions

View file

@ -126,11 +126,14 @@ def validate_message(payload, ignore_crc=False):
raise RuntimeError("Expected trailer %r, found %r" % (tail_exp, tail))
def make_exec_request(shell_command):
# Allow use of shell constructs such as piping. Needs more work not to eat
# all repetitive spaces, it should also escape some things...
body = b'sh -c "$@" -- eval 2>&1 </dev/null '
body += shell_command.encode('ascii') + b'\0'
return make_request(b'EXEC', body=body)
# Allow use of shell constructs such as piping and reports syntax errors
# such as unterminated quotes. Remaining limitation: repetitive spaces are
# still eaten.
argv = b'sh -c eval\t"$*"</dev/null\t2>&1 -- '
argv += shell_command.encode('ascii')
if len(argv) > 255:
raise RuntimeError("Command length %d is larger than 255" % len(argv))
return make_request(b'EXEC', body=argv + b'\0')
### USB or serial port communication

View file

@ -130,19 +130,25 @@ reboot, everything was zeroed out though.
### EXEC - Execute Command
Arguments: none
Request body: NUL-terminated command.
Request body: NUL-terminated command, at most 255 bytes including terminator.
Response body: standard output of the command.
The command is probably split on space and then passes to `execve`. In order to
see standard error, use variables and globbing, use a command such as:
The command is split on spaces and then passed to `execvp`. In order to see
standard error, use variables and globbing, use a command such as:
sh -c "$@" -- eval 2>&1 </dev/null echo $PATH
sh -c eval\t"$*"</dev/null\t2>&1 -- echo $PATH
(replace `\t` by tabs)
If you need to read dmesg (or other blocking files), try to put busybox on the
device (e.g. by writing to an unused partition) and execute:
/data/busybox timeout -s 2 cat /proc/kmsg
The maximum output size appears to be 0x800001 (`LAF_MAX_DATA_PAYLOAD`). Larger
values result in an error. Output is read per byte, not very efficient for large
output...
### INFO
Arguments:
- arg1: action (`GPRO` - Get Properties, `SPRO` - Set Properties)