summaryrefslogtreecommitdiffstats
path: root/runtime
diff options
context:
space:
mode:
authorDave Brolley <brolley@redhat.com>2009-11-24 15:04:01 -0500
committerDave Brolley <brolley@redhat.com>2009-11-24 15:04:01 -0500
commitff3576d585aee3140b41bb77a0e8e4063e704f43 (patch)
treea35182cf49cef1c61b065099d298f513ae58d4ae /runtime
parent5d1c958ce2dcc0f28c1bd13b8e005c0c2ad1cdba (diff)
parent7067e1b0418eed528fe2d102654dbe12bb9236af (diff)
downloadsystemtap-steved-ff3576d585aee3140b41bb77a0e8e4063e704f43.tar.gz
systemtap-steved-ff3576d585aee3140b41bb77a0e8e4063e704f43.tar.xz
systemtap-steved-ff3576d585aee3140b41bb77a0e8e4063e704f43.zip
Merge branch 'master' of ssh://sources.redhat.com/git/systemtap
Diffstat (limited to 'runtime')
-rw-r--r--runtime/staprun/staprun_funcs.c182
1 files changed, 121 insertions, 61 deletions
diff --git a/runtime/staprun/staprun_funcs.c b/runtime/staprun/staprun_funcs.c
index 4df1992c..b23d7822 100644
--- a/runtime/staprun/staprun_funcs.c
+++ b/runtime/staprun/staprun_funcs.c
@@ -22,6 +22,8 @@
#include <pwd.h>
#include <assert.h>
+typedef int (*check_module_path_func)(const char *module_path);
+
extern long init_module(void *, unsigned long, const char *);
/* Module errors get translated. */
@@ -231,10 +233,7 @@ int mountfs(void)
#if HAVE_NSS
/*
- * Modules which have been signed using a certificate and private key
- * corresponding to a certificate and public key in the database in
- * the '$sysconfdir/systemtap/staprun' directory may be loaded by
- * anyone.
+ * Check the signature of the given module.
*
* Returns: -1 on errors, 0 on failure, 1 on success.
*/
@@ -263,14 +262,15 @@ check_signature(const char *path, const void *module_data, off_t module_size)
#endif /* HAVE_NSS */
/*
- * Members of the 'stapusr' group can only use "blessed" modules -
+ * For stap modules which have not been signed by a trusted signer,
+ * members of the 'stapusr' group can only use the "blessed" modules -
* ones in the '/lib/modules/KVER/systemtap' directory. Make sure the
* module path is in that directory.
*
- * Returns: -1 on errors, 0 on failure, 1 on success.
+ * Returns: -1 on errors, 1 on success.
*/
static int
-check_path(const char *module_path)
+check_stap_module_path(const char *module_path)
{
char staplib_dir_path[PATH_MAX];
char staplib_dir_realpath[PATH_MAX];
@@ -288,39 +288,49 @@ check_path(const char *module_path)
/* Validate /lib/modules/KVER/systemtap. */
if (stat(staplib_dir_path, &sb) < 0) {
- perr("Members of the \"stapusr\" group can only use modules within\n"
+ perr("Unable to verify the signature for the module %s.\n"
+ " Members of the \"stapusr\" group can only use untrusted modules within\n"
" the \"%s\" directory.\n"
- " Error getting information on that directory", staplib_dir_path);
+ " Error getting information on that directory",
+ module_path, staplib_dir_path);
return -1;
}
/* Make sure it is a directory. */
if (! S_ISDIR(sb.st_mode)) {
- err("ERROR: Members of the \"stapusr\" group can only use modules within\n"
+ err("ERROR: Unable to verify the signature for the module %s.\n"
+ " Members of the \"stapusr\" group can only use untrusted modules within\n"
" the \"%s\" directory.\n"
- " That path must refer to a directory.\n", staplib_dir_path);
+ " That path must refer to a directory.\n",
+ module_path, staplib_dir_path);
return -1;
}
/* Make sure it is owned by root. */
if (sb.st_uid != 0) {
- err("ERROR: Members of the \"stapusr\" group can only use modules within\n"
+ err("ERROR: Unable to verify the signature for the module %s.\n"
+ " Members of the \"stapusr\" group can only use untrusted modules within\n"
" the \"%s\" directory.\n"
- " That directory should be owned by root.\n", staplib_dir_path);
+ " That directory should be owned by root.\n",
+ module_path, staplib_dir_path);
return -1;
}
/* Make sure it isn't world writable. */
if (sb.st_mode & S_IWOTH) {
- err("ERROR: Members of the \"stapusr\" group can only use modules within\n"
+ err("ERROR: Unable to verify the signature for the module %s.\n"
+ " Members of the \"stapusr\" group can only use untrusted modules within\n"
" the \"%s\" directory.\n"
- " That directory should not be world writable.\n", staplib_dir_path);
+ " That directory should not be world writable.\n",
+ module_path, staplib_dir_path);
return -1;
}
/* Use realpath() to canonicalize the module directory
* path. */
if (realpath(staplib_dir_path, staplib_dir_realpath) == NULL) {
- perr("Members of the \"stapusr\" group can only use modules within\n"
+ perr("Unable to verify the signature for the module %s.\n"
+ " Members of the \"stapusr\" group can only use untrusted modules within\n"
" the \"%s\" directory.\n"
- " Unable to canonicalize that directory", staplib_dir_path);
+ " Unable to canonicalize that directory",
+ module_path, staplib_dir_path);
return -1;
}
@@ -338,20 +348,34 @@ check_path(const char *module_path)
* path starts with staplib_dir_realpath. */
if (strncmp(staplib_dir_realpath, module_path,
strlen(staplib_dir_realpath)) != 0) {
- err("ERROR: Members of the \"stapusr\" group can only use modules within\n"
+ err("ERROR: Unable to verify the signature for the module %s.\n"
+ " Members of the \"stapusr\" group can only use untrusted modules within\n"
" the \"%s\" directory.\n"
" Module \"%s\" does not exist within that directory.\n",
- staplib_dir_path, module_path);
- return 0;
+ module_path, staplib_dir_path, module_path);
+ return -1;
}
return 1;
}
/*
+ * Members of the 'stapusr' group can load the uprobes module freely,
+ * since it is loaded from a fixed path in the installed runtime.
+ *
+ * Returns: -1 on errors, 0 on failure, 1 on success.
+ */
+static int
+check_uprobes_module_path (const char *module_path __attribute__ ((unused)))
+{
+ return 1;
+}
+
+/*
* Check the user's group membership.
*
* o members of stapdev can do anything
- * o members of stapusr can load modules from /lib/modules/KVER/systemtap
+ * o members of stapusr can load modules from certain module-specific
+ * paths.
*
* Returns: -2 if neither group exists
* -1 for other errors
@@ -359,7 +383,11 @@ check_path(const char *module_path)
* 1 on success
*/
static int
-check_groups (const char *module_path)
+check_groups (
+ const char *module_path,
+ int module_signature_status,
+ check_module_path_func check_path
+)
{
gid_t gid, gidlist[NGROUPS_MAX];
gid_t stapdev_gid, stapusr_gid;
@@ -428,8 +456,16 @@ check_groups (const char *module_path)
/* At this point the user is only a member of the 'stapusr'
* group. Members of the 'stapusr' group can only use modules
- * in /lib/modules/KVER/systemtap. Make sure the module path
- * is in that directory. */
+ * which have been signed by a trusted signer or which, in some cases,
+ * are at approved paths. */
+ if (module_signature_status == MODULE_OK)
+ return 1;
+ assert (module_signature_status == MODULE_UNTRUSTED ||
+ module_signature_status == MODULE_CHECK_ERROR);
+
+ /* Could not verify the module's signature, so check whether this module
+ can be loaded based on its path. check_path is a pointer to a
+ module-specific function which will do this. */
return check_path (module_path);
}
@@ -441,8 +477,8 @@ check_groups (const char *module_path)
*
* 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
+ * 3) members of stapusr can load a module which has been signed by a trusted signer
+ * 4) members of stapusr can load untrusted modules from /lib/modules/KVER/systemtap
*
* It is only an error if all 4 levels of checking fail
*/
@@ -452,13 +488,17 @@ void assert_stap_module_permissions(
off_t module_size __attribute__ ((unused))
) {
int check_groups_rc;
+ int check_signature_rc;
#if HAVE_NSS
- /* Attempt to verify the module against its signature. Return failure
- if the module has been tampered with (altered). */
- int check_signature_rc = check_signature (module_path, module_data, module_size);
+ /* Attempt to verify the module against its signature. Exit
+ immediately if the module has been tampered with (altered). */
+ check_signature_rc = check_signature (module_path, module_data, module_size);
if (check_signature_rc == MODULE_ALTERED)
exit(-1);
+#else
+ /* If we don't have NSS, the stap module is considered untrusted */
+ check_signature_rc = MODULE_UNTRUSTED;
#endif
/* If we're root, we can do anything. */
@@ -479,60 +519,80 @@ void assert_stap_module_permissions(
}
/* Check permissions for group membership. */
- check_groups_rc = check_groups (module_path);
+ check_groups_rc = check_groups (module_path, check_signature_rc, check_stap_module_path);
if (check_groups_rc == 1)
return;
- /* The user is an ordinary user. If the module has been signed with
- * an authorized certificate and private key, then we will load it for
- * anyone. */
+ /* Are we are an ordinary user?. */
+ if (check_groups_rc == 0) {
+ err("ERROR: You are trying to run systemtap as a normal user.\n"
+ "You should either be root, or be part of either "
+ "group \"stapdev\" or group \"stapusr\".\n");
+ if (check_groups_rc == -2)
+ err("Your system doesn't seem to have either group.\n");
#if HAVE_NSS
- if (check_signature_rc == MODULE_OK)
- return;
- assert (check_signature_rc == MODULE_UNTRUSTED || check_signature_rc == MODULE_CHECK_ERROR);
+ err("If you are part of the group \"stapusr\", the module must be "
+ "signed by a trusted signer.\n");
#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");
- if (check_groups_rc == -2) {
- 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
exit(-1);
}
/*
- * For the uprobes.ko module, if we have NSS, then
- * check the signature. Otherwise go ahead and load it.
+ * Check the user's permissions. Is he allowed to load the uprobes module?
+ *
+ * There are several levels of possible permission:
+ *
+ * 1) root can do anything
+ * 2) members of stapdev can do anything
+ * 3) members of stapusr can load a uprobes module which has been signed by a
+ * trusted signer
+ *
+ * It is only an error if all 3 levels of checking fail
*/
void assert_uprobes_module_permissions(
const char *module_path __attribute__ ((unused)),
const void *module_data __attribute__ ((unused)),
off_t module_size __attribute__ ((unused))
) {
+ int check_groups_rc;
+ int check_signature_rc;
+
#if HAVE_NSS
/* Attempt to verify the module against its signature. Return failure
if the module has been tampered with (altered). */
- int rc = check_signature (module_path, module_data, module_size);
- if (rc == MODULE_ALTERED)
+ check_signature_rc = check_signature (module_path, module_data, module_size);
+ if (check_signature_rc == MODULE_ALTERED)
exit(-1);
- if (rc == MODULE_OK)
+#else
+ /* If we don't have NSS, then the uprobes module is considered trusted.
+ Otherwise a member of the group 'stapusr' will not be able to load it.
+ */
+ check_signature_rc = MODULE_OK;
+#endif
+
+ /* root can still load this module. */
+ if (getuid() == 0)
return;
- assert (rc == MODULE_UNTRUSTED || rc == MODULE_CHECK_ERROR);
- err("Signature verification failed for module %s.\n", module_path);
- if (rc == MODULE_UNTRUSTED) {
- err("Run '" BINDIR "/stap-sign-module %s' as root and/or\n", module_path);
- err("run '" BINDIR "/stap-authorize-signing-cert %s' as root\n",
- SYSCONFDIR "/systemtap/ssl/server/stap.cert");
+
+ /* Members of the groups stapdev and stapusr can still load this module. */
+ check_groups_rc = check_groups (module_path, check_signature_rc, check_uprobes_module_path);
+ if (check_groups_rc == 1)
+ return;
+
+ /* Check permissions for group membership. */
+ if (check_groups_rc == 0) {
+ err("ERROR: You are trying to load the module %s as a normal user.\n"
+ "You should either be root, or be part of either "
+ "group \"stapdev\" or group \"stapusr\".\n", module_path);
+ if (check_groups_rc == -2)
+ err("Your system doesn't seem to have either group.\n");
+#if HAVE_NSS
+ err("If you are part of the group \"stapusr\", the module must be "
+ "signed by a trusted signer.\n");
+#endif
}
+
exit(-1);
-#endif
}