summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Stone <jistone@redhat.com>2009-09-03 14:31:02 -0700
committerJosh Stone <jistone@redhat.com>2009-09-03 14:31:02 -0700
commit06e0b6262393b095a33e9cc6e7ab7bc5d4fe9c95 (patch)
tree8029267099eec7bd898e6532bf6152c8b946f8ba
parentb969d16b2986a491eb37706e09da888d9914a7dd (diff)
parentd0822e28934cd0387c2af4349cf52c52c368c55a (diff)
downloadsystemtap-steved-06e0b6262393b095a33e9cc6e7ab7bc5d4fe9c95.tar.gz
systemtap-steved-06e0b6262393b095a33e9cc6e7ab7bc5d4fe9c95.tar.xz
systemtap-steved-06e0b6262393b095a33e9cc6e7ab7bc5d4fe9c95.zip
Merge branch 'master' of sourceware.org:/git/systemtap
-rw-r--r--runtime/addr-map.c45
-rw-r--r--runtime/loc2c-runtime.h28
-rw-r--r--runtime/staprun/staprun.c10
-rw-r--r--runtime/task_finder.c23
-rw-r--r--runtime/transport/transport.c4
-rw-r--r--tapset-utrace.cxx20
-rw-r--r--tapsets.cxx17
-rw-r--r--testsuite/systemtap.base/cache.exp5
-rw-r--r--translate.cxx2
9 files changed, 97 insertions, 57 deletions
diff --git a/runtime/addr-map.c b/runtime/addr-map.c
index e898044f..8c0e84d8 100644
--- a/runtime/addr-map.c
+++ b/runtime/addr-map.c
@@ -1,6 +1,6 @@
/* -*- linux-c -*-
* Map of addresses to disallow.
- * Copyright (C) 2005-2008 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
@@ -59,28 +59,41 @@ upper_bound(unsigned long addr, struct addr_map* map)
return entry - &map->entries[0];
}
+/* Search for an entry in the given map which overlaps the range specified by
+ addr and size. */
static struct addr_map_entry*
-lookup_addr_aux(unsigned long addr, struct addr_map* map)
+lookup_addr_aux(unsigned long addr, size_t size, struct addr_map* map)
{
size_t start = 0;
size_t end;
+
+ /* No map? No matching entry. */
if (!map)
return 0;
- end = map->size;
+ /* Empty map? No matching entry. */
if (map->size == 0)
return 0;
+ /* Use binary search on the sorted map entries. */
+ end = map->size;
do
{
int entry_idx;
struct addr_map_entry *entry = 0;
- if (addr < map->entries[start].min || addr >= map->entries[end - 1].max)
+ /* If the target range is beyond those of the remaining entries in the
+ map, then a matching entry will not be found */
+ if (addr + size <= map->entries[start].min ||
+ addr >= map->entries[end - 1].max)
return 0;
+ /* Choose the map entry at the mid point of the remaining entries. */
entry_idx = (end + start) / 2;
entry = &map->entries[entry_idx];
- if (entry->min <= addr && entry->max > addr)
+ /* If our range overlaps the range of this entry, then we have a match. */
+ if (addr + size > entry->min && addr < entry->max)
return entry;
- if (addr < entry->min)
+ /* If our range is below the range of this entry, then cull the entries
+ above this entry, otherwise cull the entries below it. */
+ if (addr + size <= entry->min)
end = entry_idx;
else
start = entry_idx + 1;
@@ -88,12 +101,24 @@ lookup_addr_aux(unsigned long addr, struct addr_map* map)
return 0;
}
+#ifndef STP_PRIVILEGED
+#include <asm/processor.h> /* For TASK_SIZE */
+#endif
+
static int
-lookup_bad_addr(unsigned long addr)
+lookup_bad_addr(unsigned long addr, size_t size)
{
struct addr_map_entry* result = 0;
+
+#ifndef STP_PRIVILEGED
+ /* Unprivileged users must not access kernel space memory. */
+ if (addr + size > TASK_SIZE)
+ return 1;
+#endif
+
+ /* Search for the given range in the black-listed map. */
spin_lock(&addr_map_lock);
- result = lookup_addr_aux(addr, blackmap);
+ result = lookup_addr_aux(addr, size, blackmap);
spin_unlock(&addr_map_lock);
if (result)
return 1;
@@ -149,8 +174,8 @@ add_bad_addr_entry(unsigned long min_addr, unsigned long max_addr,
}
else
{
- min_entry = lookup_addr_aux(min_addr, blackmap);
- max_entry = lookup_addr_aux(max_addr, blackmap);
+ min_entry = lookup_addr_aux(min_addr, 1, blackmap);
+ max_entry = lookup_addr_aux(max_addr, 1, blackmap);
if (min_entry || max_entry)
{
if (existing_min)
diff --git a/runtime/loc2c-runtime.h b/runtime/loc2c-runtime.h
index 620e1615..e9e5a071 100644
--- a/runtime/loc2c-runtime.h
+++ b/runtime/loc2c-runtime.h
@@ -192,7 +192,7 @@
#define kread(ptr) ({ \
typeof(*(ptr)) _v = 0; \
- if (lookup_bad_addr((unsigned long)(ptr)) || \
+ if (lookup_bad_addr((unsigned long)(ptr), sizeof (*(ptr))) || \
probe_kernel_read((void *)&_v, (void *)(ptr), sizeof(*(ptr)))) \
DEREF_FAULT(ptr); \
_v; \
@@ -201,7 +201,7 @@
#define kwrite(ptr, value) ({ \
typeof(*(ptr)) _v; \
_v = (typeof(*(ptr)))(value); \
- if (lookup_bad_addr((unsigned long)addr) || \
+ if (lookup_bad_addr((unsigned long)addr, sizeof (*(ptr))) || \
probe_kernel_write((void *)(ptr), (void *)&_v, sizeof(*(ptr)))) \
STORE_DEREF_FAULT(ptr); \
})
@@ -240,7 +240,7 @@ extern void __store_deref_bad(void);
int _bad = 0; \
u8 _b; u16 _w; u32 _l; \
intptr_t _v = 0; \
- if (lookup_bad_addr((unsigned long)addr)) \
+ if (lookup_bad_addr((unsigned long)addr, size)) \
_bad = 1; \
else \
switch (size) \
@@ -258,7 +258,7 @@ extern void __store_deref_bad(void);
#define store_deref(size, addr, value) \
({ \
int _bad = 0; \
- if (lookup_bad_addr((unsigned long)addr)) \
+ if (lookup_bad_addr((unsigned long)addr, size)) \
_bad = 1; \
else \
switch (size) \
@@ -280,7 +280,7 @@ extern void __store_deref_bad(void);
int _bad = 0; \
u8 _b; u16 _w; u32 _l; u64 _q; \
intptr_t _v = 0; \
- if (lookup_bad_addr((unsigned long)addr)) \
+ if (lookup_bad_addr((unsigned long)addr, size)) \
_bad = 1; \
else \
switch (size) \
@@ -299,7 +299,7 @@ extern void __store_deref_bad(void);
#define store_deref(size, addr, value) \
({ \
int _bad = 0; \
- if (lookup_bad_addr((unsigned long)addr)) \
+ if (lookup_bad_addr((unsigned long)addr, size)) \
_bad = 1; \
else \
switch (size) \
@@ -319,7 +319,7 @@ extern void __store_deref_bad(void);
({ \
int _bad = 0; \
intptr_t _v=0; \
- if (lookup_bad_addr((unsigned long)addr)) \
+ if (lookup_bad_addr((unsigned long)addr, size)) \
_bad = 1; \
else \
switch (size){ \
@@ -337,7 +337,7 @@ extern void __store_deref_bad(void);
#define store_deref(size, addr, value) \
({ \
int _bad=0; \
- if (lookup_bad_addr((unsigned long)addr)) \
+ if (lookup_bad_addr((unsigned long)addr, size)) \
_bad = 1; \
else \
switch (size){ \
@@ -397,7 +397,7 @@ extern void __store_deref_bad(void);
({ \
int _bad = 0; \
intptr_t _v = 0; \
- if (lookup_bad_addr((unsigned long)addr)) \
+ if (lookup_bad_addr((unsigned long)addr, size)) \
_bad = 1; \
else \
switch (size) \
@@ -416,7 +416,7 @@ extern void __store_deref_bad(void);
#define store_deref(size, addr, value) \
({ \
int _bad = 0; \
- if (lookup_bad_addr((unsigned long)addr)) \
+ if (lookup_bad_addr((unsigned long)addr, size)) \
_bad = 1; \
else \
switch (size) \
@@ -571,7 +571,7 @@ extern void __store_deref_bad(void);
({ \
int _bad = 0; \
intptr_t _v=0; \
- if (lookup_bad_addr((unsigned long)addr)) \
+ if (lookup_bad_addr((unsigned long)addr, size)) \
_bad = 1; \
else \
switch (size){ \
@@ -588,7 +588,7 @@ extern void __store_deref_bad(void);
#define store_deref(size, addr, value) \
({ \
int _bad=0; \
- if (lookup_bad_addr((unsigned long)addr)) \
+ if (lookup_bad_addr((unsigned long)addr, size)) \
_bad = 1; \
else \
switch (size){ \
@@ -660,7 +660,7 @@ extern void __store_deref_bad(void);
u8 _b; u16 _w; u32 _l; u64 _q; \
int _bad = 0; \
intptr_t _v = 0; \
- if (lookup_bad_addr((unsigned long)addr)) \
+ if (lookup_bad_addr((unsigned long)addr, size)) \
_bad = 1; \
else \
switch (size) { \
@@ -696,7 +696,7 @@ extern void __store_deref_bad(void);
({ \
int _bad = 0; \
int i; \
- if (lookup_bad_addr((unsigned long)addr)) \
+ if (lookup_bad_addr((unsigned long)addr, size)) \
_bad = 1; \
else \
for(i=0;i<size;i++){ \
diff --git a/runtime/staprun/staprun.c b/runtime/staprun/staprun.c
index 7eb7f28f..da3e304b 100644
--- a/runtime/staprun/staprun.c
+++ b/runtime/staprun/staprun.c
@@ -145,19 +145,11 @@ static int enable_uprobes(void)
static int insert_stap_module(void)
{
char special_options[128];
- char *bufptr = special_options;
/* Add the _stp_bufsize option. */
- if (snprintf_chk(bufptr, sizeof (special_options), "_stp_bufsize=%d", buffer_size))
+ if (snprintf_chk(special_options, sizeof (special_options), "_stp_bufsize=%d", buffer_size))
return -1;
- /* 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);
}
diff --git a/runtime/task_finder.c b/runtime/task_finder.c
index ca807020..fb6dc20d 100644
--- a/runtime/task_finder.c
+++ b/runtime/task_finder.c
@@ -753,6 +753,18 @@ __stp_utrace_attach_match_filename(struct task_struct *tsk,
/* Notice that "pid == 0" (which means to probe all
* threads) falls through. */
+#ifndef STP_PRIVILEGED
+ /* Make sure unprivileged users only probe their own threads. */
+ if (_stp_uid != tsk->euid) {
+ if (tgt->pid != 0) {
+ _stp_warn("Process %d does not belong to unprivileged user %d",
+ tsk->pid, _stp_uid);
+ }
+ continue;
+ }
+#endif
+
+
// Set up events we need for attached tasks. When
// register_p is set, we won't actually call the
// callbacks here - we'll call it when the thread gets
@@ -1414,6 +1426,17 @@ stap_start_task_finder(void)
/* Notice that "pid == 0" (which means to
* probe all threads) falls through. */
+#ifndef STP_PRIVILEGED
+ /* Make sure unprivileged users only probe their own threads. */
+ if (_stp_uid != tsk->euid) {
+ if (tgt->pid != 0) {
+ _stp_warn("Process %d does not belong to unprivileged user %d",
+ tsk->pid, _stp_uid);
+ }
+ continue;
+ }
+#endif
+
// Set up events we need for attached tasks.
rc = __stp_utrace_attach(tsk, &tgt->ops, tgt,
__STP_ATTACHED_TASK_EVENTS,
diff --git a/runtime/transport/transport.c b/runtime/transport/transport.c
index ec73f05f..1d029e53 100644
--- a/runtime/transport/transport.c
+++ b/runtime/transport/transport.c
@@ -59,10 +59,6 @@ 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/tapset-utrace.cxx b/tapset-utrace.cxx
index c6214e70..490af20f 100644
--- a/tapset-utrace.cxx
+++ b/tapset-utrace.cxx
@@ -1033,12 +1033,20 @@ register_tapset_utrace(systemtap_session& s)
for (unsigned i = 0; i < roots.size(); ++i)
{
- roots[i]->bind(TOK_BEGIN)->bind(builder);
- roots[i]->bind(TOK_END)->bind(builder);
- roots[i]->bind(TOK_THREAD)->bind(TOK_BEGIN)->bind(builder);
- roots[i]->bind(TOK_THREAD)->bind(TOK_END)->bind(builder);
- roots[i]->bind(TOK_SYSCALL)->bind(builder);
- roots[i]->bind(TOK_SYSCALL)->bind(TOK_RETURN)->bind(builder);
+ roots[i]->bind(TOK_BEGIN)
+ ->allow_unprivileged()
+ ->bind(builder);
+ roots[i]->bind(TOK_END)
+ ->allow_unprivileged()
+ ->bind(builder);
+ roots[i]->bind(TOK_THREAD)->bind(TOK_BEGIN)
+ ->bind(builder);
+ roots[i]->bind(TOK_THREAD)->bind(TOK_END)
+ ->bind(builder);
+ roots[i]->bind(TOK_SYSCALL)
+ ->bind(builder);
+ roots[i]->bind(TOK_SYSCALL)->bind(TOK_RETURN)
+ ->bind(builder);
}
}
diff --git a/tapsets.cxx b/tapsets.cxx
index e0768868..053344cf 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -2525,9 +2525,6 @@ void dwarf_cast_expanding_visitor::filter_special_modules(string& module)
void dwarf_cast_expanding_visitor::visit_cast_op (cast_op* e)
{
- if (s.unprivileged)
- throw semantic_error("typecasting may not be used when --unprivileged is specified", e->tok);
-
bool lvalue = is_active_lvalue(e);
if (lvalue && !s.guru_mode)
throw semantic_error("write to typecast value not permitted", e->tok);
@@ -2633,6 +2630,8 @@ void dwarf_cast_expanding_visitor::visit_cast_op (cast_op* e)
else
ec->code += "/* pure */";
+ ec->code += "/* unprivileged */";
+
s.functions[fdecl->name] = fdecl;
// Synthesize a functioncall.
@@ -3192,7 +3191,7 @@ dwarf_derived_probe_group::emit_module_init (systemtap_session& s)
s.op->newline() << "if (rc) {"; // PR6749: tolerate a failed register_*probe.
s.op->newline(1) << "sdp->registered_p = 0;";
s.op->newline() << "if (!sdp->optional_p)";
- s.op->newline(1) << "_stp_warn (\"probe %s (address 0x%lx) registration error (rc %d)\", probe_point, relocated_addr, rc);";
+ s.op->newline(1) << "_stp_warn (\"probe %s (address 0x%lx) registration error (rc %d)\", probe_point, (unsigned long) relocated_addr, rc);";
s.op->newline(-1) << "rc = 0;"; // continue with other probes
// XXX: shall we increment numskipped?
s.op->newline(-1) << "}";
@@ -3269,7 +3268,7 @@ dwarf_derived_probe_group::emit_module_exit (systemtap_session& s)
s.op->newline() << "atomic_add (kp->u.krp.kp.nmissed, & skipped_count);";
s.op->newline() << "#ifdef STP_TIMING";
s.op->newline() << "if (kp->u.krp.kp.nmissed)";
- s.op->newline(1) << "_stp_warn (\"Skipped due to missed kretprobe/2 on '%s': %d\\n\", sdp->pp, kp->u.krp.kp.nmissed);";
+ s.op->newline(1) << "_stp_warn (\"Skipped due to missed kretprobe/2 on '%s': %lu\\n\", sdp->pp, kp->u.krp.kp.nmissed);";
s.op->newline(-1) << "#endif";
s.op->newline(-1) << "} else {";
s.op->newline() << "#if !defined(STAPCONF_UNREGISTER_KPROBES)";
@@ -3278,7 +3277,7 @@ dwarf_derived_probe_group::emit_module_exit (systemtap_session& s)
s.op->newline() << "atomic_add (kp->u.kp.nmissed, & skipped_count);";
s.op->newline() << "#ifdef STP_TIMING";
s.op->newline() << "if (kp->u.kp.nmissed)";
- s.op->newline(1) << "_stp_warn (\"Skipped due to missed kprobe on '%s': %d\\n\", sdp->pp, kp->u.kp.nmissed);";
+ s.op->newline(1) << "_stp_warn (\"Skipped due to missed kprobe on '%s': %lu\\n\", sdp->pp, kp->u.kp.nmissed);";
s.op->newline(-1) << "#endif";
s.op->newline(-1) << "}";
s.op->newline() << "#if !defined(STAPCONF_UNREGISTER_KPROBES) && defined(__ia64__)";
@@ -5140,7 +5139,7 @@ kprobe_derived_probe_group::emit_module_init (systemtap_session& s)
s.op->newline() << "if (rc) {"; // PR6749: tolerate a failed register_*probe.
s.op->newline(1) << "sdp->registered_p = 0;";
s.op->newline() << "if (!sdp->optional_p)";
- s.op->newline(1) << "_stp_warn (\"probe %s (address 0x%lx) registration error (rc %d)\", probe_point, addr, rc);";
+ s.op->newline(1) << "_stp_warn (\"probe %s (address 0x%lx) registration error (rc %d)\", probe_point, (unsigned long) addr, rc);";
s.op->newline(-1) << "rc = 0;"; // continue with other probes
// XXX: shall we increment numskipped?
s.op->newline(-1) << "}";
@@ -5200,7 +5199,7 @@ kprobe_derived_probe_group::emit_module_exit (systemtap_session& s)
s.op->newline() << "atomic_add (kp->u.krp.kp.nmissed, & skipped_count);";
s.op->newline() << "#ifdef STP_TIMING";
s.op->newline() << "if (kp->u.krp.kp.nmissed)";
- s.op->newline(1) << "_stp_warn (\"Skipped due to missed kretprobe/2 on '%s': %d\\n\", sdp->pp, kp->u.krp.kp.nmissed);";
+ s.op->newline(1) << "_stp_warn (\"Skipped due to missed kretprobe/2 on '%s': %lu\\n\", sdp->pp, kp->u.krp.kp.nmissed);";
s.op->newline(-1) << "#endif";
s.op->newline(-1) << "} else {";
s.op->newline() << "#if !defined(STAPCONF_UNREGISTER_KPROBES)";
@@ -5209,7 +5208,7 @@ kprobe_derived_probe_group::emit_module_exit (systemtap_session& s)
s.op->newline() << "atomic_add (kp->u.kp.nmissed, & skipped_count);";
s.op->newline() << "#ifdef STP_TIMING";
s.op->newline() << "if (kp->u.kp.nmissed)";
- s.op->newline(1) << "_stp_warn (\"Skipped due to missed kprobe on '%s': %d\\n\", sdp->pp, kp->u.kp.nmissed);";
+ s.op->newline(1) << "_stp_warn (\"Skipped due to missed kprobe on '%s': %lu\\n\", sdp->pp, kp->u.kp.nmissed);";
s.op->newline(-1) << "#endif";
s.op->newline(-1) << "}";
s.op->newline() << "#if !defined(STAPCONF_UNREGISTER_KPROBES) && defined(__ia64__)";
diff --git a/testsuite/systemtap.base/cache.exp b/testsuite/systemtap.base/cache.exp
index b9e7ad1b..a70a3cce 100644
--- a/testsuite/systemtap.base/cache.exp
+++ b/testsuite/systemtap.base/cache.exp
@@ -93,11 +93,6 @@ cache_compile OPTION2 [F_CACHED_COMPILE] $basic_script1 -DFOO=1
cache_compile BULK1 [F_UNCACHED_COMPILE] $basic_script1 -b
cache_compile BULK2 [F_CACHED_COMPILE] $basic_script1 -b
-# Using '-M' (don't merge per-cpu files for bulk mode) should change
-# the hash
-cache_compile MERGE1 [F_UNCACHED_COMPILE] $basic_script1 -b -M
-cache_compile MERGE2 [F_CACHED_COMPILE] $basic_script1 -b -M
-
# Using '-t' (benchmark timing) should change the hash
cache_compile TIMING1 [F_UNCACHED_COMPILE] $basic_script1 -t
cache_compile TIMING2 [F_CACHED_COMPILE] $basic_script1 -t
diff --git a/translate.cxx b/translate.cxx
index ffe6d489..9a25df61 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -5210,6 +5210,8 @@ translate_pass (systemtap_session& s)
if (ri.recursive) nesting += 10;
// This is at the very top of the file.
+ if (! s.unprivileged)
+ s.op->newline() << "#define STP_PRIVILEGED 1";
s.op->newline() << "#ifndef MAXNESTING";
s.op->newline() << "#define MAXNESTING " << nesting;
s.op->newline() << "#endif";