Hi,

On Fri, Oct 19, 2012 at 1:56 PM,  <[email protected]> wrote:
> From: Kees Cook <[email protected]>
> Subject: kernel/sys.c: fix stack memory content leak via UNAME26
>
> Calling uname() with the UNAME26 personality set allows a leak of kernel
> stack contents.  This fixes it by defensively calculating the length of
> copy_to_user() call, making the len argument unsigned, and initializing
> the stack buffer to zero (now technically unneeded, but hey, overkill).
>
> CVE-2012-0957
>
> Reported-by: PaX Team <[email protected]>
> Signed-off-by: Kees Cook <[email protected]>
> Cc: Andi Kleen <[email protected]>
> Cc: PaX Team <[email protected]>
> Cc: Brad Spengler <[email protected]>
> Cc: <[email protected]>
> Signed-off-by: Andrew Morton <[email protected]>
> ---
>
>  kernel/sys.c |   12 +++++++-----
>  1 file changed, 7 insertions(+), 5 deletions(-)
>
> diff -puN kernel/sys.c~kernel-sysc-fix-stack-memory-content-leak-via-uname26 
> kernel/sys.c
> --- a/kernel/sys.c~kernel-sysc-fix-stack-memory-content-leak-via-uname26
> +++ a/kernel/sys.c
> @@ -1265,15 +1265,16 @@ DECLARE_RWSEM(uts_sem);
>   * Work around broken programs that cannot handle "Linux 3.0".
>   * Instead we map 3.x to 2.6.40+x, so e.g. 3.0 would be 2.6.40
>   */
> -static int override_release(char __user *release, int len)
> +static int override_release(char __user *release, size_t len)
>  {
>         int ret = 0;
> -       char buf[65];
>
>         if (current->personality & UNAME26) {
> -               char *rest = UTS_RELEASE;
> +               const char *rest = UTS_RELEASE;
> +               char buf[65] = { 0 };
>                 int ndots = 0;
>                 unsigned v;
> +               size_t copy;
>
>                 while (*rest) {
>                         if (*rest == '.' && ++ndots >= 3)
> @@ -1283,8 +1284,9 @@ static int override_release(char __user
>                         rest++;
>                 }
>                 v = ((LINUX_VERSION_CODE >> 8) & 0xff) + 40;
> -               snprintf(buf, len, "2.6.%u%s", v, rest);
> -               ret = copy_to_user(release, buf, len);
> +               copy = min(sizeof(buf), max_t(size_t, 1, len));
> +               copy = scnprintf(buf, copy, "2.6.%u%s", v, rest);
> +               ret = copy_to_user(release, buf, copy + 1);
>         }
>         return ret;
>  }
> _

Please use this improved patch, the one above had an issue that
Fengguang Wu found (needed to swap min/max with clamp):
https://lkml.org/lkml/2012/10/12/358

Thanks,

-Kees

-- 
Kees Cook
Chrome OS Security
--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to