diff options
Diffstat (limited to 'tapset')
-rw-r--r-- | tapset/DEVGUIDE | 17 | ||||
-rw-r--r-- | tapset/context-symbols.stp | 6 | ||||
-rw-r--r-- | tapset/context-unwind.stp | 15 | ||||
-rw-r--r-- | tapset/context.stp | 79 | ||||
-rw-r--r-- | tapset/conversions.stp | 50 | ||||
-rw-r--r-- | tapset/networking.stp | 175 | ||||
-rw-r--r-- | tapset/signal.stp | 4 | ||||
-rw-r--r-- | tapset/socket.stp | 2 | ||||
-rw-r--r-- | tapset/string.stp | 20 | ||||
-rw-r--r-- | tapset/timestamp_gtod.stp | 2 | ||||
-rw-r--r-- | tapset/ucontext-symbols.stp | 12 | ||||
-rw-r--r-- | tapset/ucontext-unwind.stp | 6 | ||||
-rw-r--r-- | tapset/utrace.stp | 27 |
13 files changed, 331 insertions, 84 deletions
diff --git a/tapset/DEVGUIDE b/tapset/DEVGUIDE index 693521a8..5d7c8658 100644 --- a/tapset/DEVGUIDE +++ b/tapset/DEVGUIDE @@ -244,6 +244,23 @@ potentially be invalid. If you're not sure, err on the side of caution. The cost of using kread() is small compared to the cost of your tapset inadvertently crashing a system! +Add the string + /* pure */ +into the body of the embedded-C function if it has no side-effects +such as changing external state, so that systemtap could elide +(optimize away) a call to the function if its results are unused. + +Add the string + /* unprivileged */ +into the body of the embedded-C function, only if it is safe for use +by unprivileged users. In general, this requires the function to be +absolutely robust with respect to its inputs, and expose/modify no +information except that belonging to the user's own processes. +(The assert_is_myproc() macro may help enforce this.) Roughly +speaking, it should only perform operations that the same user +could already do from ordinary userspace interfaces. + + Review & Submission ------------------- All new tapsets and major changes should be reviewed "early and often" diff --git a/tapset/context-symbols.stp b/tapset/context-symbols.stp index e4406d9b..3ec7a866 100644 --- a/tapset/context-symbols.stp +++ b/tapset/context-symbols.stp @@ -8,7 +8,7 @@ // later version. // <tapsetdescription> // Context functions provide additional information about where an event occurred. These functions can -//provide information such as a backtrace to where the event occured and the current register values for the +//provide information such as a backtrace to where the event occurred and the current register values for the //processor. // </tapsetdescription> %{ @@ -19,7 +19,7 @@ /** * sfunction print_stack - Print out stack from string. - * @stk: String with list of hexidecimal addresses. + * @stk: String with list of hexadecimal addresses. * * Perform a symbolic lookup of the addresses in the given string, * which is assumed to be the result of a prior call to @@ -138,7 +138,7 @@ function symname:string (addr: long) %{ /* pure */ * Description: Returns the (function) symbol name associated with the * given address if known, plus the module name (between brackets) and * the offset inside the module, plus the size of the symbol function. - * If any element is not known it will be ommitted and if the symbol name + * If any element is not known it will be omitted and if the symbol name * is unknown it will return the hex string for the given address. */ function symdata:string (addr: long) %{ /* pure */ diff --git a/tapset/context-unwind.stp b/tapset/context-unwind.stp index d6654d25..33431fd0 100644 --- a/tapset/context-unwind.stp +++ b/tapset/context-unwind.stp @@ -8,7 +8,7 @@ // later version. // <tapsetdescription> // Context functions provide additional information about where an event occurred. These functions can -//provide information such as a backtrace to where the event occured and the current register values for the +//provide information such as a backtrace to where the event occurred and the current register values for the //processor. // </tapsetdescription> %{ @@ -48,6 +48,19 @@ function backtrace:string () %{ /* pure */ %} /** + * sfunction task_backtrace - Hex backtrace of an arbitrary task + * @task: pointer to task_struct + * + * Return a string of hex addresses that are a backtrace of the + * stack of a particular task. Output may be truncated as per + * maximum string length. + */ +function task_backtrace:string (task:long) %{ /* pure */ + _stp_stack_snprint_tsk(THIS->__retvalue, MAXSTRINGLEN, + (struct task_struct *)(unsigned long)THIS->task, 0, MAXTRACE); +%} + +/** * sfunction caller - Return name and address of calling function * * Return the address and name of the calling function. diff --git a/tapset/context.stp b/tapset/context.stp index 5be9f21f..226e3ee5 100644 --- a/tapset/context.stp +++ b/tapset/context.stp @@ -7,8 +7,8 @@ // Public License (GPL); either version 2, or (at your option) any // later version. // <tapsetdescription> -// Context functions provide additional information about where an event occurred. These functions can -//provide information such as a backtrace to where the event occured and the current register values for the +// Context functions provide additional information about where an event occurred. These functions can +//provide information such as a backtrace to where the event occurred and the current register values for the //processor. // </tapsetdescription> @@ -34,28 +34,28 @@ function print_regs () %{ /** * sfunction execname - Returns the execname of a target process (or group of processes). */ -function execname:string () %{ /* pure */ +function execname:string () %{ /* pure */ /* unprivileged */ strlcpy (THIS->__retvalue, current->comm, MAXSTRINGLEN); %} /** * sfunction pid - Returns the ID of a target process. */ -function pid:long () %{ /* pure */ +function pid:long () %{ /* pure */ /* unprivileged */ THIS->__retvalue = current->tgid; %} /** * sfunction tid - Returns the thread ID of a target process. */ -function tid:long () %{ /* pure */ +function tid:long () %{ /* pure */ /* unprivileged */ THIS->__retvalue = current->pid; %} /** * sfunction ppid - Returns the process ID of a target process's parent process. */ -function ppid:long () %{ /* pure */ +function ppid:long () %{ /* pure */ /* unprivileged */ #if defined(STAPCONF_REAL_PARENT) THIS->__retvalue = current->real_parent->tgid; #else @@ -66,7 +66,7 @@ function ppid:long () %{ /* pure */ /** * sfunction pgrp - Returns the process group ID of the current process. */ -function pgrp:long () %{ /* pure */ +function pgrp:long () %{ /* pure */ /* unprivileged */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) struct signal_struct *ss = kread( &(current->signal) ); THIS->__retvalue = kread ( &(ss->pgrp) ); @@ -78,11 +78,11 @@ function pgrp:long () %{ /* pure */ /** * sfunction sid - Returns the session ID of the current process. - * + * * The session ID of a process is the process group ID of the session * leader. Session ID is stored in the signal_struct since Kernel 2.6.0. */ -function sid:long () %{ /* pure */ +function sid:long () %{ /* pure */ /* unprivileged */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) struct signal_struct *ss = kread( &(current->signal) ); THIS->__retvalue = kread ( &(ss->session) ); @@ -95,7 +95,7 @@ function sid:long () %{ /* pure */ /** * sfunction pexecname - Returns the execname of a target process's parent process. */ -function pexecname:string () %{ /* pure */ +function pexecname:string () %{ /* pure */ /* unprivileged */ #if defined(STAPCONF_REAL_PARENT) strlcpy (THIS->__retvalue, current->real_parent->comm, MAXSTRINGLEN); #else @@ -106,47 +106,59 @@ function pexecname:string () %{ /* pure */ /** * sfunction gid - Returns the group ID of a target process. */ -function gid:long () %{ /* pure */ +function gid:long () %{ /* pure */ /* unprivileged */ #ifdef STAPCONF_TASK_UID - THIS->__retvalue = current->gid; + THIS->__retvalue = current->gid; #else - THIS->__retvalue = current_gid(); + THIS->__retvalue = current_gid(); #endif %} /** * sfunction egid - Returns the effective gid of a target process. */ -function egid:long () %{ /* pure */ +function egid:long () %{ /* pure */ /* unprivileged */ #ifdef STAPCONF_TASK_UID - THIS->__retvalue = current->egid; + THIS->__retvalue = current->egid; #else - THIS->__retvalue = current_egid(); + THIS->__retvalue = current_egid(); #endif %} /** * sfunction uid - Returns the user ID of a target process. */ -function uid:long () %{ /* pure */ +function uid:long () %{ /* pure */ /* unprivileged */ #ifdef STAPCONF_TASK_UID - THIS->__retvalue = current->uid; + THIS->__retvalue = current->uid; #else - THIS->__retvalue = current_uid(); + THIS->__retvalue = current_uid(); #endif %} /** * sfunction euid - Return the effective uid of a target process. */ -function euid:long () %{ /* pure */ +function euid:long () %{ /* pure */ /* unprivileged */ #ifdef STAPCONF_TASK_UID - THIS->__retvalue = current->euid; + THIS->__retvalue = current->euid; #else - THIS->__retvalue = current_euid(); + THIS->__retvalue = current_euid(); #endif %} + +/** + * sfunction is_myproc - Determines if the current probe point has occurred in the user's own process. + * + * Return 1 if the current probe point has occurred in the user's own process. + */ +function is_myproc:long () %{ /* pure */ /* unprivileged */ + THIS->__retvalue = is_myproc(); +%} + + + // cpuid() is not documented function cpuid:long () %{ /* pure */ THIS->__retvalue = smp_processor_id(); @@ -155,7 +167,7 @@ function cpuid:long () %{ /* pure */ /** * sfunction cpu - Returns the current cpu number. */ -function cpu:long () %{ /* pure */ +function cpu:long () %{ /* pure */ /* unprivileged */ THIS->__retvalue = smp_processor_id(); %} @@ -163,9 +175,9 @@ function cpu:long () %{ /* pure */ * sfunction pp - Return the probe point associated with the currently running probe handler, * including alias and wildcard expansion effects * Context: - * The current probe point. + * The current probe point. */ -function pp:string () %{ /* pure */ +function pp:string () %{ /* pure */ /* unprivileged */ strlcpy (THIS->__retvalue, CONTEXT->probe_point, MAXSTRINGLEN); %} @@ -177,7 +189,7 @@ function pp:string () %{ /* pure */ * For example, <command>registers_valid()</command> returns 0 * when called from a begin or end probe. */ -function registers_valid:long () %{ /* pure */ +function registers_valid:long () %{ /* pure */ /* unprivileged */ THIS->__retvalue = (CONTEXT->regs != NULL); %} @@ -186,7 +198,7 @@ function registers_valid:long () %{ /* pure */ * * Return 1 if the probe point occurred in user-mode. */ -function user_mode:long () %{ /* pure */ /* currently a user-mode address? */ +function user_mode:long () %{ /* pure */ /* unprivileged */ if (CONTEXT->regs) { #if defined(__i386__) || defined(__x86_64__) THIS->__retvalue = (uint64_t) user_mode_vm (CONTEXT->regs); @@ -207,14 +219,14 @@ function user_mode:long () %{ /* pure */ /* currently a user-mode address? */ function is_return:long () %{ /* pure */ if (CONTEXT->pi) THIS->__retvalue = 1; - else - THIS->__retvalue = 0; + else + THIS->__retvalue = 0; %} /** * sfunction target - Return the process ID of the target process. */ -function target:long () %{ /* pure */ +function target:long () %{ /* pure */ /* unprivileged */ THIS->__retvalue = _stp_target; %} @@ -225,7 +237,7 @@ function target:long () %{ /* pure */ /// <remark>FIXME: need description.</remark> /// </para> ///</formalpara> -function module_name:string () %{ /* pure */ +function module_name:string () %{ /* pure */ /* unprivileged */ strlcpy(THIS->__retvalue, THIS_MODULE->name, MAXSTRINGLEN); %} @@ -271,14 +283,15 @@ function stack_unused:long () %{ /* pure */ * sfunction uaddr - User space address of current running task. EXPERIMENTAL. * * Description: Returns the address in userspace that the current - * task was at when the probe occured. When the current running task + * task was at when the probe occurred. When the current running task * isn't a user space thread, or the address cannot be found, zero * is returned. Can be used to see where the current task is combined * with usymname() or symdata(). Often the task will be in the VDSO * where it entered the kernel. FIXME - need VDSO tracking support #10080. */ -function uaddr:long () %{ /* pure */ +function uaddr:long () %{ /* pure */ /* unprivileged */ int64_t addr = 0; + assert_is_myproc(); if (current->mm) { struct pt_regs *uregs; diff --git a/tapset/conversions.stp b/tapset/conversions.stp index fdf00bd3..a218025b 100644 --- a/tapset/conversions.stp +++ b/tapset/conversions.stp @@ -1,5 +1,5 @@ // conversions tapset -// Copyright (C) 2005-2008 Red Hat Inc. +// Copyright (C) 2005-2009 Red Hat Inc. // Copyright (C) 2007 Intel Corporation. // // This file is part of systemtap, and is free software. You can @@ -79,15 +79,18 @@ deref_fault: /* branched to from kread() */ function user_string:string (addr:long) { return user_string2 (addr, "<unknown>") } -function user_string2:string (addr:long, err_msg:string) %{ /* pure */ +function user_string2:string (addr:long, err_msg:string) %{ /* pure */ /* unprivileged */ + assert_is_myproc(); if (_stp_strncpy_from_user (THIS->__retvalue, (const char __user*) (uintptr_t) THIS->addr, MAXSTRINGLEN) < 0) strlcpy (THIS->__retvalue, THIS->err_msg, MAXSTRINGLEN); %} -function user_string_warn:string (addr:long) %{ /* pure */ - long rc = _stp_strncpy_from_user (THIS->__retvalue, +function user_string_warn:string (addr:long) %{ /* pure */ /* unprivileged */ + long rc; + assert_is_myproc(); + rc = _stp_strncpy_from_user (THIS->__retvalue, (const char __user*) (uintptr_t) THIS->addr, MAXSTRINGLEN); if (rc < 0) { // NB: using error_buffer to get local space for the warning, but we're @@ -100,7 +103,8 @@ function user_string_warn:string (addr:long) %{ /* pure */ } %} -function user_string_quoted:string (addr:long) %{ /* pure */ +function user_string_quoted:string (addr:long) %{ /* pure */ /* unprivileged */ + assert_is_myproc(); if (THIS->addr == 0) strlcpy (THIS->__retvalue, "NULL", MAXSTRINGLEN); else @@ -113,8 +117,9 @@ function user_string_n:string (addr:long, n:long) { return user_string_n2(addr, n, "<unknown>") } -function user_string_n2:string (addr:long, n:long, err_msg:string) %{ /* pure */ +function user_string_n2:string (addr:long, n:long, err_msg:string) %{ /* pure */ /* unprivileged */ long len = THIS->n + 1; + assert_is_myproc(); len = (len > MAXSTRINGLEN) ? MAXSTRINGLEN : len; if (_stp_strncpy_from_user(THIS->__retvalue, (char __user *) (uintptr_t) THIS->addr, @@ -124,10 +129,11 @@ function user_string_n2:string (addr:long, n:long, err_msg:string) %{ /* pure */ THIS->__retvalue[len - 1] = '\0'; %} -function user_string_n_warn:string (addr:long, n:long) %{ /* pure */ +function user_string_n_warn:string (addr:long, n:long) %{ /* pure */ /* unprivileged */ long len = THIS->n + 1; long rc; + assert_is_myproc(); len = (len > MAXSTRINGLEN) ? MAXSTRINGLEN : len; rc = _stp_strncpy_from_user(THIS->__retvalue, (char __user *) (uintptr_t) THIS->addr, len); @@ -143,8 +149,10 @@ function user_string_n_warn:string (addr:long, n:long) %{ /* pure */ THIS->__retvalue[len - 1] = '\0'; %} -function user_string_n_quoted:string (addr:long, n:long) %{ /* pure */ - long len = THIS->n + 1; +function user_string_n_quoted:string (addr:long, n:long) %{ /* pure */ /* unprivileged */ + long len; + assert_is_myproc(); + len = THIS->n + 1; if (THIS->addr == 0) strlcpy(THIS->__retvalue, "NULL", MAXSTRINGLEN); else @@ -155,7 +163,8 @@ function user_string_n_quoted:string (addr:long, n:long) %{ /* pure */ // When userspace data is not accessible, the following functions return 0 -function user_short:long (addr:long) %{ /* pure */ +function user_short:long (addr:long) %{ /* pure */ /* unprivileged */ + assert_is_myproc(); if (!access_ok(VERIFY_READ, (short *) (intptr_t) THIS->addr, sizeof(short))) goto fault; if (__stp_get_user(THIS->__retvalue, (short *) (intptr_t) THIS->addr)) { @@ -164,7 +173,8 @@ fault: } %} -function user_short_warn:long (addr:long) %{ /* pure */ +function user_short_warn:long (addr:long) %{ /* pure */ /* unprivileged */ + assert_is_myproc(); if (!access_ok(VERIFY_READ, (short *) (intptr_t) THIS->addr, sizeof(short))) goto fault; if (__stp_get_user(THIS->__retvalue, (short *) (intptr_t) THIS->addr)) { @@ -176,7 +186,8 @@ fault: } %} -function user_int:long (addr:long) %{ /* pure */ +function user_int:long (addr:long) %{ /* pure */ /* unprivileged */ + assert_is_myproc(); if (!access_ok(VERIFY_READ, (int *) (intptr_t) THIS->addr, sizeof(int))) goto fault; if (__stp_get_user(THIS->__retvalue, (int *) (intptr_t) THIS->addr)) { @@ -185,7 +196,8 @@ fault: } %} -function user_int_warn:long (addr:long) %{ /* pure */ +function user_int_warn:long (addr:long) %{ /* pure */ /* unprivileged */ + assert_is_myproc(); if (!access_ok(VERIFY_READ, (int *) (intptr_t) THIS->addr, sizeof(int))) goto fault; if (__stp_get_user(THIS->__retvalue, (int *) (intptr_t) THIS->addr)) { @@ -197,7 +209,8 @@ fault: } %} -function user_long:long (addr:long) %{ /* pure */ +function user_long:long (addr:long) %{ /* pure */ /* unprivileged */ + assert_is_myproc(); if (!access_ok(VERIFY_READ, (long *) (intptr_t) THIS->addr, sizeof(long))) goto fault; if (__stp_get_user(THIS->__retvalue, (long *) (intptr_t) THIS->addr)) { @@ -206,7 +219,8 @@ fault: } %} -function user_long_warn:long (addr:long) %{ /* pure */ +function user_long_warn:long (addr:long) %{ /* pure */ /* unprivileged */ + assert_is_myproc(); if (!access_ok(VERIFY_READ, (long *) (intptr_t) THIS->addr, sizeof(long))) goto fault; if (__stp_get_user(THIS->__retvalue, (long *) (intptr_t) THIS->addr)) { @@ -218,7 +232,8 @@ fault: } %} -function user_char:long (addr:long) %{ /* pure */ +function user_char:long (addr:long) %{ /* pure */ /* unprivileged */ + assert_is_myproc(); if (!access_ok(VERIFY_READ, (char *) (intptr_t) THIS->addr, sizeof(char))) goto fault; if (__stp_get_user(THIS->__retvalue, (char *) (intptr_t) THIS->addr)) { @@ -227,7 +242,8 @@ fault: } %} -function user_char_warn:long (addr:long) %{ /* pure */ +function user_char_warn:long (addr:long) %{ /* pure */ /* unprivileged */ + assert_is_myproc(); if (!access_ok(VERIFY_READ, (char *) (intptr_t) THIS->addr, sizeof(char))) goto fault; if (__stp_get_user(THIS->__retvalue, (char *) (intptr_t) THIS->addr)) { diff --git a/tapset/networking.stp b/tapset/networking.stp index f6d78536..4732a72d 100644 --- a/tapset/networking.stp +++ b/tapset/networking.stp @@ -8,11 +8,17 @@ // <tapsetdescription> // This family of probe points is used to probe the activities of the network device. // </tapsetdescription> + +/* A function that returns the device name given the net_device struct */ +function get_netdev_name:string (addr:long) { + return kernel_string(@cast(addr, "net_device")->name) +} + /** - * probe netdev.receive - Data recieved from network device. + * probe netdev.receive - Data received from network device. * @dev_name: The name of the device. e.g: eth0, ath1. * @length: The length of the receiving buffer. - * @protocol: Protocol of recieved packet. + * @protocol: Protocol of received packet. * */ /// <varlistentry><term>protocol</term> @@ -66,7 +72,7 @@ probe netdev.receive * @dev_name: The name of the device. e.g: eth0, ath1. * @length: The length of the transmit buffer. * @protocol: The protocol of this packet. - * @truesize: The size of the the data to be transmitted. + * @truesize: The size of the data to be transmitted. * */ // Queue a buffer for transmission to a network device @@ -78,3 +84,166 @@ probe netdev.transmit protocol = $skb->protocol truesize = $skb->truesize } + +/** + * probe netdev.change_mtu - Called when the netdev MTU is changed + * @dev_name: The device that will have the MTU changed + * @old_mtu: The current MTU + * @new_mtu: The new MTU + */ +probe netdev.change_mtu + = kernel.function("dev_set_mtu") +{ + old_mtu = $dev->mtu + new_mtu = $new_mtu + dev_name = get_netdev_name($dev) +} + +/** + * probe netdev.open - Called when the device is opened + * @dev_name: The device that is going to be opened + */ +probe netdev.open + = kernel.function("dev_open") +{ + dev_name = get_netdev_name($dev) +} + +/** + * probe netdev.close - Called when the device is closed + * @dev_name: The device that is going to be closed + */ +probe netdev.close + = kernel.function("dev_close") +{ + dev_name = get_netdev_name($dev) +} + +/** + * probe netdev.hard_transmit - Called when the devices is going to TX (hard) + * @dev_name: The device scheduled to transmit + * @protocol: The protocol used in the transmission + * @length: The length of the transmit buffer. + * @truesize: The size of the data to be transmitted. + */ +probe netdev.hard_transmit + = kernel.function("dev_hard_start_xmit") +{ + dev_name = get_netdev_name($dev) + protocol = $skb->protocol + length = $skb->len + truesize = $skb->truesize +} + +/** + * probe netdev.rx - Called when the device is going to receive a packet + * @dev_name: The device received the packet + * @protocol: The packet protocol + */ +probe netdev.rx + = kernel.function("netif_rx") +{ + netdev = $skb->dev + dev_name = get_netdev_name(netdev) + protocol = $skb->protocol +} + +/** + * probe netdev.change_rx_flag - Called when the device RX flag will be changed + * @dev_name: The device that will be changed + * @flags: The new flags + */ +probe netdev.change_rx_flag + = kernel.function("dev_change_rx_flags") +{ + dev_name = get_netdev_name($dev) + flags = $flags +} + +/** + * probe netdev.set_promiscuity - Called when the device enters/leaves promiscuity + * @dev_name: The device that is entering/leaving promiscuity mode + * @enable: If the device is entering promiscuity mode + * @disable: If the device is leaving promiscuity mode + * @inc: Count the number of promiscuity openers + */ +probe netdev.set_promiscuity + = kernel.function("dev_set_promiscuity") +{ + dev_name = get_netdev_name($dev) + if ($inc){ + enable = 1 + } else { + disable = 1 + } + inc = $inc +} + +/** + * probe netdev.ioctl - Called when the device suffers an IOCTL + * @cmd: The IOCTL request + * @arg: The IOCTL argument (usually the netdev interface) + */ +probe netdev.ioctl + = kernel.function("dev_ioctl") +{ + cmd = $cmd + arg = user_string($arg) +} + +/** + * probe netdev.register - Called when the device is registered + * @dev_name: The device that is going to be registered + */ +probe netdev.register + = kernel.function("register_netdevice"), + kernel.function("register_netdev") +{ + dev_name = get_netdev_name($dev) +} + +/** + * probe netdev.unregister - Called when the device is being unregistered + * @dev_name: The device that is going to be unregistered + */ +probe netdev.unregister + = kernel.function("unregister_netdev") +{ + dev_name = get_netdev_name($dev) +} + +/** + * probe netdev.get_stats - Called when someone asks the device statistics + * @dev_name: The device that is going to provide the statistics + */ +probe netdev.get_stats + = kernel.function("dev_get_stats") +{ + dev_name = get_netdev_name($dev) +} + +/** + * probe netdev.change_mac - Called when the netdev_name has the MAC changed + * @dev_name: The device that will have the MTU changed + * @mac_len: The MAC length + * @old_mac: The current MAC address + * @new_mac: The new MAC address + */ +probe netdev.change_mac + = kernel.function("dev_set_mac_address") +{ + dev_name = get_netdev_name($dev) + mac_len = $dev->addr_len + + // Old MAC Address + old_mac = sprintf("%02x:%02x:%02x:%02x:%02x:%02x", + $dev->dev_addr[0], $dev->dev_addr[1], + $dev->dev_addr[2], $dev->dev_addr[3], + $dev->dev_addr[4], $dev->dev_addr[5]) + + // New MAC Address + new_mac = sprintf("%02x:%02x:%02x:%02x:%02x:%02x", + $sa->sa_data[0], $sa->sa_data[1], + $sa->sa_data[2], $sa->sa_data[3], + $sa->sa_data[4], $sa->sa_data[5]) +} diff --git a/tapset/signal.stp b/tapset/signal.stp index 02c761c3..2e10af0c 100644 --- a/tapset/signal.stp +++ b/tapset/signal.stp @@ -414,7 +414,7 @@ probe signal.syskill.return = syscall.kill.return * * The <command>tkill</command> call is analogous to <command>kill(2)</command>, * except that it also allows a process within a specific thread group to - * be targetted. Such processes are targetted through their unique + * be targeted. Such processes are targeted through their unique * thread IDs (TID). */ probe signal.systkill = syscall.tkill @@ -632,7 +632,7 @@ probe signal.procmask.return = kernel.function("sigprocmask").return /** - * probe signal.flush - Flusing all pending signals for a task + * probe signal.flush - Flushing all pending signals for a task * @task: The task handler of the process performing the flush * @sig_pid: The PID of the process associated with the task * performing the flush diff --git a/tapset/socket.stp b/tapset/socket.stp index de778d7c..b4d4981c 100644 --- a/tapset/socket.stp +++ b/tapset/socket.stp @@ -81,7 +81,7 @@ probe socket.receive = socket.recvmsg.return, * The message sender * * Fires at the beginning of sending a message on a socket - * via the the sock_sendmsg() function + * via the sock_sendmsg() function */ probe socket.sendmsg = kernel.function ("sock_sendmsg") { diff --git a/tapset/string.stp b/tapset/string.stp index 4b0a2a0d..92750b6b 100644 --- a/tapset/string.stp +++ b/tapset/string.stp @@ -8,7 +8,7 @@ * @param s string * @return Returns the length of the string. */ -function strlen:long(s:string) %{ /* pure */ +function strlen:long(s:string) %{ /* pure */ /* unprivileged */ THIS->__retvalue = strlen(THIS->s); %} @@ -19,7 +19,7 @@ function strlen:long(s:string) %{ /* pure */ * @param length Length of string to return. * @return Returns the substring. */ -function substr:string(str:string,start:long, length:long) %{ /* pure */ +function substr:string(str:string,start:long, length:long) %{ /* pure */ /* unprivileged */ int length = THIS->length >= MAXSTRINGLEN ? MAXSTRINGLEN : THIS->length + 1; if (THIS->start >= 0 && length > 0 && THIS->start < strlen(THIS->str)) strlcpy(THIS->__retvalue, THIS->str + THIS->start, length); @@ -31,7 +31,7 @@ function substr:string(str:string,start:long, length:long) %{ /* pure */ * @param pos the given position. 0 = start of the string * @return Returns the char in given position of string. */ -function stringat:long(str:string, pos:long) %{ /* pure */ +function stringat:long(str:string, pos:long) %{ /* pure */ /* unprivileged */ if (THIS->pos >= 0 && THIS->pos < strlen(THIS->str)) THIS->__retvalue = THIS->str[THIS->pos]; else @@ -44,7 +44,7 @@ function stringat:long(str:string, pos:long) %{ /* pure */ * @param s2 string * @return Returns 1 if s2 is in s1. Otherwise 0. */ -function isinstr:long(s1:string,s2:string) %{ /* pure */ +function isinstr:long(s1:string,s2:string) %{ /* pure */ /* unprivileged */ if (strstr(THIS->s1,THIS->s2) != NULL) THIS->__retvalue = 1; else @@ -58,13 +58,13 @@ function isinstr:long(s1:string,s2:string) %{ /* pure */ * replaced by the corresponding escape sequence in the returned * string. */ -function text_str:string(input:string) -%{ /* pure */ +function text_str:string(input:string) +%{ /* pure */ /* unprivileged */ _stp_text_str(THIS->__retvalue, THIS->input, 0, 0, 0); %} function text_strn:string(input:string, len:long, quoted:long) -%{ /* pure */ +%{ /* pure */ /* unprivileged */ _stp_text_str(THIS->__retvalue, THIS->input, THIS->len, THIS->quoted, 0); %} @@ -77,7 +77,7 @@ function text_strn:string(input:string, len:long, quoted:long) * delim Token delimiter. Set of characters that delimit the tokens. */ function tokenize:string(input:string, delim:string) -%{ /* pure */ +%{ /* unprivileged */ static char str[MAXSTRINGLEN]; static char *str_start; static char *str_end; @@ -106,7 +106,7 @@ function tokenize:string(input:string, delim:string) * @return Returns the parent string with substrings replaced. Else returns parent string. */ function str_replace:string (prnt_str:string, srch_str:string, rplc_str:string) -%{ +%{ /* pure */ /* unprivileged */ char *ptr = THIS->prnt_str; char *ptr_base = THIS->prnt_str; int strlen_srch_str = strlen(THIS->srch_str); @@ -135,7 +135,7 @@ function str_replace:string (prnt_str:string, srch_str:string, rplc_str:string) * base The base to use */ function strtol:long(str:string, base:long) -%{ /* pure */ +%{ /* pure */ /* unprivileged */ THIS->__retvalue = simple_strtol(THIS->str, NULL, THIS->base); %} diff --git a/tapset/timestamp_gtod.stp b/tapset/timestamp_gtod.stp index b916a3b1..acf525f0 100644 --- a/tapset/timestamp_gtod.stp +++ b/tapset/timestamp_gtod.stp @@ -17,7 +17,7 @@ * * Return the number of nanoseconds since the UNIX epoch. */ -function gettimeofday_ns:long () %{ /* pure */ +function gettimeofday_ns:long () %{ /* pure */ /* unprivileged */ /* NOTE: we can't use do_gettimeofday because we could be called from a * context where xtime_lock is already held. See bug #2525. */ THIS->__retvalue = _stp_gettimeofday_ns(); diff --git a/tapset/ucontext-symbols.stp b/tapset/ucontext-symbols.stp index 5502f5cd..e884a36b 100644 --- a/tapset/ucontext-symbols.stp +++ b/tapset/ucontext-symbols.stp @@ -9,7 +9,7 @@ // <tapsetdescription> // User context symbol functions provide additional information about // addresses from an application. These functions can provide -// information about the user space map (library) that the event occured or +// information about the user space map (library) that the event occurred or // the function symbol of an address. // </tapsetdescription> @@ -43,17 +43,18 @@ function usymname:string (addr: long) %{ /* pure */ * given address in the current task if known, plus the module name * (between brackets) and the offset inside the module (shared library), * plus the size of the symbol function. If any element is not known it - * will be ommitted and if the symbol name is unknown it will return the + * will be omitted and if the symbol name is unknown it will return the * hex string for the given address. */ -function usymdata:string (addr: long) %{ /* pure */ +function usymdata:string (addr: long) %{ /* pure */ /* unprivileged */ + assert_is_myproc(); _stp_symbol_snprint(THIS->__retvalue, MAXSTRINGLEN, THIS->addr, current, 1); %} /** * sfunction print_ustack - Print out stack for the current task from string. EXPERIMENTAL! - * @stk: String with list of hexidecimal addresses for the current task. + * @stk: String with list of hexadecimal addresses for the current task. * * Perform a symbolic lookup of the addresses in the given string, * which is assumed to be the result of a prior call to @@ -63,9 +64,10 @@ function usymdata:string (addr: long) %{ /* pure */ * name of the function containing the address, and an estimate of * its position within that function. Return nothing. */ -function print_ustack(stk:string) %{ +function print_ustack(stk:string) %{ /* pure */ /* unprivileged */ char *ptr = THIS->stk; char *tok = strsep(&ptr, " "); + assert_is_myproc(); while (tok && *tok) { _stp_print_char(' '); _stp_usymbol_print (simple_strtol(tok, NULL, 16), current); diff --git a/tapset/ucontext-unwind.stp b/tapset/ucontext-unwind.stp index df275d4b..e1a8ade3 100644 --- a/tapset/ucontext-unwind.stp +++ b/tapset/ucontext-unwind.stp @@ -24,7 +24,8 @@ * Equivalent to <command>print_ustack(ubacktrace())</command>, * except that deeper stack nesting may be supported. Return nothing. */ -function print_ubacktrace () %{ +function print_ubacktrace () %{ /* unprivileged */ + assert_is_myproc(); if (CONTEXT->regs) { _stp_stack_print(CONTEXT->regs, 1, CONTEXT->pi, MAXTRACE, current); @@ -41,7 +42,8 @@ function print_ubacktrace () %{ * string length. Returns empty string when current probe point cannot * determine user backtrace. */ -function ubacktrace:string () %{ /* pure */ +function ubacktrace:string () %{ /* pure */ /* unprivileged */ + assert_is_myproc(); if (CONTEXT->regs) _stp_stack_snprint (THIS->__retvalue, MAXSTRINGLEN, CONTEXT->regs, 0, CONTEXT->pi, MAXTRACE, diff --git a/tapset/utrace.stp b/tapset/utrace.stp index 0d26ed5f..4f841b30 100644 --- a/tapset/utrace.stp +++ b/tapset/utrace.stp @@ -4,23 +4,38 @@ #include "syscall.h" %} -function _utrace_syscall_nr:long () %{ /* pure */ - THIS->__retvalue = syscall_get_nr(current, CONTEXT->regs); +function _utrace_syscall_nr:long () %{ /* pure */ /* unprivileged */ + assert_is_myproc(); + if (! CONTEXT->regs) { + CONTEXT->last_error = "invalid call without context registers"; + } else { + THIS->__retvalue = syscall_get_nr(current, CONTEXT->regs); + } %} -function _utrace_syscall_arg:long (n:long) %{ /* pure */ +function _utrace_syscall_arg:long (n:long) %{ /* pure */ /* unprivileged */ unsigned long arg = 0; - syscall_get_arguments(current, CONTEXT->regs, (int)THIS->n, 1, &arg); + assert_is_myproc(); + if (! CONTEXT->regs) { + CONTEXT->last_error = "invalid call without context registers"; + } else { + syscall_get_arguments(current, CONTEXT->regs, (int)THIS->n, 1, &arg); + } THIS->__retvalue = arg; %} -function _utrace_syscall_return:long () %{ /* pure */ +function _utrace_syscall_return:long () %{ /* pure */ /* unprivileged */ /* * Here's the reason for the "unsigned long" cast. Since all * values inside systemtap are 64-bit numbers, return values were * getting sign extended. This caused return values to not match * up with the same values passes as arguments. */ - THIS->__retvalue = (unsigned long)syscall_get_return_value(current, + assert_is_myproc(); + if (! CONTEXT->regs) { + CONTEXT->last_error = "invalid call without context registers"; + } else { + THIS->__retvalue = (unsigned long)syscall_get_return_value(current, CONTEXT->regs); + } %} |