From 14138e5ab151c16b73538e5422182f94aafd2c22 Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Fri, 31 May 2013 14:38:02 -0400 Subject: [PATCH] PR15044: change _stp_text_str() from void to int and clean up tapset The tapset functions user_string_quoted() and user_string_n_quoted() now no longer return "NULL" and _stp_text_str() in stp_string.c no longer returns "". Instead, _stp_text_str() was changed to return an int which the tapset checks for to detect an error. --- runtime/stp_string.c | 13 ++++++++-- runtime/stp_string.h | 2 +- tapset/uconversions.stp | 53 +++++++++++++++++++++++++++++------------ 3 files changed, 50 insertions(+), 18 deletions(-) diff --git a/runtime/stp_string.c b/runtime/stp_string.c index 8f5041ce5..b834c24c5 100644 --- a/runtime/stp_string.c +++ b/runtime/stp_string.c @@ -64,7 +64,7 @@ static int _stp_vscnprintf(char *buf, size_t size, const char *fmt, va_list args * in will have "..." after the second quote. * @param user Set this to indicate the input string pointer is a userspace pointer. */ -static void _stp_text_str(char *outstr, char *in, int len, int quoted, int user) +static int _stp_text_str(char *outstr, char *in, int len, int quoted, int user) { char c = '\0', *out = outstr; @@ -77,7 +77,11 @@ static void _stp_text_str(char *outstr, char *in, int len, int quoted, int user) if (user) { if (_stp_read_address(c, in, USER_DS)) +#if STAP_COMPAT_VERSION < STAP_VERSION(9,0) // PR15044: set cutoff goto bad; +#else + return -1; +#endif } else c = *in; @@ -147,7 +151,11 @@ static void _stp_text_str(char *outstr, char *in, int len, int quoted, int user) in++; if (user) { if (_stp_read_address(c, in, USER_DS)) +#if STAP_COMPAT_VERSION < STAP_VERSION(9,0) // PR15044: set cutoff goto bad; +#else + return -1; +#endif } else c = *in; } @@ -163,9 +171,10 @@ static void _stp_text_str(char *outstr, char *in, int len, int quoted, int user) *out++ = '"'; } *out = '\0'; - return; + return 0; bad: strlcpy (outstr, "", len); + return -1; } /** diff --git a/runtime/stp_string.h b/runtime/stp_string.h index b709965f1..e60db237c 100644 --- a/runtime/stp_string.h +++ b/runtime/stp_string.h @@ -10,7 +10,7 @@ #define _STP_STRING_H_ #define to_oct_digit(c) ((c) + '0') -static void _stp_text_str(char *out, char *in, int len, int quoted, int user); +static int _stp_text_str(char *out, char *in, int len, int quoted, int user); #if defined(__KERNEL__) diff --git a/tapset/uconversions.stp b/tapset/uconversions.stp index 20b85dc46..3985ae536 100644 --- a/tapset/uconversions.stp +++ b/tapset/uconversions.stp @@ -131,16 +131,28 @@ function user_string2_warn:string (addr:long, warn_msg:string) * Description: Returns the null terminated C string from a given user space * memory address where any ASCII characters that are not printable are * replaced by the corresponding escape sequence in the returned string. - * Reports "NULL" for address zero. Returns "" on the rare - * cases when userspace data is not accessible at the given address. - */ -function user_string_quoted:string (addr:long) %{ /* pure */ /* myproc-unprivileged */ - if (STAP_ARG_addr == 0) - strlcpy (STAP_RETVALUE, "NULL", MAXSTRINGLEN); - else - /* XXX: stp_text_str uses sleepy __get_user() => unsafe ?! */ - _stp_text_str(STAP_RETVALUE, (char *)(uintptr_t)STAP_ARG_addr, - MAXSTRINGLEN, 1, 1); + * Reports "" for address zero or on the rare cases when userspace data + * is not accessible at the given address. + */ +function user_string_quoted:string (addr:long) +%{ /* pure */ /* myproc-unprivileged */ +#if STAP_COMPAT_VERSION < STAP_VERSION(9,0) // PR15044: set cutoff + if (STAP_ARG_addr == 0) + strlcpy (STAP_RETVALUE, "NULL", MAXSTRINGLEN); + else + /* XXX: stp_text_str uses sleepy __get_user() => unsafe ?! */ + _stp_text_str(STAP_RETVALUE, (char *)(uintptr_t)STAP_ARG_addr, + MAXSTRINGLEN, 1, 1); +#else + if (STAP_ARG_addr == 0) + strlcpy (STAP_RETVALUE, "", MAXSTRINGLEN); + else { + int rc = _stp_text_str(STAP_RETVALUE, + (char *)(uintptr_t)STAP_ARG_addr, MAXSTRINGLEN, 1, 1); + if (rc < 0) + strlcpy (STAP_RETVALUE, "", MAXSTRINGLEN); + } +#endif %} /** @@ -252,18 +264,29 @@ function user_string2_n_warn:string (addr:long, n:long, warn_msg:string) * Description: Returns up to n characters of a C string from the given * user space memory address where any ASCII characters that are not * printable are replaced by the corresponding escape sequence in the - * returned string. Reports "NULL" for address zero. Returns "" - * on the rare cases when userspace data is not accessible at the given - * address. + * returned string. Reports "" for address zero or on the rare cases + * when userspace data is not accessible at the given address. */ -function user_string_n_quoted:string (addr:long, n:long) %{ /* pure */ /* myproc-unprivileged */ - int64_t len = clamp_t(int64_t, STAP_ARG_n + 1, 1, MAXSTRINGLEN); +function user_string_n_quoted:string (addr:long, n:long) +%{ /* pure */ /* myproc-unprivileged */ + int64_t len = clamp_t(int64_t, STAP_ARG_n + 1, 1, MAXSTRINGLEN); +#if STAP_COMPAT_VERSION < STAP_VERSION(9,0) // PR15044: set cutoff if (STAP_ARG_addr == 0) strlcpy(STAP_RETVALUE, "NULL", MAXSTRINGLEN); else /* XXX: stp_text_str uses sleepy __get_user() => unsafe ?! */ _stp_text_str(STAP_RETVALUE, (char *)(uintptr_t)STAP_ARG_addr, len, 1, 1); +#else + if (STAP_ARG_addr == 0) + strlcpy (STAP_RETVALUE, "", MAXSTRINGLEN); + else { + int rc = _stp_text_str(STAP_RETVALUE, + (char *)(uintptr_t)STAP_ARG_addr, len, 1, 1); + if (rc < 0) + strlcpy (STAP_RETVALUE, "", MAXSTRINGLEN); + } +#endif %} /** -- 2.43.5