summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--buildrun.cxx5
-rw-r--r--cache.cxx33
-rw-r--r--elaborate.cxx25
-rw-r--r--elaborate.h4
-rw-r--r--main.cxx154
-rw-r--r--runtime/staprun/common.c1
-rw-r--r--runtime/staprun/modverify.c6
-rw-r--r--runtime/staprun/staprun.c18
-rw-r--r--runtime/staprun/staprun.h1
-rw-r--r--runtime/staprun/staprun_funcs.c29
-rw-r--r--runtime/transport/transport.c4
-rw-r--r--session.h1
-rwxr-xr-x[-rw-r--r--]stap-authorize-server-cert0
-rwxr-xr-x[-rw-r--r--]stap-authorize-signing-cert0
-rwxr-xr-x[-rw-r--r--]stap-env6
-rw-r--r--systemtap.spec2
-rw-r--r--tapset-been.cxx32
-rw-r--r--tapset-timers.cxx91
-rw-r--r--tapsets.cxx44
-rw-r--r--translate.cxx2
-rw-r--r--translate.h2
-rw-r--r--util.cxx24
-rw-r--r--util.h2
23 files changed, 350 insertions, 136 deletions
diff --git a/buildrun.cxx b/buildrun.cxx
index 54aa5d4f..effc6cd8 100644
--- a/buildrun.cxx
+++ b/buildrun.cxx
@@ -223,11 +223,12 @@ compile_pass (systemtap_session& s)
rc = run_make_cmd(s, make_cmd);
#if HAVE_NSS
- // If a certificate database was specified, then try to sign the module.
+ // If a certificate database was specified, and we're in unprivileged
+ // mode, then try to sign the module.
// Failure to do so is not a fatal error. If the signature is actually needed,
// staprun will complain at that time.
assert (! s.cert_db_path.empty());
- if (!rc)
+ if (s.unprivileged && ! rc)
sign_module (s);
#endif
diff --git a/cache.cxx b/cache.cxx
index bfe2b527..200e51e9 100644
--- a/cache.cxx
+++ b/cache.cxx
@@ -79,16 +79,19 @@ add_to_cache(systemtap_session& s)
string module_signature_src_path = module_src_path;
module_signature_src_path += ".sgn";
- if (s.verbose > 1)
- clog << "Copying " << module_signature_src_path << " to " << module_signature_dest_path << endl;
- if (copy_file(module_signature_src_path.c_str(), module_signature_dest_path.c_str()) != 0)
+ if (file_exists (module_signature_src_path))
{
- cerr << "Copy failed (\"" << module_signature_src_path << "\" to \""
- << module_signature_dest_path << "\"): " << strerror(errno) << endl;
- // NB: this is not so severe as to prevent reuse of the .ko
- // already copied.
- //
- // s.use_cache = false;
+ if (s.verbose > 1)
+ clog << "Copying " << module_signature_src_path << " to " << module_signature_dest_path << endl;
+ if (copy_file(module_signature_src_path.c_str(), module_signature_dest_path.c_str()) != 0)
+ {
+ cerr << "Copy failed (\"" << module_signature_src_path << "\" to \""
+ << module_signature_dest_path << "\"): " << strerror(errno) << endl;
+ // NB: this is not so severe as to prevent reuse of the .ko
+ // already copied.
+ //
+ // s.use_cache = false;
+ }
}
#endif /* HAVE_NSS */
@@ -364,18 +367,6 @@ clean_cache(systemtap_session& s)
}
}
-// Get the size of a file in bytes
-static size_t
-get_file_size(const string &path)
-{
- struct stat file_info;
-
- if (stat(path.c_str(), &file_info) == 0)
- return file_info.st_size;
- else
- return 0;
-}
-
//Assign a weight for a particular file. A lower weight
// will be removed before a higher weight.
//TODO: for now use system mtime... later base a
diff --git a/elaborate.cxx b/elaborate.cxx
index 30e9a775..f0c6c5a9 100644
--- a/elaborate.cxx
+++ b/elaborate.cxx
@@ -261,8 +261,9 @@ match_key::globmatch(match_key const & other) const
// ------------------------------------------------------------------------
match_node::match_node()
- : end(NULL)
-{}
+ : end(NULL), unprivileged_ok (false)
+{
+}
match_node *
match_node::bind(match_key const & k)
@@ -304,6 +305,18 @@ match_node::bind_num(string const & k)
return bind(match_key(k).with_number());
}
+match_node*
+match_node::allow_unprivileged (bool b)
+{
+ unprivileged_ok = b;
+ return this;
+}
+
+bool
+match_node::unprivileged_allowed () const
+{
+ return unprivileged_ok;
+}
void
match_node::find_and_build (systemtap_session& s,
@@ -331,6 +344,14 @@ match_node::find_and_build (systemtap_session& s,
param_map[loc->components[i]->functor] = loc->components[i]->arg;
// maybe 0
+ // Are we compiling for unprivileged users? */
+ if (s.unprivileged)
+ {
+ // Is this probe point ok for unprivileged users?
+ if (! unprivileged_allowed ())
+ throw semantic_error (string("probe point is not allowed for unprivileged users"));
+ }
+
b->build (s, p, loc, param_map, results);
}
else if (isglob(loc->components[pos]->functor)) // wildcard?
diff --git a/elaborate.h b/elaborate.h
index d927177b..36439c4f 100644
--- a/elaborate.h
+++ b/elaborate.h
@@ -236,6 +236,7 @@ match_node
typedef std::map<match_key, match_node*>::iterator sub_map_iterator_t;
sub_map_t sub;
derived_probe_builder* end;
+ bool unprivileged_ok;
public:
match_node();
@@ -250,6 +251,9 @@ match_node
match_node* bind_str(std::string const & k);
match_node* bind_num(std::string const & k);
void bind(derived_probe_builder* e);
+
+ match_node* allow_unprivileged (bool b = true);
+ bool unprivileged_allowed () const;
};
// ------------------------------------------------------------------------
diff --git a/main.cxx b/main.cxx
index 9dc658ff..4530075e 100644
--- a/main.cxx
+++ b/main.cxx
@@ -44,6 +44,7 @@ extern "C" {
using namespace std;
+#define PATH_TBD string("__TBD__")
void
version ()
@@ -131,6 +132,8 @@ usage (systemtap_session& s, int exitcode)
#ifdef HAVE_LIBSQLITE3
<< " -q generate information on tapset coverage" << endl
#endif /* HAVE_LIBSQLITE3 */
+ << " --unprivileged" << endl
+ << " restrict usage to features available to unprivileged users" << endl
#if 0 /* PR6864: disable temporarily; should merge with -d somehow */
<< " --kelf make do with symbol table from vmlinux" << endl
<< " --kmap[=FILE]" << endl
@@ -354,6 +357,90 @@ setup_kernel_release (systemtap_session &s, const char* kstr) {
}
}
+static void
+checkOptions (systemtap_session &s)
+{
+ bool optionsConflict = false;
+
+ if(!s.bulk_mode && !s.merge)
+ {
+ cerr << "-M option is valid only for bulk (relayfs) mode." <<endl;
+ optionsConflict = true;
+ }
+
+ if(!s.output_file.empty() && s.bulk_mode && !s.merge)
+ {
+ cerr << "You can't specify -M, -b and -o options together." <<endl;
+ optionsConflict = true;
+ }
+
+ if((s.cmd != "") && (s.target_pid))
+ {
+ cerr << "You can't specify -c and -x options together." <<endl;
+ optionsConflict = true;
+ }
+
+ if (s.unprivileged)
+ {
+ if (s.guru_mode)
+ {
+ cerr << "You can't specify -g and --unprivileged together." << endl;
+ optionsConflict = true;
+ }
+ if (s.include_path.size () > 1)
+ {
+ cerr << "You can't specify -I and --unprivileged together." << endl;
+ optionsConflict = true;
+ }
+ if (s.runtime_path != string(PKGDATADIR) + "/runtime")
+ {
+ cerr << "You can't use -R to specify an alternate runtime path when --unprivileged is specified." << endl;
+ optionsConflict = true;
+ }
+ if (s.kernel_build_tree.substr(0, 13) != "/lib/modules/")
+ {
+ cerr << "You can't use -r to specify a kernel release which is not installed when --unprivileged is specified." << endl;
+ optionsConflict = true;
+ }
+ if (! s.macros.empty ())
+ {
+ cerr << "You can't specify -D and --unprivileged together." << endl;
+ optionsConflict = true;
+ }
+
+ if (getenv ("SYSTEMTAP_TAPSET"))
+ {
+ cerr << "The environment variable SYSTEMTAP_TAPSET can not be defined when --unprivileged is specified." << endl;
+ optionsConflict = true;
+ }
+ if (getenv ("SYSTEMTAP_RUNTIME"))
+ {
+ cerr << "The environment variable SYSTEMTAP_RUNTIME can not be defined when --unprivileged is specified." << endl;
+ optionsConflict = true;
+ }
+ if (getenv ("SYSTEMTAP_DEBUGINFO_PATH"))
+ {
+ cerr << "The environment variable SYSTEMTAP_DEBUGINFO_PATH can not be defined when --unprivileged is specified." << endl;
+ optionsConflict = true;
+ }
+ }
+
+ if (!s.kernel_symtab_path.empty())
+ {
+ if (s.consult_symtab)
+ {
+ cerr << "You can't specify --kelf and --kmap together." << endl;
+ optionsConflict = true;
+ }
+ s.consult_symtab = true;
+ if (s.kernel_symtab_path == PATH_TBD)
+ s.kernel_symtab_path = string("/boot/System.map-") + s.kernel_release;
+ }
+
+ if (optionsConflict)
+ usage (s, 1);
+}
+
int
main (int argc, char * const argv [])
{
@@ -403,11 +490,12 @@ main (int argc, char * const argv [])
s.ignore_dwarf = false;
s.load_only = false;
s.skip_badvars = false;
+ s.unprivileged = false;
// Location of our signing certificate.
// If we're root, use the database in SYSCONFDIR, otherwise
// use the one in our $HOME directory. */
- if (geteuid() == 0)
+ if (getuid() == 0)
s.cert_db_path = SYSCONFDIR "/systemtap/ssl/server";
else
s.cert_db_path = getenv("HOME") + string ("/.systemtap/ssl/server");
@@ -457,6 +545,14 @@ main (int argc, char * const argv [])
}
}
+ // Location of our signing certificate.
+ // If we're root, use the database in SYSCONFDIR, otherwise
+ // use the one in s.data_path. */
+ if (geteuid() == 0)
+ s.cert_db_path = SYSCONFDIR "/systemtap/ssl/server";
+ else
+ s.cert_db_path = s.data_path + "/ssl/server";
+
const char* s_tc = getenv ("SYSTEMTAP_COVERAGE");
if (s_tc != NULL)
s.tapset_compile_coverage = true;
@@ -477,6 +573,7 @@ main (int argc, char * const argv [])
#define LONG_OPT_IGNORE_DWARF 4
#define LONG_OPT_VERBOSE_PASS 5
#define LONG_OPT_SKIP_BADVARS 6
+#define LONG_OPT_UNPRIVILEGED 7
// NB: also see find_hash(), usage(), switch stmt below, stap.1 man page
static struct option long_options[] = {
{ "kelf", 0, &long_opt, LONG_OPT_KELF },
@@ -485,6 +582,7 @@ main (int argc, char * const argv [])
{ "ignore-dwarf", 0, &long_opt, LONG_OPT_IGNORE_DWARF },
{ "skip-badvars", 0, &long_opt, LONG_OPT_SKIP_BADVARS },
{ "vp", 1, &long_opt, LONG_OPT_VERBOSE_PASS },
+ { "unprivileged", 0, &long_opt, LONG_OPT_UNPRIVILEGED },
{ NULL, 0, NULL, 0 }
};
int grc = getopt_long (argc, argv, "hVMvtp:I:e:o:R:r:m:kgPc:x:D:bs:uqwl:d:L:FS:",
@@ -701,7 +799,6 @@ main (int argc, char * const argv [])
if (optarg)
s.kernel_symtab_path = optarg;
else
-#define PATH_TBD string("__TBD__")
s.kernel_symtab_path = PATH_TBD;
break;
case LONG_OPT_IGNORE_VMLINUX:
@@ -733,6 +830,9 @@ main (int argc, char * const argv [])
case LONG_OPT_SKIP_BADVARS:
s.skip_badvars = true;
break;
+ case LONG_OPT_UNPRIVILEGED:
+ s.unprivileged = true;
+ break;
default:
cerr << "Internal error parsing command arguments." << endl;
usage(s, 1);
@@ -745,35 +845,8 @@ main (int argc, char * const argv [])
}
}
- if(!s.bulk_mode && !s.merge)
- {
- cerr << "-M option is valid only for bulk (relayfs) mode." <<endl;
- usage (s, 1);
- }
-
- if(!s.output_file.empty() && s.bulk_mode && !s.merge)
- {
- cerr << "You can't specify -M, -b and -o options together." <<endl;
- usage (s, 1);
- }
-
- if((s.cmd != "") && (s.target_pid))
- {
- cerr << "You can't specify -c and -x options together." <<endl;
- usage (s, 1);
- }
-
- if (!s.kernel_symtab_path.empty())
- {
- if (s.consult_symtab)
- {
- cerr << "You can't specify --kelf and --kmap together." << endl;
- usage (s, 1);
- }
- s.consult_symtab = true;
- if (s.kernel_symtab_path == PATH_TBD)
- s.kernel_symtab_path = string("/boot/System.map-") + s.kernel_release;
- }
+ // Check for options conflicts.
+ checkOptions (s);
// Warn in case the target kernel release doesn't match the running one.
if (s.last_pass > 4 &&
@@ -1157,14 +1230,17 @@ main (int argc, char * const argv [])
// Save the signature as well.
assert (! s.cert_db_path.empty());
module_src_path += ".sgn";
- module_dest_path += ".sgn";
-
- if (s.verbose > 1)
- clog << "Copying " << module_src_path << " to "
- << module_dest_path << endl;
- if (copy_file(module_src_path.c_str(), module_dest_path.c_str()) != 0)
- cerr << "Copy failed (\"" << module_src_path << "\" to \""
- << module_dest_path << "\"): " << strerror(errno) << endl;
+ if (file_exists (module_src_path))
+ {
+ module_dest_path += ".sgn";
+
+ if (s.verbose > 1)
+ clog << "Copying " << module_src_path << " to "
+ << module_dest_path << endl;
+ if (copy_file(module_src_path.c_str(), module_dest_path.c_str()) != 0)
+ cerr << "Copy failed (\"" << module_src_path << "\" to \""
+ << module_dest_path << "\"): " << strerror(errno) << endl;
+ }
#endif
}
}
diff --git a/runtime/staprun/common.c b/runtime/staprun/common.c
index 5c4a8431..010cab12 100644
--- a/runtime/staprun/common.c
+++ b/runtime/staprun/common.c
@@ -30,6 +30,7 @@ int need_uprobes;
int daemon_mode;
off_t fsize_max;
int fnum_max;
+int unprivileged_user = 0;
/* module variables */
char *modname = NULL;
diff --git a/runtime/staprun/modverify.c b/runtime/staprun/modverify.c
index b50a69f4..f4b15ac3 100644
--- a/runtime/staprun/modverify.c
+++ b/runtime/staprun/modverify.c
@@ -203,11 +203,7 @@ verify_it (const char *inputName, const char *signatureName, SECKEYPublicKey *pu
/* Get the size of the signature file. */
prStatus = PR_GetFileInfo (signatureName, &info);
if (prStatus != PR_SUCCESS || info.type != PR_FILE_FILE || info.size < 0)
- {
- fprintf (stderr, "Unable to obtain information on the signature file %s.\n", signatureName);
- nssError ();
- return MODULE_UNTRUSTED; /* Not signed */
- }
+ return MODULE_UNTRUSTED; /* Not signed */
/* Open the signature file. */
local_file_fd = PR_Open (signatureName, PR_RDONLY, 0);
diff --git a/runtime/staprun/staprun.c b/runtime/staprun/staprun.c
index 42b72ff1..917990dc 100644
--- a/runtime/staprun/staprun.c
+++ b/runtime/staprun/staprun.c
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
- * Copyright (C) 2005-2008 Red Hat, Inc.
+ * Copyright (C) 2005-2009 Red Hat, Inc.
*
*/
@@ -139,11 +139,21 @@ static int enable_uprobes(void)
static int insert_stap_module(void)
{
- char bufsize_option[128];
+ char special_options[128];
+ char *bufptr = special_options;
- if (snprintf_chk(bufsize_option, 128, "_stp_bufsize=%d", buffer_size))
+ /* Add the _stp_bufsize option. */
+ if (snprintf_chk(bufptr, sizeof (special_options), "_stp_bufsize=%d", buffer_size))
return -1;
- return insert_module(modpath, bufsize_option, modoptions);
+
+ /* Add the _stp_unprivileged_user option. */
+ bufptr += strlen (bufptr);
+ if (snprintf_chk(bufptr,
+ sizeof (special_options) - (bufptr - special_options),
+ " _stp_unprivileged_user=%d", unprivileged_user))
+ return -1;
+
+ return insert_module(modpath, special_options, modoptions);
}
static int remove_module(const char *name, int verb);
diff --git a/runtime/staprun/staprun.h b/runtime/staprun/staprun.h
index 3c9dab3f..6af04042 100644
--- a/runtime/staprun/staprun.h
+++ b/runtime/staprun/staprun.h
@@ -168,6 +168,7 @@ extern int need_uprobes;
extern int daemon_mode;
extern off_t fsize_max;
extern int fnum_max;
+extern int unprivileged_user;
/* getopt variables */
extern char *optarg;
diff --git a/runtime/staprun/staprun_funcs.c b/runtime/staprun/staprun_funcs.c
index 781bb999..669dc996 100644
--- a/runtime/staprun/staprun_funcs.c
+++ b/runtime/staprun/staprun_funcs.c
@@ -403,7 +403,6 @@ check_groups (void)
perr("Unable to retrieve group list");
return -1;
}
-
for (i = 0; i < ngids; i++) {
/* If the user is a member of 'stapdev', then we're
* done, since he can use staprun without any
@@ -419,9 +418,10 @@ check_groups (void)
if (gidlist[i] == stapusr_gid)
gid = stapusr_gid;
}
- /* Not a member of stapusr? */
- if (gid != stapusr_gid)
- return 0;
+ if (gid != stapusr_gid) {
+ unprivileged_user = 1;
+ return 0;
+ }
}
/* At this point the user is only a member of the 'stapusr'
@@ -440,8 +440,9 @@ check_groups (void)
* 1) root can do anything
* 2) members of stapdev can do anything
* 3) members of stapusr can load modules from /lib/modules/KVER/systemtap
+ * 4) anyone can load a module which has been signed by a trusted signer
*
- * It is only an error if all 3 levels of checking fail
+ * It is only an error if all 4 levels of checking fail
*
* Returns: -1 on errors, 0 on failure, 1 on success.
*/
@@ -480,6 +481,17 @@ int check_permissions(void)
if (check_groups_rc == 1)
return 1;
+ /* The user is an ordinary user. If the module has been signed with
+ * a "blessed" certificate and private key, then we will load it for
+ * anyone. */
+#if HAVE_NSS
+ if (check_signature_rc == MODULE_OK)
+ return 1;
+ assert (check_signature_rc == MODULE_UNTRUSTED || check_signature_rc == MODULE_CHECK_ERROR);
+#endif
+
+ /* We are an ordinary user and the module was not signed by a trusted
+ signer. */
err("ERROR: You are trying to run stap as a normal user.\n"
"You should either be root, or be part of either "
"group \"stapdev\" or group \"stapusr\".\n");
@@ -487,6 +499,11 @@ int check_permissions(void)
err("Your system doesn't seem to have either group.\n");
check_groups_rc = -1;
}
+#if HAVE_NSS
+ err("Alternatively, your module must be compiled using the --unprivileged option and signed by a trusted signer.\n"
+ "For more information, please consult the \"SAFETY AND SECURITY\" section of the \"stap(1)\" manpage\n");
+#endif
- return check_groups_rc;
+ /* Combine the return codes. They are either 0 or -1. */
+ return check_groups_rc | check_signature_rc;
}
diff --git a/runtime/transport/transport.c b/runtime/transport/transport.c
index 1d029e53..ec73f05f 100644
--- a/runtime/transport/transport.c
+++ b/runtime/transport/transport.c
@@ -59,6 +59,10 @@ static int _stp_bufsize;
module_param(_stp_bufsize, int, 0);
MODULE_PARM_DESC(_stp_bufsize, "buffer size");
+static int _stp_unprivileged_user;
+module_param(_stp_unprivileged_user, int, 1);
+MODULE_PARM_DESC(_stp_unprivileged_user, "user is unprivileged");
+
/* forward declarations */
static void probe_exit(void);
static int probe_start(void);
diff --git a/session.h b/session.h
index a617e47f..84cc6b01 100644
--- a/session.h
+++ b/session.h
@@ -114,6 +114,7 @@ struct systemtap_session
bool tapset_compile_coverage;
bool need_uprobes;
bool load_only; // flight recorder mode
+ bool unprivileged;
// NB: It is very important for all of the above (and below) fields
// to be cleared in the systemtap_session ctor (elaborate.cxx)
diff --git a/stap-authorize-server-cert b/stap-authorize-server-cert
index 13fb9c9f..13fb9c9f 100644..100755
--- a/stap-authorize-server-cert
+++ b/stap-authorize-server-cert
diff --git a/stap-authorize-signing-cert b/stap-authorize-signing-cert
index 22da27c4..22da27c4 100644..100755
--- a/stap-authorize-signing-cert
+++ b/stap-authorize-signing-cert
diff --git a/stap-env b/stap-env
index 8d765ae6..ceeca465 100644..100755
--- a/stap-env
+++ b/stap-env
@@ -25,7 +25,11 @@ stap_avahi_service_tag=_stap._tcp
# NSS certificate databases
stap_root_ssl_db=$stap_sysconfdir/systemtap/ssl
-stap_user_ssl_db=$HOME/.systemtap/ssl
+if test "X$SYSTEMTAP_DIR" = "X"; then
+ stap_user_ssl_db=$HOME/.systemtap/ssl
+else
+ stap_user_ssl_db=$SYSTEMTAP_DIR/ssl
+fi
if test $EUID = 0; then
stap_ssl_db=$stap_root_ssl_db
diff --git a/systemtap.spec b/systemtap.spec
index d62bb7ad..d679d969 100644
--- a/systemtap.spec
+++ b/systemtap.spec
@@ -320,6 +320,8 @@ exit 0
%{_bindir}/stap-client
%{_bindir}/stap-env
%{_bindir}/stap-find-servers
+%{_bindir}/stap-authorize-cert
+%{_bindir}/stap-authorize-server-cert
%{_bindir}/stap-client-connect
%{_mandir}/man8/stap-server.8*
diff --git a/tapset-been.cxx b/tapset-been.cxx
index d695bdf3..99b59574 100644
--- a/tapset-been.cxx
+++ b/tapset-been.cxx
@@ -215,14 +215,30 @@ register_tapset_been(systemtap_session& s)
{
match_node* root = s.pattern_root;
- root->bind(TOK_BEGIN)->bind(new be_builder(BEGIN));
- root->bind_num(TOK_BEGIN)->bind(new be_builder(BEGIN));
- root->bind(TOK_END)->bind(new be_builder(END));
- root->bind_num(TOK_END)->bind(new be_builder(END));
- root->bind(TOK_ERROR)->bind(new be_builder(ERROR));
- root->bind_num(TOK_ERROR)->bind(new be_builder(ERROR));
-
- root->bind(TOK_NEVER)->bind(new never_builder());
+ root->bind(TOK_BEGIN)
+ ->allow_unprivileged()
+ ->bind(new be_builder(BEGIN));
+ root->bind_num(TOK_BEGIN)
+ ->allow_unprivileged()
+ ->bind(new be_builder(BEGIN));
+
+ root->bind(TOK_END)
+ ->allow_unprivileged()
+ ->bind(new be_builder(END));
+ root->bind_num(TOK_END)
+ ->allow_unprivileged()
+ ->bind(new be_builder(END));
+
+ root->bind(TOK_ERROR)
+ ->allow_unprivileged()
+ ->bind(new be_builder(ERROR));
+ root->bind_num(TOK_ERROR)
+ ->allow_unprivileged()
+ ->bind(new be_builder(ERROR));
+
+ root->bind(TOK_NEVER)
+ ->allow_unprivileged()
+ ->bind(new never_builder());
}
/* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
diff --git a/tapset-timers.cxx b/tapset-timers.cxx
index 1dc0acac..565a54e8 100644
--- a/tapset-timers.cxx
+++ b/tapset-timers.cxx
@@ -593,32 +593,71 @@ register_tapset_timers(systemtap_session& s)
root = root->bind(TOK_TIMER);
- root->bind_num("s")->bind(builder);
- root->bind_num("s")->bind_num("randomize")->bind(builder);
- root->bind_num("sec")->bind(builder);
- root->bind_num("sec")->bind_num("randomize")->bind(builder);
-
- root->bind_num("ms")->bind(builder);
- root->bind_num("ms")->bind_num("randomize")->bind(builder);
- root->bind_num("msec")->bind(builder);
- root->bind_num("msec")->bind_num("randomize")->bind(builder);
-
- root->bind_num("us")->bind(builder);
- root->bind_num("us")->bind_num("randomize")->bind(builder);
- root->bind_num("usec")->bind(builder);
- root->bind_num("usec")->bind_num("randomize")->bind(builder);
-
- root->bind_num("ns")->bind(builder);
- root->bind_num("ns")->bind_num("randomize")->bind(builder);
- root->bind_num("nsec")->bind(builder);
- root->bind_num("nsec")->bind_num("randomize")->bind(builder);
-
- root->bind_num("jiffies")->bind(builder);
- root->bind_num("jiffies")->bind_num("randomize")->bind(builder);
-
- root->bind_num("hz")->bind(builder);
-
- root->bind("profile")->bind(builder);
+ root->bind_num("s")
+ ->allow_unprivileged()
+ ->bind(builder);
+ root->bind_num("s")->bind_num("randomize")
+ ->allow_unprivileged()
+ ->bind(builder);
+ root->bind_num("sec")
+ ->allow_unprivileged()
+ ->bind(builder);
+ root->bind_num("sec")->bind_num("randomize")
+ ->allow_unprivileged()
+ ->bind(builder);
+
+ root->bind_num("ms")
+ ->allow_unprivileged()
+ ->bind(builder);
+ root->bind_num("ms")->bind_num("randomize")
+ ->allow_unprivileged()
+ ->bind(builder);
+ root->bind_num("msec")
+ ->allow_unprivileged()
+ ->bind(builder);
+ root->bind_num("msec")->bind_num("randomize")
+ ->allow_unprivileged()
+ ->bind(builder);
+
+ root->bind_num("us")
+ ->allow_unprivileged()
+ ->bind(builder);
+ root->bind_num("us")->bind_num("randomize")
+ ->allow_unprivileged()
+ ->bind(builder);
+ root->bind_num("usec")
+ ->allow_unprivileged()
+ ->bind(builder);
+ root->bind_num("usec")->bind_num("randomize")
+ ->allow_unprivileged()
+ ->bind(builder);
+
+ root->bind_num("ns")
+ ->allow_unprivileged()
+ ->bind(builder);
+ root->bind_num("ns")->bind_num("randomize")
+ ->allow_unprivileged()
+ ->bind(builder);
+ root->bind_num("nsec")
+ ->allow_unprivileged()
+ ->bind(builder);
+ root->bind_num("nsec")->bind_num("randomize")
+ ->allow_unprivileged()
+ ->bind(builder);
+
+ root->bind_num("jiffies")
+ ->allow_unprivileged()
+ ->bind(builder);
+ root->bind_num("jiffies")->bind_num("randomize")
+ ->allow_unprivileged()
+ ->bind(builder);
+
+ root->bind_num("hz")
+ ->allow_unprivileged()
+ ->bind(builder);
+
+ root->bind("profile")
+ ->bind(builder);
}
diff --git a/tapsets.cxx b/tapsets.cxx
index 7aee6930..694905d9 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -367,11 +367,14 @@ struct dwarf_derived_probe: public derived_probe
// Pattern registration helpers.
static void register_statement_variants(match_node * root,
- dwarf_builder * dw);
+ dwarf_builder * dw,
+ bool unprivileged_ok_p = false);
static void register_function_variants(match_node * root,
- dwarf_builder * dw);
+ dwarf_builder * dw,
+ bool unprivileged_ok_p = false);
static void register_function_and_statement_variants(match_node * root,
- dwarf_builder * dw);
+ dwarf_builder * dw,
+ bool unprivileged_ok_p = false);
static void register_patterns(systemtap_session& s);
};
@@ -2928,25 +2931,28 @@ dwarf_derived_probe::dwarf_derived_probe(const string& funcname,
void
dwarf_derived_probe::register_statement_variants(match_node * root,
- dwarf_builder * dw)
+ dwarf_builder * dw,
+ bool unprivileged_ok_p)
{
- root->bind(dw);
+ root->allow_unprivileged(unprivileged_ok_p)->bind(dw);
}
void
dwarf_derived_probe::register_function_variants(match_node * root,
- dwarf_builder * dw)
-{
- root->bind(dw);
- root->bind(TOK_INLINE)->bind(dw);
- root->bind(TOK_CALL)->bind(dw);
- root->bind(TOK_RETURN)->bind(dw);
- root->bind(TOK_RETURN)->bind_num(TOK_MAXACTIVE)->bind(dw);
+ dwarf_builder * dw,
+ bool unprivileged_ok_p)
+{
+ root->allow_unprivileged(unprivileged_ok_p)->bind(dw);
+ root->bind(TOK_INLINE)->allow_unprivileged(unprivileged_ok_p)->bind(dw);
+ root->bind(TOK_CALL)->allow_unprivileged(unprivileged_ok_p)->bind(dw);
+ root->bind(TOK_RETURN)->allow_unprivileged(unprivileged_ok_p)->bind(dw);
+ root->bind(TOK_RETURN)->bind_num(TOK_MAXACTIVE)->allow_unprivileged(unprivileged_ok_p)->bind(dw);
}
void
dwarf_derived_probe::register_function_and_statement_variants(match_node * root,
- dwarf_builder * dw)
+ dwarf_builder * dw,
+ bool unprivileged_ok_p)
{
// Here we match 4 forms:
//
@@ -2955,10 +2961,10 @@ dwarf_derived_probe::register_function_and_statement_variants(match_node * root,
// .statement("foo")
// .statement(0xdeadbeef)
- register_function_variants(root->bind_str(TOK_FUNCTION), dw);
- register_function_variants(root->bind_num(TOK_FUNCTION), dw);
- register_statement_variants(root->bind_str(TOK_STATEMENT), dw);
- register_statement_variants(root->bind_num(TOK_STATEMENT), dw);
+ register_function_variants(root->bind_str(TOK_FUNCTION), dw, unprivileged_ok_p);
+ register_function_variants(root->bind_num(TOK_FUNCTION), dw, unprivileged_ok_p);
+ register_statement_variants(root->bind_str(TOK_STATEMENT), dw, unprivileged_ok_p);
+ register_statement_variants(root->bind_num(TOK_STATEMENT), dw, unprivileged_ok_p);
}
void
@@ -2975,8 +2981,7 @@ dwarf_derived_probe::register_patterns(systemtap_session& s)
root->bind(TOK_KERNEL)->bind_num(TOK_STATEMENT)->bind(TOK_ABSOLUTE)->bind(dw);
root->bind(TOK_KERNEL)->bind_str(TOK_FUNCTION)->bind_str(TOK_LABEL)->bind(dw);
root->bind_str(TOK_PROCESS)->bind_str(TOK_FUNCTION)->bind_str(TOK_LABEL)->bind(dw);
-
- register_function_and_statement_variants(root->bind_str(TOK_PROCESS), dw);
+ register_function_and_statement_variants(root->bind_str(TOK_PROCESS), dw, false/*!unprivileged_ok_p*/);
root->bind_str(TOK_PROCESS)->bind_str(TOK_MARK)->bind(dw);
root->bind_str(TOK_PROCESS)->bind_num(TOK_MARK)->bind(dw);
}
@@ -5741,7 +5746,6 @@ register_standard_tapsets(systemtap_session & s)
register_tapset_timers(s);
register_tapset_utrace(s);
-
// dwarf-based kprobe/uprobe parts
dwarf_derived_probe::register_patterns(s);
diff --git a/translate.cxx b/translate.cxx
index cc634555..5336dc66 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -1087,7 +1087,6 @@ c_unparser::emit_functionsig (functiondecl* v)
}
-
void
c_unparser::emit_module_init ()
{
@@ -1131,6 +1130,7 @@ c_unparser::emit_module_init ()
o->newline() << "if (_stp_module_check()) rc = -EINVAL;";
o->newline(-1) << "}";
+
o->newline() << "if (rc) goto out;";
// initialize gettimeofday (if needed)
diff --git a/translate.h b/translate.h
index fdff9521..d1bff678 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
diff --git a/util.cxx b/util.cxx
index 5c05a1dd..a258bf72 100644
--- a/util.cxx
+++ b/util.cxx
@@ -51,6 +51,30 @@ get_home_directory(void)
}
+// Get the size of a file in bytes
+size_t
+get_file_size(const string &path)
+{
+ struct stat file_info;
+
+ if (stat(path.c_str(), &file_info) == 0)
+ return file_info.st_size;
+ else
+ return 0;
+}
+
+// Get the size of a file in bytes
+bool
+file_exists (const string &path)
+{
+ struct stat file_info;
+
+ if (stat(path.c_str(), &file_info) == 0)
+ return true;
+
+ return false;
+}
+
// Copy a file. The copy is done via a temporary file and atomic
// rename.
int
diff --git a/util.h b/util.h
index 63e41f9a..4921cef7 100644
--- a/util.h
+++ b/util.h
@@ -6,6 +6,8 @@
#include <cctype>
const char *get_home_directory(void);
+size_t get_file_size(const std::string &path);
+bool file_exists (const std::string &path);
int copy_file(const char *src, const char *dest);
int create_dir(const char *dir);
int remove_file_or_dir(const char *dir);