Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20180624191831.GA5047@openwall.com>
Date: Sun, 24 Jun 2018 21:18:31 +0200
From: Solar Designer <solar@...nwall.com>
To: owl-dev@...ts.openwall.com
Cc: Vasily Averin <vvs@...tuozzo.com>
Subject: 32-bit syscall breakage in -431 kernel with KAISER

Hi,

So we got reported this bug (or maybe several bugs, but luckily they all
look related to me so far):

http://www.openwall.com/lists/owl-users/2018/06/21/2

I'm not sure if it's worth our time with so few users left (and
interested in upgrading the kernel for security fixes), but it is indeed
weird to release a kernel update with those regressions and then do
nothing about them.  So I finally looked into this today.

My preliminary analysis suggests that maybe the KAISER backport broke
the pt_regs ABI for 32-bit syscalls in x86_64 kernels.  Specifically,
SIOCGIFCONF might be failing with EFAULT because fs/compat_ioctl.c:
dev_ifconf() uses compat_alloc_user_space():

static int dev_ifconf(unsigned int fd, unsigned int cmd, unsigned long arg)
{
        struct ifconf32 ifc32;
        struct ifconf ifc;
        struct ifconf __user *uifc;
        struct ifreq32 __user *ifr32;
        struct ifreq __user *ifr;
        unsigned int i, j;
        int err;

        if (copy_from_user(&ifc32, compat_ptr(arg), sizeof(struct ifconf32)))
                return -EFAULT;

        if (ifc32.ifcbuf == 0) {
                ifc32.ifc_len = 0;
                ifc.ifc_len = 0;
                ifc.ifc_req = NULL;
                uifc = compat_alloc_user_space(sizeof(struct ifconf));
        } else {
                size_t len =((ifc32.ifc_len / sizeof (struct ifreq32)) + 1) *
                        sizeof (struct ifreq);
                uifc = compat_alloc_user_space(sizeof(struct ifconf) + len);

which in turn relies on pt_regs:

static __inline__ void __user *arch_compat_alloc_user_space(long len)
{
        struct pt_regs *regs = task_pt_regs(current);
        return (void __user *)regs->rsp - len;
}

Searching for other uses of compat_alloc_user_space(), I find there are
not a lot overall, but this includes many uses in ipc/compat.c.  This
led me to test the ipcs(1) command, and indeed it's partially broken:

root@...32:/ # ipcs

kernel not configured for shared memory

------ Semaphore Arrays --------
key        semid      owner      perms      nsems

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages

The "kernel not configured for shared memory" line appears in a 32-bit
container now, but not in 64-bit.

I also took a look at the 32-bit syscall entry code changes, but don't
immediately see any breakage of the pt_regs ABI.  So maybe my guess is
wrong, or maybe I just don't see how it's right.

The bug might have come from the RHEL5 ELS changes, or it might have
been introduced in the merging with OpenVZ, or it might have been
introduced in Owl (such as with our different kernel config and our
different gcc, whereas our patch is too small and unrelated to be a
likely culprit).  It doesn't have to be with KAISER - it could also be
with RETPOLINE, which is disabled in this build but it does make many
invasive changes anyway (even if no-op'ish for security).

I tried searching whether this is possibly a known issue for RHEL5 ELS,
but couldn't find anything.  I guess not many systems use RHEL5 ELS and
its rebuilds, and those who do are possibly 64-bit only.

Alexander

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.