From f75409719f120a3dbee66d761cf23a64092d1414 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 28 Jan 2010 21:00:58 -0800 Subject: PR11234: Ensure __get_argv doesn't overflow That function was calling strlcpy as if the return value was the number of bytes copied, but strlcpy actually returns the length of the input string. We now use min() to handle the case when it's bigger than the buffer length, and drop out of the loop when that happens. --- tapset/aux_syscalls.stp | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'tapset') diff --git a/tapset/aux_syscalls.stp b/tapset/aux_syscalls.stp index 4577d64e..a0ab557b 100644 --- a/tapset/aux_syscalls.stp +++ b/tapset/aux_syscalls.stp @@ -401,20 +401,20 @@ function __sem_flags:string(semflg:long) /* This function copies an argv from userspace. */ function __get_argv:string(a:long, first:long) %{ /* pure */ - char __user *__user *argv = (char __user *__user *)(long)THIS->a; + char __user *__user *argv = (char __user *__user *)(long)THIS->a; char __user *vstr; int space, rc, len = MAXSTRINGLEN; char *str = THIS->__retvalue; char buf[80]; char *ptr = buf; - + if (THIS->first && argv) argv++; - while (argv != NULL) { + while (argv != NULL && len) { if (__stp_get_user (vstr, argv)) - break; + break; if (vstr == NULL) break; @@ -443,8 +443,8 @@ function __get_argv:string(a:long, first:long) *str++='\"'; len--; } - - rc = strlcpy (str, buf, len); + + rc = min(len, (int) strlcpy (str, buf, len)); str += rc; len -= rc; @@ -455,13 +455,15 @@ function __get_argv:string(a:long, first:long) argv++; } + if (!len) + --str; *str = 0; %} /* This function copies an argv from userspace. */ function __get_compat_argv:string(a:long, first:long) %{ /* pure */ #ifdef CONFIG_COMPAT - compat_uptr_t __user *__user *argv = (compat_uptr_t __user *__user *)(long)THIS->a; + compat_uptr_t __user *__user *argv = (compat_uptr_t __user *__user *)(long)THIS->a; compat_uptr_t __user *vstr; int space, rc, len = MAXSTRINGLEN; char *str = THIS->__retvalue; @@ -471,9 +473,9 @@ function __get_compat_argv:string(a:long, first:long) if (THIS->first && argv) argv++; - while (argv != NULL) { + while (argv != NULL && len) { if (__stp_get_user (vstr, argv)) - break; + break; if (vstr == NULL) break; @@ -502,8 +504,8 @@ function __get_compat_argv:string(a:long, first:long) *str++='\"'; len--; } - - rc = strlcpy (str, buf, len); + + rc = min(len, (int) strlcpy (str, buf, len)); str += rc; len -= rc; @@ -514,6 +516,8 @@ function __get_compat_argv:string(a:long, first:long) argv++; } + if (!len) + --str; *str = 0; #endif %} -- cgit From 1a11a23e5eba2caad084961a505a344a3c6e1ead Mon Sep 17 00:00:00 2001 From: Petr Muller Date: Mon, 1 Feb 2010 18:19:58 +0100 Subject: Fix a incorrect UNKNOWN VALUE message creation in _sock_type_str function --- tapset/aux_syscalls.stp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tapset') diff --git a/tapset/aux_syscalls.stp b/tapset/aux_syscalls.stp index a0ab557b..2d0ba210 100644 --- a/tapset/aux_syscalls.stp +++ b/tapset/aux_syscalls.stp @@ -1340,7 +1340,7 @@ function _sock_type_str:string(type:long) strlcpy (THIS->__retvalue, "SOCK_PACKET", MAXSTRINGLEN); break; default: - strlcpy (THIS->__retvalue, "UNKNOWN VALUE: %d", t); + snprintf (THIS->__retvalue, MAXSTRINGLEN, "UNKNOWN VALUE: %d", t); break; } -- cgit