summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Brolley <brolley@redhat.com>2010-02-15 13:56:20 -0500
committerDave Brolley <brolley@redhat.com>2010-02-15 13:56:20 -0500
commit27dc09b13650456b7b3efd45c07690083e526b6d (patch)
treefee2a7ea25f8e8d5f51a0bb5012c07743b170476
parent189559623dcda793b1ae9ade54299f5c7a775b76 (diff)
downloadsystemtap-steved-27dc09b13650456b7b3efd45c07690083e526b6d.tar.gz
systemtap-steved-27dc09b13650456b7b3efd45c07690083e526b6d.tar.xz
systemtap-steved-27dc09b13650456b7b3efd45c07690083e526b6d.zip
Rework identification of probes allowed for unprivileged users.
- Bind unprivileged permission at probe registration time. - Remove check_unprivileged filter from derived_probe_builder and its children. - Add test suites for unprivilegedok and unprivilegedko.
-rw-r--r--elaborate.cxx37
-rw-r--r--elaborate.h8
-rw-r--r--tapset-been.cxx17
-rw-r--r--tapset-mark.cxx4
-rw-r--r--tapset-timers.cxx35
-rw-r--r--tapset-utrace.cxx10
-rw-r--r--tapsets.cxx127
-rwxr-xr-xtestsuite/semko/fortyeight.stp4
-rw-r--r--testsuite/systemtap.unprivileged/foo.c7
-rw-r--r--testsuite/systemtap.unprivileged/unprivilegedko.exp13
-rwxr-xr-xtestsuite/systemtap.unprivileged/unprivilegedko/five.stp4
-rwxr-xr-xtestsuite/systemtap.unprivileged/unprivilegedko/four.stp4
-rwxr-xr-xtestsuite/systemtap.unprivileged/unprivilegedko/one.stp4
-rwxr-xr-xtestsuite/systemtap.unprivileged/unprivilegedko/three.stp4
-rwxr-xr-xtestsuite/systemtap.unprivileged/unprivilegedko/two.stp4
-rw-r--r--testsuite/systemtap.unprivileged/unprivilegedok.exp15
-rwxr-xr-xtestsuite/systemtap.unprivileged/unprivilegedok/one.stp4
17 files changed, 205 insertions, 96 deletions
diff --git a/elaborate.cxx b/elaborate.cxx
index 2ae90139..b8bff286 100644
--- a/elaborate.cxx
+++ b/elaborate.cxx
@@ -1,5 +1,5 @@
// elaboration functions
-// Copyright (C) 2005-2009 Red Hat Inc.
+// Copyright (C) 2005-2010 Red Hat Inc.
// Copyright (C) 2008 Intel Corporation
//
// This file is part of systemtap, and is free software. You can
@@ -179,17 +179,6 @@ derived_probe::print_dupe_stamp_unprivileged_process_owner(ostream& o)
// ------------------------------------------------------------------------
// Members of derived_probe_builder
-void
-derived_probe_builder::check_unprivileged (const systemtap_session & sess,
- const literal_map_t & parameters)
-{
- // By default, probes are not allowed for unprivileged users.
- if (sess.unprivileged)
- {
- throw semantic_error (string("probe point is not allowed for unprivileged users"));
- }
-}
-
bool
derived_probe_builder::get_param (std::map<std::string, literal*> const & params,
const std::string& key,
@@ -314,7 +303,8 @@ match_key::globmatch(match_key const & other) const
// Members of match_node
// ------------------------------------------------------------------------
-match_node::match_node()
+match_node::match_node() :
+ unprivileged_ok(false)
{
}
@@ -356,6 +346,13 @@ match_node::bind_num(string const & k)
return bind(match_key(k).with_number());
}
+match_node *
+match_node::bind_unprivileged(bool b)
+{
+ unprivileged_ok = b;
+ return this;
+}
+
void
match_node::find_and_build (systemtap_session& s,
probe* p, probe_point *loc, unsigned pos,
@@ -375,6 +372,11 @@ match_node::find_and_build (systemtap_session& s,
" (follow:" + alternatives + ")", loc->components.back()->tok);
}
+ if (s.unprivileged && ! unprivileged_ok)
+ {
+ throw semantic_error (string("probe point is not allowed for unprivileged users"));
+ }
+
map<string, literal *> param_map;
for (unsigned i=0; i<pos; i++)
param_map[loc->components[i]->functor] = loc->components[i]->arg;
@@ -384,7 +386,6 @@ match_node::find_and_build (systemtap_session& s,
for (unsigned k=0; k<ends.size(); k++)
{
derived_probe_builder *b = ends[k];
- b->check_unprivileged (s, param_map);
b->build (s, p, loc, param_map, results);
}
}
@@ -465,8 +466,7 @@ match_node::find_and_build (systemtap_session& s,
for (sub_map_iterator_t i = sub.begin(); i != sub.end(); i++)
alternatives += string(" ") + i->first.str();
-
- throw semantic_error (string("probe point mismatch at position ") +
+ throw semantic_error(string("probe point mismatch at position ") +
lex_cast (pos) +
" (alternatives:" + alternatives + ")",
loc->components[pos]->tok);
@@ -607,11 +607,6 @@ alias_expansion_builder
}
return false;
}
-
- // No action required. The actual probes will be checked when they are
- // built.
- virtual void check_unprivileged (const systemtap_session & sess,
- const literal_map_t & parameters) {}
};
diff --git a/elaborate.h b/elaborate.h
index 0a1549fb..b97d2ca8 100644
--- a/elaborate.h
+++ b/elaborate.h
@@ -1,5 +1,5 @@
// -*- C++ -*-
-// Copyright (C) 2005-2009 Red Hat Inc.
+// Copyright (C) 2005-2010 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
@@ -218,8 +218,6 @@ struct derived_probe_builder
probe_point* location,
literal_map_t const & parameters,
std::vector<derived_probe*> & finished_results) = 0;
- virtual void check_unprivileged (const systemtap_session & sess,
- const literal_map_t & parameters);
virtual ~derived_probe_builder() {}
virtual void build_no_more (systemtap_session &) {}
@@ -270,7 +268,11 @@ match_node
match_node* bind(std::string const & k);
match_node* bind_str(std::string const & k);
match_node* bind_num(std::string const & k);
+ match_node* bind_unprivileged(bool b = true);
void bind(derived_probe_builder* e);
+
+private:
+ bool unprivileged_ok;
};
// ------------------------------------------------------------------------
diff --git a/tapset-been.cxx b/tapset-been.cxx
index d7d74c33..ac97ebca 100644
--- a/tapset-been.cxx
+++ b/tapset-been.cxx
@@ -1,5 +1,5 @@
// tapset for begin/end/error/never
-// Copyright (C) 2005-2009 Red Hat Inc.
+// Copyright (C) 2005-2010 Red Hat Inc.
// Copyright (C) 2005-2007 Intel Corporation.
// Copyright (C) 2008 James.Bottomley@HansenPartnership.com
//
@@ -92,10 +92,6 @@ struct be_builder: public derived_probe_builder
finished_results.push_back
(new be_derived_probe(base, location, type, priority));
}
-
- // No action required. These probes are allowed for unprivileged users.
- virtual void check_unprivileged (const systemtap_session & sess,
- const literal_map_t & parameters) {}
};
@@ -214,10 +210,6 @@ struct never_builder: public derived_probe_builder
{
finished_results.push_back(new never_derived_probe(base, location));
}
-
- // No action required. This probe is allowed for unprivileged users.
- virtual void check_unprivileged (const systemtap_session & sess,
- const literal_map_t & parameters) {}
};
@@ -232,21 +224,28 @@ register_tapset_been(systemtap_session& s)
match_node* root = s.pattern_root;
root->bind(TOK_BEGIN)
+ ->bind_unprivileged()
->bind(new be_builder(BEGIN));
root->bind_num(TOK_BEGIN)
+ ->bind_unprivileged()
->bind(new be_builder(BEGIN));
root->bind(TOK_END)
+ ->bind_unprivileged()
->bind(new be_builder(END));
root->bind_num(TOK_END)
+ ->bind_unprivileged()
->bind(new be_builder(END));
root->bind(TOK_ERROR)
+ ->bind_unprivileged()
->bind(new be_builder(ERROR));
root->bind_num(TOK_ERROR)
+ ->bind_unprivileged()
->bind(new be_builder(ERROR));
root->bind(TOK_NEVER)
+ ->bind_unprivileged()
->bind(new never_builder());
}
diff --git a/tapset-mark.cxx b/tapset-mark.cxx
index 4d873eed..3fd6f11f 100644
--- a/tapset-mark.cxx
+++ b/tapset-mark.cxx
@@ -1,5 +1,5 @@
// tapset for kernel static markers
-// Copyright (C) 2005-2009 Red Hat Inc.
+// Copyright (C) 2005-2010 Red Hat Inc.
// Copyright (C) 2005-2007 Intel Corporation.
// Copyright (C) 2008 James.Bottomley@HansenPartnership.com
//
@@ -714,8 +714,6 @@ mark_builder::build(systemtap_session & sess,
void
register_tapset_mark(systemtap_session& s)
{
- if (s.unprivileged) return;
-
match_node* root = s.pattern_root;
derived_probe_builder *builder = new mark_builder();
diff --git a/tapset-timers.cxx b/tapset-timers.cxx
index 7195cfaf..464f36f2 100644
--- a/tapset-timers.cxx
+++ b/tapset-timers.cxx
@@ -1,5 +1,5 @@
// tapset for timers
-// Copyright (C) 2005-2009 Red Hat Inc.
+// Copyright (C) 2005-2010 Red Hat Inc.
// Copyright (C) 2005-2007 Intel Corporation.
// Copyright (C) 2008 James.Bottomley@HansenPartnership.com
//
@@ -515,9 +515,6 @@ struct timer_builder: public derived_probe_builder
vector<derived_probe *> & finished_results);
static void register_patterns(systemtap_session& s);
-
- virtual void check_unprivileged (const systemtap_session & sess,
- const literal_map_t & parameters);
};
void
@@ -599,16 +596,6 @@ timer_builder::build(systemtap_session & sess,
}
void
-timer_builder::check_unprivileged (const systemtap_session & sess,
- const literal_map_t & parameters)
-{
- // All timer probes are allowed except for timer.profile
- if (has_null_param(parameters, "profile"))
- derived_probe_builder::check_unprivileged (sess, parameters);
-}
-
-
-void
register_tapset_timers(systemtap_session& s)
{
match_node* root = s.pattern_root;
@@ -617,49 +604,69 @@ register_tapset_timers(systemtap_session& s)
root = root->bind(TOK_TIMER);
root->bind_num("s")
+ ->bind_unprivileged()
->bind(builder);
root->bind_num("s")->bind_num("randomize")
+ ->bind_unprivileged()
->bind(builder);
root->bind_num("sec")
+ ->bind_unprivileged()
->bind(builder);
root->bind_num("sec")->bind_num("randomize")
+ ->bind_unprivileged()
->bind(builder);
root->bind_num("ms")
+ ->bind_unprivileged()
->bind(builder);
root->bind_num("ms")->bind_num("randomize")
+ ->bind_unprivileged()
->bind(builder);
root->bind_num("msec")
+ ->bind_unprivileged()
->bind(builder);
root->bind_num("msec")->bind_num("randomize")
+ ->bind_unprivileged()
->bind(builder);
root->bind_num("us")
+ ->bind_unprivileged()
->bind(builder);
root->bind_num("us")->bind_num("randomize")
+ ->bind_unprivileged()
->bind(builder);
root->bind_num("usec")
+ ->bind_unprivileged()
->bind(builder);
root->bind_num("usec")->bind_num("randomize")
+ ->bind_unprivileged()
->bind(builder);
root->bind_num("ns")
+ ->bind_unprivileged()
->bind(builder);
root->bind_num("ns")->bind_num("randomize")
+ ->bind_unprivileged()
->bind(builder);
root->bind_num("nsec")
+ ->bind_unprivileged()
->bind(builder);
root->bind_num("nsec")->bind_num("randomize")
+ ->bind_unprivileged()
->bind(builder);
root->bind_num("jiffies")
+ ->bind_unprivileged()
->bind(builder);
root->bind_num("jiffies")->bind_num("randomize")
+ ->bind_unprivileged()
->bind(builder);
root->bind_num("hz")
+ ->bind_unprivileged()
->bind(builder);
+ // Not ok for unprivileged users.
root->bind("profile")
->bind(builder);
}
diff --git a/tapset-utrace.cxx b/tapset-utrace.cxx
index fc2fbc1d..73f52c4d 100644
--- a/tapset-utrace.cxx
+++ b/tapset-utrace.cxx
@@ -654,10 +654,6 @@ struct utrace_builder: public derived_probe_builder
has_path, path, pid,
flags));
}
-
- // No action required. These probes are allowed for unprivileged users.
- virtual void check_unprivileged (const systemtap_session & sess,
- const literal_map_t & parameters) {}
};
@@ -1062,16 +1058,22 @@ register_tapset_utrace(systemtap_session& s)
for (unsigned i = 0; i < roots.size(); ++i)
{
roots[i]->bind(TOK_BEGIN)
+ ->bind_unprivileged()
->bind(builder);
roots[i]->bind(TOK_END)
+ ->bind_unprivileged()
->bind(builder);
roots[i]->bind(TOK_THREAD)->bind(TOK_BEGIN)
+ ->bind_unprivileged()
->bind(builder);
roots[i]->bind(TOK_THREAD)->bind(TOK_END)
+ ->bind_unprivileged()
->bind(builder);
roots[i]->bind(TOK_SYSCALL)
+ ->bind_unprivileged()
->bind(builder);
roots[i]->bind(TOK_SYSCALL)->bind(TOK_RETURN)
+ ->bind_unprivileged()
->bind(builder);
}
}
diff --git a/tapsets.cxx b/tapsets.cxx
index bdce18a5..b4987b33 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -352,6 +352,7 @@ struct dwarf_derived_probe: public derived_probe
string section;
Dwarf_Addr addr;
string path;
+ bool has_process;
bool has_return;
bool has_maxactive;
bool has_library;
@@ -366,13 +367,19 @@ struct dwarf_derived_probe: public derived_probe
void emit_probe_local_init(translator_output * o);
void getargs(std::list<std::string> &arg_set) const;
+ void emit_unprivileged_assertion (translator_output*);
+ void print_dupe_stamp(ostream& o);
+
// Pattern registration helpers.
static void register_statement_variants(match_node * root,
- dwarf_builder * dw);
+ dwarf_builder * dw,
+ bool bind_unprivileged_p = false);
static void register_function_variants(match_node * root,
- dwarf_builder * dw);
+ dwarf_builder * dw,
+ bool bind_unprivileged_p = false);
static void register_function_and_statement_variants(match_node * root,
- dwarf_builder * dw);
+ dwarf_builder * dw,
+ bool bind_unprivileged_p = false);
static void register_patterns(systemtap_session& s);
protected:
@@ -690,11 +697,6 @@ struct dwarf_builder: public derived_probe_builder
probe_point * location,
literal_map_t const & parameters,
vector<derived_probe *> & finished_results);
-
- // No action required. These probes are allowed for unprivileged users.
- // as process owners.
- virtual void check_unprivileged (const systemtap_session & sess,
- const literal_map_t & parameters) {}
};
@@ -2877,6 +2879,7 @@ dwarf_derived_probe::dwarf_derived_probe(const string& funcname,
: derived_probe (q.base_probe, new probe_point(*q.base_loc) /* .components soon rewritten */ ),
module (module), section (section), addr (addr),
path (q.path),
+ has_process (q.has_process),
has_return (q.has_return),
has_maxactive (q.has_maxactive),
has_library (q.has_library),
@@ -3105,28 +3108,77 @@ dwarf_derived_probe::getargs(std::list<std::string> &arg_set) const
}
+void
+dwarf_derived_probe::emit_unprivileged_assertion (translator_output* o)
+{
+ if (has_process)
+ {
+ // These probes are allowed for unprivileged users, but only in the
+ // context of processes which they own.
+ emit_process_owner_assertion (o);
+ return;
+ }
+
+ // Other probes must contain the default assertion which aborts
+ // if executed by an unprivileged user.
+ derived_probe::emit_unprivileged_assertion (o);
+}
+
+
+void
+dwarf_derived_probe::print_dupe_stamp(ostream& o)
+{
+ if (has_process)
+ {
+ // These probes are allowed for unprivileged users, but only in the
+ // context of processes which they own.
+ print_dupe_stamp_unprivileged_process_owner (o);
+ return;
+ }
+
+ // Other probes must contain the default dupe stamp
+ derived_probe::print_dupe_stamp (o);
+}
+
void
dwarf_derived_probe::register_statement_variants(match_node * root,
- dwarf_builder * dw)
+ dwarf_builder * dw,
+ bool bind_unprivileged_p)
{
- root->bind(dw);
+ root
+ ->bind_unprivileged(bind_unprivileged_p)
+ ->bind(dw);
}
void
dwarf_derived_probe::register_function_variants(match_node * root,
- dwarf_builder * dw)
+ dwarf_builder * dw,
+ bool bind_unprivileged_p)
{
- 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);
+ root
+ ->bind_unprivileged(bind_unprivileged_p)
+ ->bind(dw);
+ root->bind(TOK_INLINE)
+ ->bind_unprivileged(bind_unprivileged_p)
+ ->bind(dw);
+ root->bind(TOK_CALL)
+ ->bind_unprivileged(bind_unprivileged_p)
+ ->bind(dw);
+ root->bind(TOK_RETURN)
+ ->bind_unprivileged(bind_unprivileged_p)
+ ->bind(dw);
+ root->bind(TOK_RETURN)
+ ->bind_unprivileged(bind_unprivileged_p)
+ ->bind_num(TOK_MAXACTIVE)->bind(dw);
}
void
-dwarf_derived_probe::register_function_and_statement_variants(match_node * root,
- dwarf_builder * dw)
+dwarf_derived_probe::register_function_and_statement_variants(
+ match_node * root,
+ dwarf_builder * dw,
+ bool bind_unprivileged_p
+)
{
// Here we match 4 forms:
//
@@ -3135,10 +3187,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, bind_unprivileged_p);
+ register_function_variants(root->bind_num(TOK_FUNCTION), dw, bind_unprivileged_p);
+ register_statement_variants(root->bind_str(TOK_STATEMENT), dw, bind_unprivileged_p);
+ register_statement_variants(root->bind_num(TOK_STATEMENT), dw, bind_unprivileged_p);
}
void
@@ -3150,24 +3202,27 @@ dwarf_derived_probe::register_patterns(systemtap_session& s)
update_visitor *filter = new dwarf_cast_expanding_visitor(s, *dw);
s.code_filters.push_back(filter);
- if (! s.unprivileged)
- {
- register_function_and_statement_variants(root->bind(TOK_KERNEL), dw);
- register_function_and_statement_variants(root->bind_str(TOK_MODULE), dw);
- 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);
- }
+ register_function_and_statement_variants(root->bind(TOK_KERNEL), dw);
+ register_function_and_statement_variants(root->bind_str(TOK_MODULE), dw);
+
+ 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);
- register_function_and_statement_variants(root->bind_str(TOK_PROCESS), dw);
+ register_function_and_statement_variants(root->bind_str(TOK_PROCESS), dw,
+ true/*bind_unprivileged*/);
root->bind_str(TOK_PROCESS)->bind_str(TOK_FUNCTION)->bind_str(TOK_LABEL)
+ ->bind_unprivileged()
->bind(dw);
root->bind_str(TOK_PROCESS)->bind_str(TOK_LIBRARY)->bind_str(TOK_MARK)
+ ->bind_unprivileged()
->bind(dw);
root->bind_str(TOK_PROCESS)->bind_str(TOK_MARK)
+ ->bind_unprivileged()
->bind(dw);
root->bind_str(TOK_PROCESS)->bind_num(TOK_MARK)
+ ->bind_unprivileged()
->bind(dw);
}
@@ -4536,10 +4591,6 @@ struct uprobe_builder: public derived_probe_builder
finished_results.push_back(new uprobe_derived_probe(base, location, process, address, rr));
}
-
- // No action required. These probes are allowed for unprivileged users.
- virtual void check_unprivileged (const systemtap_session & sess,
- const literal_map_t & parameters) {}
};
@@ -6494,13 +6545,13 @@ register_standard_tapsets(systemtap_session & s)
// XXX: user-space starter set
s.pattern_root->bind_num(TOK_PROCESS)
->bind_num(TOK_STATEMENT)->bind(TOK_ABSOLUTE)
+ ->bind_unprivileged()
->bind(new uprobe_builder ());
s.pattern_root->bind_num(TOK_PROCESS)
->bind_num(TOK_STATEMENT)->bind(TOK_ABSOLUTE)->bind(TOK_RETURN)
+ ->bind_unprivileged()
->bind(new uprobe_builder ());
- if (s.unprivileged) return;
-
// kernel tracepoint probes
s.pattern_root->bind(TOK_KERNEL)->bind_str(TOK_TRACE)
->bind(new tracepoint_builder());
diff --git a/testsuite/semko/fortyeight.stp b/testsuite/semko/fortyeight.stp
deleted file mode 100755
index e79d7a1d..00000000
--- a/testsuite/semko/fortyeight.stp
+++ /dev/null
@@ -1,4 +0,0 @@
-#! /bin/sh
-
-# None of these probe types should even be acceptable to pass-2
-stap --unprivileged -p2 -t -e 'probe kernel.function("sys_open")!, kernel.trace("*")!, kernel.mark("*")!, module("*scsi*").function("*") { }'
diff --git a/testsuite/systemtap.unprivileged/foo.c b/testsuite/systemtap.unprivileged/foo.c
new file mode 100644
index 00000000..82ff7232
--- /dev/null
+++ b/testsuite/systemtap.unprivileged/foo.c
@@ -0,0 +1,7 @@
+/* Test application */
+void bar () {
+}
+
+main () {
+ bar ();
+}
diff --git a/testsuite/systemtap.unprivileged/unprivilegedko.exp b/testsuite/systemtap.unprivileged/unprivilegedko.exp
new file mode 100644
index 00000000..edcea130
--- /dev/null
+++ b/testsuite/systemtap.unprivileged/unprivilegedko.exp
@@ -0,0 +1,13 @@
+set self unprivilegedko
+foreach file [lsort [glob -nocomplain $srcdir/systemtap.unprivileged/$self/*.stp]] {
+ set test $self/[file tail $file]
+ verbose -log "Running $file"
+ set rc [stap_run_batch $file]
+ if {$rc < 0} {
+ # crashed
+ fail $test
+ } else {
+ setup_xfail *-*-*
+ if {$rc == 0} { pass $test } else { fail $test }
+ }
+}
diff --git a/testsuite/systemtap.unprivileged/unprivilegedko/five.stp b/testsuite/systemtap.unprivileged/unprivilegedko/five.stp
new file mode 100755
index 00000000..3f6d278e
--- /dev/null
+++ b/testsuite/systemtap.unprivileged/unprivilegedko/five.stp
@@ -0,0 +1,4 @@
+#! /bin/sh
+
+# This probe should not be acceptable to pass-2
+stap --unprivileged -p2 -e 'probe kernel.mark("*").format("*") { }'
diff --git a/testsuite/systemtap.unprivileged/unprivilegedko/four.stp b/testsuite/systemtap.unprivileged/unprivilegedko/four.stp
new file mode 100755
index 00000000..6c5e4f64
--- /dev/null
+++ b/testsuite/systemtap.unprivileged/unprivilegedko/four.stp
@@ -0,0 +1,4 @@
+#! /bin/sh
+
+# This probe should not be acceptable to pass-2
+stap --unprivileged -p2 -e 'probe kernel.mark("*") {}' \ No newline at end of file
diff --git a/testsuite/systemtap.unprivileged/unprivilegedko/one.stp b/testsuite/systemtap.unprivileged/unprivilegedko/one.stp
new file mode 100755
index 00000000..1dfde502
--- /dev/null
+++ b/testsuite/systemtap.unprivileged/unprivilegedko/one.stp
@@ -0,0 +1,4 @@
+#! /bin/sh
+
+# This probe should not be acceptable to pass-2
+stap --unprivileged -p2 -e 'probe kernel.function("sys_open") { }'
diff --git a/testsuite/systemtap.unprivileged/unprivilegedko/three.stp b/testsuite/systemtap.unprivileged/unprivilegedko/three.stp
new file mode 100755
index 00000000..5ab986c5
--- /dev/null
+++ b/testsuite/systemtap.unprivileged/unprivilegedko/three.stp
@@ -0,0 +1,4 @@
+#! /bin/sh
+
+# This probe should not be acceptable to pass-2
+stap --unprivileged -p2 -e 'probe module("*scsi*").function("*") { }'
diff --git a/testsuite/systemtap.unprivileged/unprivilegedko/two.stp b/testsuite/systemtap.unprivileged/unprivilegedko/two.stp
new file mode 100755
index 00000000..f37149b2
--- /dev/null
+++ b/testsuite/systemtap.unprivileged/unprivilegedko/two.stp
@@ -0,0 +1,4 @@
+#! /bin/sh
+
+# This probe should not be acceptable to pass-2
+stap --unprivileged -p2 -e 'probe kernel.trace("*") {}' \ No newline at end of file
diff --git a/testsuite/systemtap.unprivileged/unprivilegedok.exp b/testsuite/systemtap.unprivileged/unprivilegedok.exp
new file mode 100644
index 00000000..d86bdd7b
--- /dev/null
+++ b/testsuite/systemtap.unprivileged/unprivilegedok.exp
@@ -0,0 +1,15 @@
+set self unprivilegedok
+
+# Need to build a user application
+catch {exec gcc -g -o foo $srcdir/systemtap.unprivileged/foo.c} err
+if {$err == "" && [file exists foo]} then { pass "$self compile" } else { fail "$self compile: $err" }
+
+# Now run the tests
+foreach file [lsort [glob -nocomplain $srcdir/systemtap.unprivileged/$self/*.stp]] {
+ set test $self/[file tail $file]
+ verbose -log "Running $file"
+ set rc [stap_run_batch $file]
+ if {$rc == 0} { pass $test } else { fail $test }
+}
+
+catch {exec rm -f foo}
diff --git a/testsuite/systemtap.unprivileged/unprivilegedok/one.stp b/testsuite/systemtap.unprivileged/unprivilegedok/one.stp
new file mode 100755
index 00000000..fb0ad6e7
--- /dev/null
+++ b/testsuite/systemtap.unprivileged/unprivilegedok/one.stp
@@ -0,0 +1,4 @@
+#! /bin/sh
+
+# This probe should be ok
+stap --unprivileged -p2 -t -e 'probe process("foo").function("bar").call { }' -c ./foo