diff options
author | Dave Brolley <brolley@redhat.com> | 2009-04-06 11:39:35 -0400 |
---|---|---|
committer | Dave Brolley <brolley@redhat.com> | 2009-04-06 11:39:35 -0400 |
commit | faf38cd9bd782cf460b2b46f29a6922205b0eab1 (patch) | |
tree | de1038c7453064a3baa678207e09a58104b708e5 | |
parent | 8d3854b9f124aa818552d462bd8cbd2577be298e (diff) | |
download | systemtap-steved-faf38cd9bd782cf460b2b46f29a6922205b0eab1.tar.gz systemtap-steved-faf38cd9bd782cf460b2b46f29a6922205b0eab1.tar.xz systemtap-steved-faf38cd9bd782cf460b2b46f29a6922205b0eab1.zip |
2009-04-06 Dave Brolley <brolley@redhat.com>
* translate.cxx (emint_unprivileged_user_check): New method of c_unparser.
(c_unparser::emit_module_init): If --unprivileged has been specified,
generate code to call systemtap_unprivileged_user_check.
(translate_pass): Call emit_unprivileged_user_check.
* translate.h (emint_unprivileged_user_check): New method of c_unparser.
-rw-r--r-- | translate.cxx | 40 | ||||
-rw-r--r-- | translate.h | 5 |
2 files changed, 44 insertions, 1 deletions
diff --git a/translate.cxx b/translate.cxx index cab37487..63e84a1f 100644 --- a/translate.cxx +++ b/translate.cxx @@ -66,6 +66,7 @@ struct c_unparser: public unparser, public visitor void emit_global_init (vardecl* v); void emit_global_param (vardecl* v); void emit_functionsig (functiondecl* v); + void emit_unprivileged_user_check (); void emit_module_init (); void emit_module_exit (); void emit_function (functiondecl* v); @@ -1086,6 +1087,36 @@ c_unparser::emit_functionsig (functiondecl* v) } +void +c_unparser::emit_unprivileged_user_check () +{ + // If the --unprivileged option was specified then the module + // will be safe for unprivileged users, if it is successfully generated, + // so no check need be emitted. + if (session->unprivileged) + return; + + // Otherwise, generate code to check the user or group. If the user is not + // root or a member of stapdev or stapusr, then generate an error and + // unload the module. + o->newline(); + o->newline() << "static int systemtap_unprivileged_user_check (void) {"; + o->newline(1) << "struct group *stgr;"; + o->newline() << "if (_stp_uid == 0)"; + o->newline(1) << "return 0;"; +#error can we call getgrpnam???? + o->newline(-1) << "stgr = getgrnam(\"stapdev\");"; + o->newline() << "if (stgr != NULL && _stp_gid == stgr->gr_gid)"; + o->newline(1) << "return 0;"; + o->newline(-1) << "stgr = getgrnam(\"stapusr\");"; + o->newline() << "if (stgr != NULL && _stp_gid == stgr->gr_gid)"; + o->newline(1) << "return 0;"; + o->newline(-1) << "_stp_error (\"You are attempting to run stap as an ordinary user.\");"; + o->newline() << "_stp_error (\"Your module must be compiled using the --unprivileged option.\");"; + o->newline() << "return 1;"; + o->newline(-1) << "}\n"; +} + void c_unparser::emit_module_init () @@ -1130,6 +1161,12 @@ c_unparser::emit_module_init () o->newline() << "if (_stp_module_check()) rc = -EINVAL;"; o->newline(-1) << "}"; + + if (! session->unprivileged) { + // Check whether the user is unprivileged. + o->newline() << "if (systemtap_unprivileged_user_check ()) rc = -EINVAL;"; + } + o->newline() << "if (rc) goto out;"; o->newline() << "(void) probe_point;"; @@ -5047,6 +5084,9 @@ translate_pass (systemtap_session& s) s.op->assert_0_indent(); s.op->newline(); + s.up->emit_unprivileged_user_check (); + s.op->assert_0_indent(); + s.op->newline(); s.up->emit_module_init (); s.op->assert_0_indent(); s.op->newline(); diff --git a/translate.h b/translate.h index fdff9521..2c59a495 100644 --- a/translate.h +++ b/translate.h @@ -1,5 +1,5 @@ // -*- C++ -*- -// Copyright (C) 2005 Red Hat Inc. +// Copyright (C) 2005, 2009 Red Hat Inc. // // This file is part of systemtap, and is free software. You can // redistribute it and/or modify it under the terms of the GNU General @@ -79,6 +79,9 @@ struct unparser virtual void emit_functionsig (functiondecl* v) = 0; // static void function_NAME (context* c); + virtual void emit_unprivileged_user_check () = 0; + // static void systemtap_check_unprivileged_user + virtual void emit_module_init () = 0; virtual void emit_module_exit () = 0; // XXX |