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>
10 #include <linux/security.h>
11 #include <linux/ipc_namespace.h>
14 #ifdef __ARCH_WANT_SYS_IPC
15 #include <linux/errno.h>
16 #include <linux/ipc.h>
17 #include <linux/shm.h>
18 #include <linux/uaccess.h>
20 SYSCALL_DEFINE6(ipc
, unsigned int, call
, int, first
, unsigned long, second
,
21 unsigned long, third
, void __user
*, ptr
, long, fifth
)
25 version
= call
>> 16; /* hack for backward compatibility */
30 return ksys_semtimedop(first
, (struct sembuf __user
*)ptr
,
33 return ksys_semtimedop(first
, (struct sembuf __user
*)ptr
,
35 (const struct timespec __user
*)fifth
);
38 return ksys_semget(first
, second
, third
);
43 if (get_user(arg
, (unsigned long __user
*) ptr
))
45 return ksys_semctl(first
, second
, third
, arg
);
49 return ksys_msgsnd(first
, (struct msgbuf __user
*) ptr
,
54 struct ipc_kludge tmp
;
58 if (copy_from_user(&tmp
,
59 (struct ipc_kludge __user
*) ptr
,
62 return ksys_msgrcv(first
, tmp
.msgp
, second
,
66 return ksys_msgrcv(first
,
67 (struct msgbuf __user
*) ptr
,
68 second
, fifth
, third
);
71 return ksys_msgget((key_t
) first
, second
);
73 return ksys_msgctl(first
, second
,
74 (struct msqid_ds __user
*)ptr
);
80 ret
= do_shmat(first
, (char __user
*)ptr
,
81 second
, &raddr
, SHMLBA
);
84 return put_user(raddr
, (unsigned long __user
*) third
);
88 * This was the entry point for kernel-originating calls
89 * from iBCS2 in 2.2 days.
94 return ksys_shmdt((char __user
*)ptr
);
96 return ksys_shmget(first
, second
, third
);
98 return ksys_shmctl(first
, second
,
99 (struct shmid_ds __user
*) ptr
);
107 #include <linux/compat.h>
109 #ifndef COMPAT_SHMLBA
110 #define COMPAT_SHMLBA SHMLBA
113 struct compat_ipc_kludge
{
115 compat_long_t msgtyp
;
118 #ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC
119 COMPAT_SYSCALL_DEFINE6(ipc
, u32
, call
, int, first
, int, second
,
120 u32
, third
, compat_uptr_t
, ptr
, u32
, fifth
)
125 version
= call
>> 16; /* hack for backward compatibility */
130 /* struct sembuf is the same on 32 and 64bit :)) */
131 return ksys_semtimedop(first
, compat_ptr(ptr
), second
, NULL
);
133 return compat_ksys_semtimedop(first
, compat_ptr(ptr
), second
,
136 return ksys_semget(first
, second
, third
);
140 if (get_user(pad
, (u32 __user
*) compat_ptr(ptr
)))
142 return compat_ksys_semctl(first
, second
, third
, pad
);
145 return compat_ksys_msgsnd(first
, ptr
, second
, third
);
148 void __user
*uptr
= compat_ptr(ptr
);
150 if (first
< 0 || second
< 0)
154 struct compat_ipc_kludge ipck
;
157 if (copy_from_user(&ipck
, uptr
, sizeof(ipck
)))
159 return compat_ksys_msgrcv(first
, ipck
.msgp
, second
,
162 return compat_ksys_msgrcv(first
, ptr
, second
, fifth
, third
);
165 return ksys_msgget(first
, second
);
167 return compat_ksys_msgctl(first
, second
, compat_ptr(ptr
));
175 err
= do_shmat(first
, compat_ptr(ptr
), second
, &raddr
,
179 return put_user(raddr
, (compat_ulong_t __user
*)compat_ptr(third
));
182 return ksys_shmdt(compat_ptr(ptr
));
184 return ksys_shmget(first
, (unsigned int)second
, third
);
186 return compat_ksys_shmctl(first
, second
, compat_ptr(ptr
));