Bug 11105 - check/fix vulnerability of stap-server to spacious incoming arguments
Summary: check/fix vulnerability of stap-server to spacious incoming arguments
Status: RESOLVED FIXED
Alias: None
Product: systemtap
Classification: Unclassified
Component: runtime (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Dave Brolley
URL:
Keywords:
Depends on:
Blocks: blockers-1.1
  Show dependency treegraph
 
Reported: 2009-12-18 17:29 UTC by Frank Ch. Eigler
Modified: 2014-05-28 19:40 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Frank Ch. Eigler 2009-12-18 17:29:00 UTC
stap-server is a shell script that manipulates stap command line
arguments in a pretty simple way.  Trouble would occur if these
incoming arguments (from a potentially hostile stap-client/user)
contain space or other control goo characters that can work their
way past stap-server's filtering to the later stap command line.
Comment 1 Frank Ch. Eigler 2009-12-22 03:33:51 UTC
Lots of badness hides in the string processing.  Horror cases include


stap-client \; ...
stap-client -; ...
stap-client -D 'asdf ; ls /etc' ...
stap-client -e 'script' -D 'asdf ; \; '

So far I haven't found additional small amounts of quoting, and/or
changed eval and such constructs, to make the above not work but keep
ordinary scripts (-e '{..}"..."') work.
Comment 2 Dave Brolley 2009-12-23 15:32:37 UTC
It seems clear that a first and necessary step to solving this is to rework the
way the command line information is presented to the server so that it no longer
needs to parse and interpret the command line at all. This is true regardless of
the future of the client and server as standalone scripts/programs or integrated
with stap.

Perhaps something like having each relevant option and its value occupy its own
line in a structured file passed to the server from the client. Perhaps
something in an option:value format. Some examples:

scriptFile:script file name possibly containing spaces.stp
v:2
p:3
unprivileged:

or

e:probe begin { printf ("Hello\n"); exit (); }
unprivileged:

This should be easy for the server to internalize for analysis and it should be
easy for the server to construct and execute the stap command line.


Comment 3 Frank Ch. Eigler 2009-12-23 16:06:33 UTC
> scriptFile:script file name possibly containing spaces.stp
> v:2
> p:3
> unprivileged:
> e:probe begin { printf ("Hello\n"); exit (); }
> unprivileged:


Right, this is a good way to start thinking about it, but you need to think
even more paranoidly: consider the script containing these lines.

/*
e: nothing 
m: something
*/

roland suggested \0 separated transcriptions of stap-client argv[], which
would be reliable by nature, but /bin/sh is not good at processing such strings.
Comment 4 Dave Brolley 2009-12-23 17:07:13 UTC
(In reply to comment #3)

> Right, this is a good way to start thinking about it, but you need to think
> even more paranoidly: consider the script containing these lines.
> 
> /*
> e: nothing 
> m: something
> */

Of course. It was an example, not a spec  :-)
There would still be the required filtering. It would just be a lot easier to
perform.
Comment 5 Frank Ch. Eigler 2009-12-29 20:54:02 UTC
Here's another approach.  Rewrite stap-client and stap-server as small c++
programs that package the args, almost entirely unparsed, into the .zip file.
(It could be done in perl, but it would add a new rpm dependency, which is
undesirable.)

The new stap-server would invoke stap with a new flag, after which it would
transcribe (carefully) all incoming args from the client:

--client-args -e SCRIPT -v  ... blah

Preceding these would be any extra stap flags that were given to
stap-start-server (-a ARCH etc.), which we can consider trusted.

Then stap itself would look for --client-args, and proceed to parse both
server-side and client-side args together, in good old main.cxx.
The logic for rejecting client-side supplied --unprivileged -D / etc.
would all be here, instead of stap-server/etc.


Dave, until we choose an approach, I'd like you to concentrate on writing 
a good testsuite for this.  It should be in the form of a dejagnu .exp
script that creates junk scripts ("fuzzing") and submits them to
stap & stap-client, to assert equal outputs.  It should arrange to include
special characters like ' ', '\'', '"', '\n', '*', ';', etc. in all the
relevant command line options (-e, -I, ...).
Comment 6 Frank Ch. Eigler 2010-01-15 08:46:08 UTC
please help test commit series ending 86f99ad, which contains the reworked
server-side parsing/invocation widgetry
Comment 7 Frank Ch. Eigler 2010-01-15 19:15:50 UTC
Some client-side quoting issues remain, but they do not pose a server-side
security problem.
Comment 8 Dave Brolley 2010-02-03 20:22:31 UTC
(In reply to comment #1)
Here is an example which demonstrates the exploit. Running

    stap-client -p1 -B\;ai2

will print the usage help followed by a message similar to

  /usr/local/bin/stap-server: line 340: ai2: command not found

 which indicates that server tried to run the 'ai2' command.
Comment 9 Frank Ch. Eigler 2010-02-05 17:59:32 UTC
There are additional problem cases that our first patch did not resolve.
Comment 10 Frank Ch. Eigler 2010-02-12 19:00:21 UTC
The following two patches appear to solve the remaining issues.

http://sourceware.org/git/?p=systemtap.git;a=commit;h=c0d1b5a00
http://sourceware.org/git/?p=systemtap.git;a=commit;h=cc9e5488d
Comment 11 Jackie Rosen 2014-02-16 19:43:38 UTC Comment hidden (spam)