1 // SPDX-License-Identifier: GPL-2.0
3 * sys_ipc() is the old de-multiplexer for the SysV IPC calls.
5 * This is really horribly ugly, and new architectures should just wire up
6 * the individual syscalls instead.
8 #include <linux/unistd.h>
9 #include <linux/syscalls.h>
11 #ifdef __ARCH_WANT_SYS_IPC
12 #include <linux/errno.h>
13 #include <linux/ipc.h>
14 #include <linux/shm.h>
15 #include <linux/uaccess.h>
17 SYSCALL_DEFINE6(ipc
, unsigned int, call
, int, first
, unsigned long, second
,
18 unsigned long, third
, void __user
*, ptr
, long, fifth
)
22 version
= call
>> 16; /* hack for backward compatibility */
27 return sys_semtimedop(first
, (struct sembuf __user
*)ptr
,
30 return sys_semtimedop(first
, (struct sembuf __user
*)ptr
,
32 (const struct timespec __user
*)fifth
);
35 return sys_semget(first
, second
, third
);
40 if (get_user(arg
, (unsigned long __user
*) ptr
))
42 return sys_semctl(first
, second
, third
, arg
);
46 return sys_msgsnd(first
, (struct msgbuf __user
*) ptr
,
51 struct ipc_kludge tmp
;
55 if (copy_from_user(&tmp
,
56 (struct ipc_kludge __user
*) ptr
,
59 return sys_msgrcv(first
, tmp
.msgp
, second
,
63 return sys_msgrcv(first
,
64 (struct msgbuf __user
*) ptr
,
65 second
, fifth
, third
);
68 return sys_msgget((key_t
) first
, second
);
70 return sys_msgctl(first
, second
, (struct msqid_ds __user
*)ptr
);
76 ret
= do_shmat(first
, (char __user
*)ptr
,
77 second
, &raddr
, SHMLBA
);
80 return put_user(raddr
, (unsigned long __user
*) third
);
84 * This was the entry point for kernel-originating calls
85 * from iBCS2 in 2.2 days.
90 return sys_shmdt((char __user
*)ptr
);
92 return sys_shmget(first
, second
, third
);
94 return sys_shmctl(first
, second
,
95 (struct shmid_ds __user
*) ptr
);
103 #include <linux/compat.h>
105 #ifndef COMPAT_SHMLBA
106 #define COMPAT_SHMLBA SHMLBA
109 struct compat_ipc_kludge
{
111 compat_long_t msgtyp
;
114 #ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC
115 COMPAT_SYSCALL_DEFINE6(ipc
, u32
, call
, int, first
, int, second
,
116 u32
, third
, compat_uptr_t
, ptr
, u32
, fifth
)
121 version
= call
>> 16; /* hack for backward compatibility */
126 /* struct sembuf is the same on 32 and 64bit :)) */
127 return sys_semtimedop(first
, compat_ptr(ptr
), second
, NULL
);
129 return compat_sys_semtimedop(first
, compat_ptr(ptr
), second
,
132 return sys_semget(first
, second
, third
);
136 if (get_user(pad
, (u32 __user
*) compat_ptr(ptr
)))
138 return compat_sys_semctl(first
, second
, third
, pad
);
141 return compat_sys_msgsnd(first
, ptr
, second
, third
);
144 void __user
*uptr
= compat_ptr(ptr
);
146 if (first
< 0 || second
< 0)
150 struct compat_ipc_kludge ipck
;
153 if (copy_from_user(&ipck
, uptr
, sizeof(ipck
)))
155 return compat_sys_msgrcv(first
, ipck
.msgp
, second
,
158 return compat_sys_msgrcv(first
, ptr
, second
, fifth
, third
);
161 return sys_msgget(first
, second
);
163 return compat_sys_msgctl(first
, second
, compat_ptr(ptr
));
171 err
= do_shmat(first
, compat_ptr(ptr
), second
, &raddr
,
175 return put_user(raddr
, (compat_ulong_t
*)compat_ptr(third
));
178 return sys_shmdt(compat_ptr(ptr
));
180 return sys_shmget(first
, (unsigned)second
, third
);
182 return compat_sys_shmctl(first
, second
, compat_ptr(ptr
));