- Server now returns uprobes.ko to client when required.
- New optional argument to staprun's -u option to specify the location
of uprobes module.
- Client uses new argument of -u to specify uprobes.ko returned by
the server.
- staprun still prefers already-loaded uprobes, built-in uprobes and
kernel-built uprobes over the one returned by the server.
- staprun verifies the signature of the uprobes module for unprivileged
users.
staprun_cmd += "-b " + lex_cast(s.buffer_size) + " ";
if (s.need_uprobes)
- staprun_cmd += "-u ";
+ staprun_cmd += "-u" + s.uprobes_path + " ";
if (s.load_only)
staprun_cmd += (s.output_file.empty() ? "-L " : "-D ");
s.module_name = components.back ();
s.module_name.erase(s.module_name.size() - 3);
}
+
+ // If a uprobes.ko module was returned, then make note of it.
+ if (file_exists (s.tmpdir + "/server/uprobes.ko"))
+ {
+ s.need_uprobes = true;
+ s.uprobes_path = s.tmpdir + "/server/uprobes.ko";
+ }
}
}
else if (s.have_script)
* Public License (GPL); either version 2, or (at your option) any
* later version.
*
- * Copyright (C) 2007 Red Hat Inc.
+ * Copyright (C) 2007, 2010 Red Hat Inc.
*/
#include "staprun.h"
int delete_mod;
int load_only;
int need_uprobes;
+const char *uprobes_path = NULL;
int daemon_mode;
off_t fsize_max;
int fnum_max;
fsize_max = 0;
fnum_max = 0;
- while ((c = getopt(argc, argv, "ALuvb:t:dc:o:x:S:D")) != EOF) {
+ while ((c = getopt(argc, argv, "ALu::vb:t:dc:o:x:S:D")) != EOF) {
switch (c) {
case 'u':
need_uprobes = 1;
+ if (optarg)
+ uprobes_path = strdup (optarg);
break;
case 'v':
verbose++;
if (run_as(0, 0, 0, argv[0], argv) == 0)
return 0;
+ /* Try the specified module or the one from the runtime. */
+ if (uprobes_path)
+ snprintf (runtimeko, sizeof(runtimeko), "%s", uprobes_path);
+ else
+ snprintf (runtimeko, sizeof(runtimeko), "%s/uprobes/uprobes.ko",
+ (getenv("SYSTEMTAP_RUNTIME") ?: PKGDATADIR "/runtime"));
+ dbug(2, "Inserting uprobes module from %s.\n", runtimeko);
/* This module may be signed, so use insert_module to load it. */
- snprintf (runtimeko, sizeof(runtimeko), "%s/uprobes/uprobes.ko",
- (getenv("SYSTEMTAP_RUNTIME") ?: PKGDATADIR "/runtime"));
- dbug(2, "Inserting uprobes module from SystemTap runtime %s.\n", runtimeko);
argv[0] = NULL;
if (insert_module(runtimeko, NULL, argv, assert_uprobes_module_permissions) == 0)
return 0;
extern int delete_mod;
extern int load_only;
extern int need_uprobes;
+extern const char *uprobes_path;
extern int daemon_mode;
extern off_t fsize_max;
extern int fnum_max;
poison_cache = false;
tapset_compile_coverage = false;
need_uprobes = false;
+ uprobes_path = "";
consult_symtab = false;
ignore_vmlinux = false;
ignore_dwarf = false;
return 0;
}
-int
-systemtap_session::parse_kernel_exports ()
-{
- string kernel_exports_file = kernel_build_tree + "/Module.symvers";
- struct stat st;
- int rc = stat(kernel_exports_file.c_str(), &st);
- if (rc != 0)
- {
- clog << "Checking \"" << kernel_exports_file << "\" failed: " << strerror(errno) << endl
- << "Ensure kernel development headers & makefiles are installed." << endl;
- return rc;
- }
-
- ifstream kef (kernel_exports_file.c_str());
- string line;
- while (getline (kef, line))
- {
- vector<string> tokens;
- tokenize (line, tokens, "\t");
- if (tokens.size() == 4 &&
- tokens[2] == "vmlinux" &&
- tokens[3].substr(0,13) == string("EXPORT_SYMBOL"))
- kernel_exports.insert (tokens[1]);
- }
- if (verbose > 2)
- clog << "Parsed kernel \"" << kernel_exports_file << "\", number of vmlinux exports: " << kernel_exports.size() << endl;
-
- kef.close();
- return 0;
-}
-
-
void systemtap_session::insert_loaded_modules()
{
char line[1024];
// to be cleared in the systemtap_session ctor (session.cxx).
void setup_kernel_release (const char* kstr);
int parse_kernel_config ();
- int parse_kernel_exports ();
void insert_loaded_modules ();
// command line parsing
bool prologue_searching;
bool tapset_compile_coverage;
bool need_uprobes;
+ std::string uprobes_path;
bool load_only; // flight recorder mode
bool omit_werror;
bool unprivileged;
char stapstdout[PATH_MAX];
char stapstderr[PATH_MAX];
char staprc[PATH_MAX];
+ char stapsymvers[PATH_MAX];
#define MAXSTAPARGC 1000 /* sorry, too lazy to dynamically allocate */
char* stapargv[MAXSTAPARGC];
int stapargc=0;
FILE* f;
int unprivileged = 0;
int stapargv_freestart = 0;
+ struct stat st;
stapargv[stapargc++] = getenv ("SYSTEMTAP_STAP") ?: STAP_PREFIX "/bin/stap";
errWarn("stap-sign-module");
}
}
- }
- /* XXX: What about uprobes.ko? */
+ /* If uprobes.ko is required, then we need to return it to the client.
+ uprobes.ko was requires if the file "Module.symvers" is not empty in
+ the temp directory. */
+ snprintf (stapsymvers, PATH_MAX, "%s/Module.symvers", new_staptmpdir);
+ rc = stat (stapsymvers, & st);
+ if (rc == 0 && st.st_size != 0)
+ {
+ /* uprobes.ko is required. Link to it from the response directory. */
+ char *lnargv[10];
+ lnargv[0] = "/bin/ln";
+ lnargv[1] = "-s";
+ lnargv[2] = PKGDATADIR "/runtime/uprobes/uprobes.ko";
+ lnargv[3] = (char*)responseDirName;
+ lnargv[4] = NULL;
+ rc = spawn_and_wait (lnargv, NULL, NULL, NULL, NULL);
+ if (rc != PR_SUCCESS)
+ errWarn("stap uprobes.ko link");
+
+ /* In unprivileged mode, we need to return the signature as well. */
+ if (unprivileged)
+ {
+ lnargv[2] = PKGDATADIR "/runtime/uprobes/uprobes.ko.sgn";
+ rc = spawn_and_wait (lnargv, NULL, NULL, NULL, NULL);
+ if (rc != PR_SUCCESS)
+ errWarn("stap uprobes.ko.sgn link");
+ }
+ }
+ }
}
/* Free up all the arg string copies. Note that the first few were alloc'd
if (prStatus != PR_SUCCESS)
exitErr("PR_SetSocketOption");
-#if 0
- /* This cipher is not on by default. The Acceptance test
- * would like it to be. Turn this cipher on.
- */
- secStatus = SSL_CipherPrefSetDefault(SSL_RSA_WITH_NULL_MD5, PR_TRUE);
- if (secStatus != SECSuccess)
- exitErr("SSL_CipherPrefSetDefault:SSL_RSA_WITH_NULL_MD5");
-#endif
-
/* Configure the network connection. */
addr.inet.family = PR_AF_INET;
addr.inet.ip = PR_INADDR_ANY;