Blame view

ipc/syscall.c 5.09 KB
b24413180   Greg Kroah-Hartman   License cleanup: ...
1
  // SPDX-License-Identifier: GPL-2.0
baed7fc9b   Christoph Hellwig   Add generic sys_i...
2
3
4
5
6
7
8
  /*
   * sys_ipc() is the old de-multiplexer for the SysV IPC calls.
   *
   * This is really horribly ugly, and new architectures should just wire up
   * the individual syscalls instead.
   */
  #include <linux/unistd.h>
20bc2a3af   Al Viro   ipc(2): move comp...
9
  #include <linux/syscalls.h>
41f4f0e2f   Dominik Brodowski   ipc: add semtimed...
10
11
12
  #include <linux/security.h>
  #include <linux/ipc_namespace.h>
  #include "util.h"
baed7fc9b   Christoph Hellwig   Add generic sys_i...
13
14
15
16
17
  
  #ifdef __ARCH_WANT_SYS_IPC
  #include <linux/errno.h>
  #include <linux/ipc.h>
  #include <linux/shm.h>
baed7fc9b   Christoph Hellwig   Add generic sys_i...
18
  #include <linux/uaccess.h>
58fa4a410   Arnd Bergmann   ipc: introduce ks...
19
20
  int ksys_ipc(unsigned int call, int first, unsigned long second,
  	unsigned long third, void __user * ptr, long fifth)
baed7fc9b   Christoph Hellwig   Add generic sys_i...
21
22
23
24
25
26
27
28
  {
  	int version, ret;
  
  	version = call >> 16; /* hack for backward compatibility */
  	call &= 0xffff;
  
  	switch (call) {
  	case SEMOP:
41f4f0e2f   Dominik Brodowski   ipc: add semtimed...
29
30
  		return ksys_semtimedop(first, (struct sembuf __user *)ptr,
  				       second, NULL);
baed7fc9b   Christoph Hellwig   Add generic sys_i...
31
  	case SEMTIMEDOP:
5dc0b1529   Arnd Bergmann   y2038: ipc: Redir...
32
33
34
35
36
  		if (IS_ENABLED(CONFIG_64BIT) || !IS_ENABLED(CONFIG_64BIT_TIME))
  			return ksys_semtimedop(first, ptr, second,
  			        (const struct __kernel_timespec __user *)fifth);
  		else if (IS_ENABLED(CONFIG_COMPAT_32BIT_TIME))
  			return compat_ksys_semtimedop(first, ptr, second,
9afc5eee6   Arnd Bergmann   y2038: globally r...
37
  			        (const struct old_timespec32 __user *)fifth);
5dc0b1529   Arnd Bergmann   y2038: ipc: Redir...
38
39
  		else
  			return -ENOSYS;
baed7fc9b   Christoph Hellwig   Add generic sys_i...
40
41
  
  	case SEMGET:
69894718a   Dominik Brodowski   ipc: add semget s...
42
  		return ksys_semget(first, second, third);
baed7fc9b   Christoph Hellwig   Add generic sys_i...
43
  	case SEMCTL: {
e1fd1f490   Al Viro   get rid of union ...
44
  		unsigned long arg;
baed7fc9b   Christoph Hellwig   Add generic sys_i...
45
46
  		if (!ptr)
  			return -EINVAL;
e1fd1f490   Al Viro   get rid of union ...
47
  		if (get_user(arg, (unsigned long __user *) ptr))
baed7fc9b   Christoph Hellwig   Add generic sys_i...
48
  			return -EFAULT;
275f22148   Arnd Bergmann   ipc: rename old-s...
49
  		return ksys_old_semctl(first, second, third, arg);
baed7fc9b   Christoph Hellwig   Add generic sys_i...
50
51
52
  	}
  
  	case MSGSND:
31c213f21   Dominik Brodowski   ipc: add msgsnd s...
53
  		return ksys_msgsnd(first, (struct msgbuf __user *) ptr,
baed7fc9b   Christoph Hellwig   Add generic sys_i...
54
55
56
57
58
59
60
61
62
63
64
65
  				  second, third);
  	case MSGRCV:
  		switch (version) {
  		case 0: {
  			struct ipc_kludge tmp;
  			if (!ptr)
  				return -EINVAL;
  
  			if (copy_from_user(&tmp,
  					   (struct ipc_kludge __user *) ptr,
  					   sizeof(tmp)))
  				return -EFAULT;
078faac9e   Dominik Brodowski   ipc: add msgrcv s...
66
  			return ksys_msgrcv(first, tmp.msgp, second,
baed7fc9b   Christoph Hellwig   Add generic sys_i...
67
68
69
  					   tmp.msgtyp, third);
  		}
  		default:
078faac9e   Dominik Brodowski   ipc: add msgrcv s...
70
  			return ksys_msgrcv(first,
baed7fc9b   Christoph Hellwig   Add generic sys_i...
71
72
73
74
  					   (struct msgbuf __user *) ptr,
  					   second, fifth, third);
  		}
  	case MSGGET:
3d65661a4   Dominik Brodowski   ipc: add msgget s...
75
  		return ksys_msgget((key_t) first, second);
baed7fc9b   Christoph Hellwig   Add generic sys_i...
76
  	case MSGCTL:
275f22148   Arnd Bergmann   ipc: rename old-s...
77
  		return ksys_old_msgctl(first, second,
e340db564   Dominik Brodowski   ipc: add msgctl s...
78
  				   (struct msqid_ds __user *)ptr);
baed7fc9b   Christoph Hellwig   Add generic sys_i...
79
80
81
82
83
84
  
  	case SHMAT:
  		switch (version) {
  		default: {
  			unsigned long raddr;
  			ret = do_shmat(first, (char __user *)ptr,
079a96ae3   Will Deacon   ipc: add COMPAT_S...
85
  				       second, &raddr, SHMLBA);
baed7fc9b   Christoph Hellwig   Add generic sys_i...
86
87
88
89
90
91
92
93
94
95
96
97
  			if (ret)
  				return ret;
  			return put_user(raddr, (unsigned long __user *) third);
  		}
  		case 1:
  			/*
  			 * This was the entry point for kernel-originating calls
  			 * from iBCS2 in 2.2 days.
  			 */
  			return -EINVAL;
  		}
  	case SHMDT:
da1e27443   Dominik Brodowski   ipc: add shmdt sy...
98
  		return ksys_shmdt((char __user *)ptr);
baed7fc9b   Christoph Hellwig   Add generic sys_i...
99
  	case SHMGET:
65749e0bb   Dominik Brodowski   ipc: add shmget s...
100
  		return ksys_shmget(first, second, third);
baed7fc9b   Christoph Hellwig   Add generic sys_i...
101
  	case SHMCTL:
275f22148   Arnd Bergmann   ipc: rename old-s...
102
  		return ksys_old_shmctl(first, second,
baed7fc9b   Christoph Hellwig   Add generic sys_i...
103
104
105
106
107
  				   (struct shmid_ds __user *) ptr);
  	default:
  		return -ENOSYS;
  	}
  }
