diff options
author | Josh Stone <jistone@redhat.com> | 2009-09-03 14:31:02 -0700 |
---|---|---|
committer | Josh Stone <jistone@redhat.com> | 2009-09-03 14:31:02 -0700 |
commit | 06e0b6262393b095a33e9cc6e7ab7bc5d4fe9c95 (patch) | |
tree | 8029267099eec7bd898e6532bf6152c8b946f8ba | |
parent | b969d16b2986a491eb37706e09da888d9914a7dd (diff) | |
parent | d0822e28934cd0387c2af4349cf52c52c368c55a (diff) | |
download | systemtap-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.c | 45 | ||||
-rw-r--r-- | runtime/loc2c-runtime.h | 28 | ||||
-rw-r--r-- | runtime/staprun/staprun.c | 10 | ||||
-rw-r--r-- | runtime/task_finder.c | 23 | ||||
-rw-r--r-- | runtime/transport/transport.c | 4 | ||||
-rw-r--r-- | tapset-utrace.cxx | 20 | ||||
-rw-r--r-- | tapsets.cxx | 17 | ||||
-rw-r--r-- | testsuite/systemtap.base/cache.exp | 5 | ||||
-rw-r--r-- | translate.cxx | 2 |
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"; |