summaryrefslogtreecommitdiffstats
path: root/tapset
diff options
context:
space:
mode:
Diffstat (limited to 'tapset')
-rw-r--r--tapset/DEVGUIDE17
-rw-r--r--tapset/context-symbols.stp6
-rw-r--r--tapset/context-unwind.stp15
-rw-r--r--tapset/context.stp79
-rw-r--r--tapset/conversions.stp50
-rw-r--r--tapset/networking.stp175
-rw-r--r--tapset/signal.stp4
-rw-r--r--tapset/socket.stp2
-rw-r--r--tapset/string.stp20
-rw-r--r--tapset/timestamp_gtod.stp2
-rw-r--r--tapset/ucontext-symbols.stp12
-rw-r--r--tapset/ucontext-unwind.stp6
-rw-r--r--tapset/utrace.stp27
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);
+ }
%}