58fa4a410   Arnd Bergmann   ipc: introduce ks...
108
109
110
111
112
113
  
  SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second,
  		unsigned long, third, void __user *, ptr, long, fifth)
  {
  	return ksys_ipc(call, first, second, third, ptr, fifth);
  }
baed7fc9b   Christoph Hellwig   Add generic sys_i...
114
  #endif
20bc2a3af   Al Viro   ipc(2): move comp...
115
116
117
118
119
120
121
122
123
124
125
126
127
128
  
  #ifdef CONFIG_COMPAT
  #include <linux/compat.h>
  
  #ifndef COMPAT_SHMLBA
  #define COMPAT_SHMLBA	SHMLBA
  #endif
  
  struct compat_ipc_kludge {
  	compat_uptr_t msgp;
  	compat_long_t msgtyp;
  };
  
  #ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC
58fa4a410   Arnd Bergmann   ipc: introduce ks...
129
130
  int compat_ksys_ipc(u32 call, int first, int second,
  	u32 third, compat_uptr_t ptr, u32 fifth)
20bc2a3af   Al Viro   ipc(2): move comp...
131
132
133
134
135
136
137
138
139
140
  {
  	int version;
  	u32 pad;
  
  	version = call >> 16; /* hack for backward compatibility */
  	call &= 0xffff;
  
  	switch (call) {
  	case SEMOP:
  		/* struct sembuf is the same on 32 and 64bit :)) */
41f4f0e2f   Dominik Brodowski   ipc: add semtimed...
141
  		return ksys_semtimedop(first, compat_ptr(ptr), second, NULL);
20bc2a3af   Al Viro   ipc(2): move comp...
142
  	case SEMTIMEDOP:
5dc0b1529   Arnd Bergmann   y2038: ipc: Redir...
143
144
  		if (!IS_ENABLED(CONFIG_COMPAT_32BIT_TIME))
  			return -ENOSYS;
41f4f0e2f   Dominik Brodowski   ipc: add semtimed...
145
  		return compat_ksys_semtimedop(first, compat_ptr(ptr), second,
20bc2a3af   Al Viro   ipc(2): move comp...
146
147
  						compat_ptr(fifth));
  	case SEMGET:
69894718a   Dominik Brodowski   ipc: add semget s...
148
  		return ksys_semget(first, second, third);
20bc2a3af   Al Viro   ipc(2): move comp...
149
150
151
152
153
  	case SEMCTL:
  		if (!ptr)
  			return -EINVAL;
  		if (get_user(pad, (u32 __user *) compat_ptr(ptr)))
  			return -EFAULT;
275f22148   Arnd Bergmann   ipc: rename old-s...
154
  		return compat_ksys_old_semctl(first, second, third, pad);
20bc2a3af   Al Viro   ipc(2): move comp...
155
156
  
  	case MSGSND:
31c213f21   Dominik Brodowski   ipc: add msgsnd s...
157
  		return compat_ksys_msgsnd(first, ptr, second, third);
20bc2a3af   Al Viro   ipc(2): move comp...
158
159
160
161
162
163
164
165
166
167
168
169
170
  
  	case MSGRCV: {
  		void __user *uptr = compat_ptr(ptr);
  
  		if (first < 0 || second < 0)
  			return -EINVAL;
  
  		if (!version) {
  			struct compat_ipc_kludge ipck;
  			if (!uptr)
  				return -EINVAL;
  			if (copy_from_user(&ipck, uptr, sizeof(ipck)))
  				return -EFAULT;
078faac9e   Dominik Brodowski   ipc: add msgrcv s...
171
  			return compat_ksys_msgrcv(first, ipck.msgp, second,
20bc2a3af   Al Viro   ipc(2): move comp...
172
173
  						 ipck.msgtyp, third);
  		}
078faac9e   Dominik Brodowski   ipc: add msgrcv s...
174
  		return compat_ksys_msgrcv(first, ptr, second, fifth, third);
20bc2a3af   Al Viro   ipc(2): move comp...
175
176
  	}
  	case MSGGET:
3d65661a4   Dominik Brodowski   ipc: add msgget s...
177
  		return ksys_msgget(first, second);
20bc2a3af   Al Viro   ipc(2): move comp...
178
  	case MSGCTL:
275f22148   Arnd Bergmann   ipc: rename old-s...
179
  		return compat_ksys_old_msgctl(first, second, compat_ptr(ptr));
20bc2a3af   Al Viro   ipc(2): move comp...
180
181
182
183
184
185
186
187
188
189
190
  
  	case SHMAT: {
  		int err;
  		unsigned long raddr;
  
  		if (version == 1)
  			return -EINVAL;
  		err = do_shmat(first, compat_ptr(ptr), second, &raddr,
  			       COMPAT_SHMLBA);
  		if (err < 0)
  			return err;
6aa211e8c   Linus Torvalds   fix address space...
191
  		return put_user(raddr, (compat_ulong_t __user *)compat_ptr(third));
20bc2a3af   Al Viro   ipc(2): move comp...
192
193
  	}
  	case SHMDT:
da1e27443   Dominik Brodowski   ipc: add shmdt sy...
194
  		return ksys_shmdt(compat_ptr(ptr));
20bc2a3af   Al Viro   ipc(2): move comp...
195
  	case SHMGET:
65749e0bb   Dominik Brodowski   ipc: add shmget s...
196
  		return ksys_shmget(first, (unsigned int)second, third);
20bc2a3af   Al Viro   ipc(2): move comp...
197
  	case SHMCTL:
275f22148   Arnd Bergmann   ipc: rename old-s...
198
  		return compat_ksys_old_shmctl(first, second, compat_ptr(ptr));
20bc2a3af   Al Viro   ipc(2): move comp...
199
200
201
202
  	}
  
  	return -ENOSYS;
  }
58fa4a410   Arnd Bergmann   ipc: introduce ks...
203
204
205
206
207
208
  
  COMPAT_SYSCALL_DEFINE6(ipc, u32, call, int, first, int, second,
  	u32, third, compat_uptr_t, ptr, u32, fifth)
  {
  	return compat_ksys_ipc(call, first, second, third, ptr, fifth);
  }
20bc2a3af   Al Viro   ipc(2): move comp...
209
210
  #endif
  #endif