summaryrefslogtreecommitdiffstats
path: root/tapset
diff options
context:
space:
mode:
Diffstat (limited to 'tapset')
-rw-r--r--tapset/ChangeLog17
-rw-r--r--tapset/conversions.stp130
-rw-r--r--tapset/null.stp2
-rw-r--r--tapset/syscalls2.stp8
4 files changed, 152 insertions, 5 deletions
diff --git a/tapset/ChangeLog b/tapset/ChangeLog
index 32ac6bf2..dae8b452 100644
--- a/tapset/ChangeLog
+++ b/tapset/ChangeLog
@@ -1,3 +1,20 @@
+2008-03-21 Eugene Teo <eugeneteo@kernel.sg>
+
+ PR 5528
+ * conversions.stp (user_string_n, user_string_n2, user_string_n_warn,
+ user_string_n_quoted, user_short, user_short_warn, user_int,
+ user_int_warn, user_long, user_long_warn, user_char, user_char_warn):
+ New user_* functions.
+
+2008-03-20 Frank Ch. Eigler <fche@elastic.org>
+
+ PR 5956.
+ * null.stp: New file, defining global NULL=0.
+
+2008-03-11 Will Cohen <wcohen@redhat.com>
+
+ * syscalls2.stp (syscall.wait{4|id}): Correct for 2.6.24.n kernels.
+
2008-03-06 Ananth N Mavinakayanahalli <ananth@in.ibm.com
* i686/syscalls.stp: Handle sys_sigaltstack parameter after
diff --git a/tapset/conversions.stp b/tapset/conversions.stp
index af993992..70725e9d 100644
--- a/tapset/conversions.stp
+++ b/tapset/conversions.stp
@@ -1,5 +1,5 @@
// conversions tapset
-// Copyright (C) 2005-2007 Red Hat Inc.
+// Copyright (C) 2005-2008 Red Hat Inc.
// Copyright (C) 2007 Intel Corporation.
//
// This file is part of systemtap, and is free software. You can
@@ -108,3 +108,131 @@ function user_string_quoted:string (addr:long) %{ /* pure */
_stp_text_str(THIS->__retvalue, (char *)(uintptr_t)THIS->addr,
MAXSTRINGLEN, 1, 1);
%}
+
+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 */
+ long len = THIS->n + 1;
+ len = (len > MAXSTRINGLEN) ? MAXSTRINGLEN : len;
+ if (_stp_strncpy_from_user(THIS->__retvalue,
+ (char __user *) (uintptr_t) THIS->addr,
+ len) < 0)
+ strlcpy(THIS->__retvalue, THIS->err_msg, MAXSTRINGLEN);
+%}
+
+function user_string_n_warn:string (addr:long, n:long) %{ /* pure */
+ long len = THIS->n + 1;
+ long rc;
+
+ len = (len > MAXSTRINGLEN) ? MAXSTRINGLEN : len;
+ rc = _stp_strncpy_from_user(THIS->__retvalue,
+ (char __user *) (uintptr_t) THIS->addr, len);
+ if (rc < 0) {
+ // NB: using error_buffer to get local space for the warning, but we're
+ // not aborting, so leave last_error alone.
+ snprintf (CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer),
+ "user string copy fault %ld at %p", rc,
+ (void *) (uintptr_t) THIS->addr);
+ _stp_warn(CONTEXT->error_buffer);
+ strlcpy (THIS->__retvalue, "<unknown>", MAXSTRINGLEN);
+ }
+%}
+
+function user_string_n_quoted:string (addr:long, n:long) %{ /* pure */
+ long len = THIS->n + 1;
+ if (THIS->addr == 0)
+ strlcpy(THIS->__retvalue, "NULL", MAXSTRINGLEN);
+ else
+ /* XXX: stp_text_str uses sleepy __get_user() => unsafe ?! */
+ _stp_text_str(THIS->__retvalue, (char *)(uintptr_t)THIS->addr,
+ len, 1, 1);
+%}
+
+// When userspace data is not accessible, the following functions return 0
+
+function user_short:long (addr:long) %{ /* pure */
+ 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)) {
+fault:
+ THIS->__retvalue = 0;
+ }
+%}
+
+function user_short_warn:long (addr:long) %{ /* pure */
+ 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)) {
+fault:
+ snprintf (CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer),
+ "user short copy fault %p", (void *) (uintptr_t) THIS->addr);
+ _stp_warn(CONTEXT->error_buffer);
+ THIS->__retvalue = 0;
+ }
+%}
+
+function user_int:long (addr:long) %{ /* pure */
+ 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)) {
+fault:
+ THIS->__retvalue = 0;
+ }
+%}
+
+function user_int_warn:long (addr:long) %{ /* pure */
+ 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)) {
+fault:
+ snprintf (CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer),
+ "user int copy fault %p", (void *) (uintptr_t) THIS->addr);
+ _stp_warn(CONTEXT->error_buffer);
+ THIS->__retvalue = 0;
+ }
+%}
+
+function user_long:long (addr:long) %{ /* pure */
+ 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)) {
+fault:
+ THIS->__retvalue = 0;
+ }
+%}
+
+function user_long_warn:long (addr:long) %{ /* pure */
+ 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)) {
+fault:
+ snprintf (CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer),
+ "user long copy fault %p", (void *) (uintptr_t) THIS->addr);
+ _stp_warn(CONTEXT->error_buffer);
+ THIS->__retvalue = 0;
+ }
+%}
+
+function user_char:long (addr:long) %{ /* pure */
+ 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)) {
+fault:
+ THIS->__retvalue = 0;
+ }
+%}
+
+function user_char_warn:long (addr:long) %{ /* pure */
+ 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)) {
+fault:
+ snprintf (CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer),
+ "user char copy fault %p", (void *) (uintptr_t) THIS->addr);
+ _stp_warn(CONTEXT->error_buffer);
+ THIS->__retvalue = 0;
+ }
+%}
+
diff --git a/tapset/null.stp b/tapset/null.stp
new file mode 100644
index 00000000..c8713665
--- /dev/null
+++ b/tapset/null.stp
@@ -0,0 +1,2 @@
+
+global NULL = 0
diff --git a/tapset/syscalls2.stp b/tapset/syscalls2.stp
index b0118423..558e89bb 100644
--- a/tapset/syscalls2.stp
+++ b/tapset/syscalls2.stp
@@ -3023,13 +3023,13 @@ probe syscall.compat_vmsplice.return = kernel.function("compat_sys_vmsplice").re
#
probe syscall.wait4 = kernel.function("sys_wait4") {
name = "wait4"
- pid = %( kernel_vr > "2.6.24"%? $upid %: $pid%)
+ pid = %( kernel_vr >= "2.6.25" %? $upid %: $pid%)
status_uaddr = $stat_addr
options = $options
options_str = _wait4_opt_str($options)
rusage_uaddr = $ru
argstr = sprintf("%d, %p, %s, %p",
- %( kernel_vr > "2.6.24"%? $upid %: $pid%),
+ %( kernel_vr >= "2.6.25" %? $upid %: $pid%),
$stat_addr,_wait4_opt_str($options), $ru)
}
probe syscall.wait4.return = kernel.function("sys_wait4").return {
@@ -3046,7 +3046,7 @@ probe syscall.wait4.return = kernel.function("sys_wait4").return {
#
probe syscall.waitid = kernel.function("sys_waitid") {
name = "waitid"
- pid = %( kernel_vr > "2.6.24"%? $upid %: $pid%)
+ pid = %( kernel_vr >= "2.6.25" %? $upid %: $pid%)
which = $which
which_str = _waitid_which_str($which)
infop_uaddr = $infop
@@ -3054,7 +3054,7 @@ probe syscall.waitid = kernel.function("sys_waitid") {
options_str = _waitid_opt_str($options)
rusage_uaddr = $ru
argstr = sprintf("%d, %d, %p, %s, %p", $which,
- %( kernel_vr > "2.6.24"%? $upid %: $pid%), $infop,
+ %( kernel_vr >= "2.6.25" %? $upid %: $pid%), $infop,
_waitid_opt_str($options), $ru)
}
probe syscall.waitid.return = kernel.function("sys_waitid").return {