diff options
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | stapfuncs.5.in | 54 | ||||
-rw-r--r-- | tapset/ChangeLog | 8 | ||||
-rw-r--r-- | tapset/conversions.stp | 130 | ||||
-rw-r--r-- | testsuite/ChangeLog | 7 | ||||
-rwxr-xr-x | testsuite/buildok/conversions-embedded.stp | 13 | ||||
-rwxr-xr-x | testsuite/buildok/conversions.stp | 13 | ||||
-rw-r--r-- | testsuite/systemtap.stress/conversions.stp | 12 |
8 files changed, 248 insertions, 1 deletions
@@ -1,3 +1,15 @@ +2008-03-21 Eugene Teo <eugeneteo@kernel.sg> + + PR 5528 + * tapset/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. + * stapfuncs.5.in: Documented the new functions. + * testsuite/systemtap.stress/conversions.stp: Test new functions. + * testsuite/buildok/conversions.stp: Test new functions. + * testsuite/buildok/conversions-embedded.stp: Test new functions. + 2008-03-20 Frank Ch. Eigler <fche@elastic.org> PR 5975. diff --git a/stapfuncs.5.in b/stapfuncs.5.in index 85a00b37..9bca845d 100644 --- a/stapfuncs.5.in +++ b/stapfuncs.5.in @@ -92,6 +92,60 @@ fault, return instead the err_msg value. user_string_warn:string (addr:long) Copy a string from user space at given address. If the access would fault, signal a warning and return "<unknown>". +.TP +user_string_quoted:string (addr:long) +Copy a string from user space at given address. Any ASCII characters +that are not printable are replaced by the corresponding escape +sequence in the returned string. +.TP +user_string_n:string (addr:long, n:long) +Copy a string of n bytes from user space at given address. If the access +would fault, return "<unknown>". +.TP +user_string_n2:string (addr:long, n:long, err_msg:string) +Copy a string of n bytes from user space at given address. If the access +would fault, return the err_msg value. +.TP +user_string_n_warn:string (addr:long, n:long) +Copy a string of n bytes from user space at given address. If the access +would fault, signal a warning and return "<unknown>". +.TP +user_string_n_quoted:string (addr:long, n:long) +Copy a string of n bytes from user space at given address. Any ASCII +characters that are not printable are replaced by the corresponding escape +sequence in the returned string. If the access would fault, return "<unknown>". +.TP +user_short:long (addr:long) +Copy a short from user space at given address. If the access would fault, +return 0. +.TP +user_short_warn:long (addr:long) +Copy a short from user space at given address. If the access would fault, +signal a warning and return 0. +.TP +user_int:long (addr:long) +Copy an int from user space at given address. If the access would fault, +return 0. +.TP +user_int_warn:long (addr:long) +Copy an int from user space at given address. If the access would fault, +signal a warning and return 0. +.TP +user_long:long (addr:long) +Copy a long from user space at given address. If the access would fault, +return 0. +.TP +user_long_warn:long (addr:long) +Copy a long from user space at given address. If the access would fault, +signal a warning and return 0. +.TP +user_char:long (addr:long) +Copy a char from user space at given address. If the access would fault, +return 0. +.TP +user_char_warn:long (addr:long) +Copy a char from user space at given address. If the access would fault, +signal a warning and return 0. .SS STRING .TP strlen:long (str:string) diff --git a/tapset/ChangeLog b/tapset/ChangeLog index da21a5ff..dae8b452 100644 --- a/tapset/ChangeLog +++ b/tapset/ChangeLog @@ -1,3 +1,11 @@ +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. 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/testsuite/ChangeLog b/testsuite/ChangeLog index 16f7af57..14f96ecc 100644 --- a/testsuite/ChangeLog +++ b/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2008-03-21 Eugene Teo <eugeneteo@kernel.sg> + + PR 5528 + * systemtap.stress/conversions.stp: Test new user_* functions. + * buildok/conversions.stp: Test new user_* functions. + * buildok/conversions-embedded.stp: Test new user_* functions. + 2008-03-20 Frank Ch. Eigler <fche@elastic.org> PR 5956. diff --git a/testsuite/buildok/conversions-embedded.stp b/testsuite/buildok/conversions-embedded.stp index 7aa5a0b4..55f6cdb7 100755 --- a/testsuite/buildok/conversions-embedded.stp +++ b/testsuite/buildok/conversions-embedded.stp @@ -9,5 +9,18 @@ probe begin { print (user_string2 (0, "")) print (user_string_warn (0)) print (user_string_quoted (0)) + + print (user_string_n(0, 5)) + print (user_string_n2(0, 5, "foobar")) + print (user_string_n_warn(0, 0)) + print (user_string_n_quoted(0, 0)) + print (user_short(0)) + print (user_short_warn(0)) + print (user_int(0)) + print (user_int_warn(0)) + print (user_long(0)) + print (user_long_warn(0)) + print (user_char(0)) + print (user_char_warn(0)) } diff --git a/testsuite/buildok/conversions.stp b/testsuite/buildok/conversions.stp index e83bd968..5f151f1d 100755 --- a/testsuite/buildok/conversions.stp +++ b/testsuite/buildok/conversions.stp @@ -12,4 +12,17 @@ probe begin { print (user_string(2342)) print (user_string2(2342,"foobar")) print (user_string_warn(2342)) + + print (user_string_n(2342, 5)) + print (user_string_n2(2342, 5, "foobar")) + print (user_string_n_warn(2342, 5)) + print (user_string_n_quoted(2342, 5)) + print (user_short(2342)) + print (user_short_warn(2342)) + print (user_int(2342)) + print (user_int_warn(2342)) + print (user_long(2342)) + print (user_long_warn(2342)) + print (user_char(2342)) + print (user_char_warn(2342)) } diff --git a/testsuite/systemtap.stress/conversions.stp b/testsuite/systemtap.stress/conversions.stp index 07795a6d..34bd0c28 100644 --- a/testsuite/systemtap.stress/conversions.stp +++ b/testsuite/systemtap.stress/conversions.stp @@ -13,4 +13,16 @@ probe begin { print (user_string ($1)) } probe begin { print (user_string2 ($1,"<only suspected, not known>")) } probe begin { print (user_string_warn ($1)) } probe begin { print (user_string_quoted ($1)) } +probe begin { print (user_string_n ($1, 5)) } +probe begin { print (user_string_n2 ($1, 5, "<only suspected, not known>")) } +probe begin { print (user_string_n_warn ($1, 5)) } +probe begin { print (user_string_n_quoted ($1, 5)) } +probe begin { print (user_short ($1)) } +probe begin { print (user_short_warn ($1)) } +probe begin { print (user_int ($1)) } +probe begin { print (user_int_warn ($1)) } +probe begin { print (user_long ($1)) } +probe begin { print (user_long_warn ($1)) } +probe begin { print (user_char ($1)) } +probe begin { print (user_char_warn ($1)) } probe begin(1) { print ("\n") exit () } |