Thread (7 messages) 7 messages, 4 authors, 2018-04-22

Re: [PATCH v3 01/17] y2038: asm-generic: Extend sysvipc data structures

From: Eric W. Biederman <hidden>
Date: 2018-04-19 22:14:15
Also in: linux-api, linux-arch, linux-mips, linuxppc-dev, lkml, sparclinux

Possibly related (same subject, not in this thread)

Arnd Bergmann [off-list ref] writes:
On Thu, Apr 19, 2018 at 5:20 PM, Arnd Bergmann [off-list ref] wrote:
quoted
On Thu, Apr 19, 2018 at 4:59 PM, Eric W. Biederman [off-list ref] wrote:
quoted
I suspect you want to use __kernel_ulong_t here instead of a raw
unsigned long.  If nothing else it seems inconsistent to use typedefs
in one half of the structure and no typedefs in the other half.
Good catch, there is definitely something wrong here, but I think using
__kernel_ulong_t for all members would also be wrong, as that
still changes the layout on x32, which effectively is

struct msqid64_ds {
     ipc64_perm msg_perm;
     u64 msg_stime;
     u32 __unused1;
     /* 32 bit implict padding */
     u64 msg_rtime;
     u32 __unused2;
     /* 32 bit implict padding */
     u64 msg_ctime;
     u32 __unused3;
     /* 32 bit implict padding */
     __kernel_pid_t          shm_cpid;       /* pid of creator */
     __kernel_pid_t          shm_lpid;       /* pid of last operator */
     ....
};

The choices here would be to either use a mix of
__kernel_ulong_t and unsigned long, or taking the x32
version back into arch/x86/include/uapi/asm/ so the
generic version at least makes some sense.

I can't use __kernel_time_t for the lower half on 32-bit
since it really should be unsigned.
After thinking about it some more, I conclude that the structure is simply
incorrect on x32: The __kernel_ulong_t usage was introduced in 2013
in commit b9cd5ca22d67 ("uapi: Use __kernel_ulong_t in struct
msqid64_ds") and apparently was correct initially as __BITS_PER_LONG
evaluated to 64, but it broke with commit f4b4aae18288 ("x86/headers/uapi:
Fix __BITS_PER_LONG value for x32 builds") that changed the value
of __BITS_PER_LONG and introduced the extra padding in 2015.

The same change apparently also broke a lot of other definitions, e.g.

$ echo "#include <linux/types.h>" | gcc -mx32 -E -xc - | grep -A3
__kernel_size_t
typedef unsigned int __kernel_size_t;
typedef int __kernel_ssize_t;
typedef int __kernel_ptrdiff_t;

Those used to be defined as 'unsigned long long' and 'long long'
respectively, so now all kernel interfaces using those on x32
became incompatible!
That seems like a real mess.

Is this just for the uapi header as seen by userspace?  I expect we are
using the a normal kernel interface with 64bit longs and 64bit pointers
when we build the kernel.

If this is just a header as seen from userspace mess it seems
unfortunate but fixable.

Eric
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help