lkml.org 
[lkml]   [2014]   [Feb]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.12 008/133] x86, x32: Correct invalid use of user timespec in the kernel
    Date
    3.12-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: PaX Team <pageexec@freemail.hu>

    commit 2def2ef2ae5f3990aabdbe8a755911902707d268 upstream.

    The x32 case for the recvmsg() timout handling is broken:

    asmlinkage long compat_sys_recvmmsg(int fd, struct compat_mmsghdr __user *mmsg,
    unsigned int vlen, unsigned int flags,
    struct compat_timespec __user *timeout)
    {
    int datagrams;
    struct timespec ktspec;

    if (flags & MSG_CMSG_COMPAT)
    return -EINVAL;

    if (COMPAT_USE_64BIT_TIME)
    return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
    flags | MSG_CMSG_COMPAT,
    (struct timespec *) timeout);
    ...

    The timeout pointer parameter is provided by userland (hence the __user
    annotation) but for x32 syscalls it's simply cast to a kernel pointer
    and is passed to __sys_recvmmsg which will eventually directly
    dereference it for both reading and writing. Other callers to
    __sys_recvmmsg properly copy from userland to the kernel first.

    The bug was introduced by commit ee4fa23c4bfc ("compat: Use
    COMPAT_USE_64BIT_TIME in net/compat.c") and should affect all kernels
    since 3.4 (and perhaps vendor kernels if they backported x32 support
    along with this code).

    Note that CONFIG_X86_X32_ABI gets enabled at build time and only if
    CONFIG_X86_X32 is enabled and ld can build x32 executables.

    Other uses of COMPAT_USE_64BIT_TIME seem fine.

    This addresses CVE-2014-0038.

    Signed-off-by: PaX Team <pageexec@freemail.hu>
    Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    net/compat.c | 9 ++-------
    1 file changed, 2 insertions(+), 7 deletions(-)

    --- a/net/compat.c
    +++ b/net/compat.c
    @@ -780,21 +780,16 @@ asmlinkage long compat_sys_recvmmsg(int
    if (flags & MSG_CMSG_COMPAT)
    return -EINVAL;

    - if (COMPAT_USE_64BIT_TIME)
    - return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
    - flags | MSG_CMSG_COMPAT,
    - (struct timespec *) timeout);
    -
    if (timeout == NULL)
    return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
    flags | MSG_CMSG_COMPAT, NULL);

    - if (get_compat_timespec(&ktspec, timeout))
    + if (compat_get_timespec(&ktspec, timeout))
    return -EFAULT;

    datagrams = __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
    flags | MSG_CMSG_COMPAT, &ktspec);
    - if (datagrams > 0 && put_compat_timespec(&ktspec, timeout))
    + if (datagrams > 0 && compat_put_timespec(&ktspec, timeout))
    datagrams = -EFAULT;

    return datagrams;



    \
     
     \ /
      Last update: 2014-02-05 00:21    [W:4.936 / U:0.584 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site