| Summary: | __IPC_64 bit is not expected by Kernel's SYSV *ctl fuctions | ||
|---|---|---|---|
| Product: | uClibc | Reporter: | Sergey Koulik <skoulik> |
| Component: | Standard Compliance | Assignee: | unassigned |
| Status: | NEW --- | ||
| Severity: | normal | CC: | skoulik, uclibc-cvs |
| Priority: | P5 | ||
| Version: | 0.9.32 | ||
| Target Milestone: | --- | ||
| Hardware: | All | ||
| OS: | Linux | ||
| Host: | Target: | ||
| Build: | |||
It seems we have a __ASSUME_IPC64 in kernel-features.h Can you please cook a patch perusing / tweaking this? |
The following define in libc/misc/sysvipc/ipc.h effectively makes uclibc wrappers OR user's *ctl commands with 0x100 before passing to kernel. However this flag is not expected and not decoded on kernel side. The latter causes all user's commands passed to *ctl fuctions fail with EINVAL result. #if __WORDSIZE == 32 || defined __alpha__ || defined __mips__ # define __IPC_64 0x100 #else # define __IPC_64 0x0 #endif The problem affects the following SYSV fuctions: semctl(), msgctl(), shmctl(). ipc/sem.c: SYSCALL_DEFINE(semctl)(int semid, int semnum, int cmd, union semun arg) { [...] switch(cmd) { <-- 0x100 is not removed, goes directly to default case and returns -EINVAL ipc/shm.c: SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf) { [...] version = ipc_parse_version(&cmd); <-- 0x100 is removed iff __ARCH_WANT_IPC_PARSE_VERSION is defined (which is not always the case) ipc/msg.c: SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf) { [...] version = ipc_parse_version(&cmd); <-- 0x100 is removed iff __ARCH_WANT_IPC_PARSE_VERSION is defined (which is not always the case) A quick and dirty fix is to define __IPC_64 0x0 unconditionally as modern kernels do not seem to use old 32 bit structures internally any more (checked 2.6 and 3.x trunk). So does user space. A better solution is to look at kernel's version to check if 0x100 is actually needed.