hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/ipc/util.h
....@@ -15,8 +15,37 @@
1515 #include <linux/err.h>
1616 #include <linux/ipc_namespace.h>
1717
18
-#define IPCMNI 32768 /* <= MAX_INT limit for ipc arrays (including sysctl changes) */
19
-#define SEQ_MULTIPLIER (IPCMNI)
18
+/*
19
+ * The IPC ID contains 2 separate numbers - index and sequence number.
20
+ * By default,
21
+ * bits 0-14: index (32k, 15 bits)
22
+ * bits 15-30: sequence number (64k, 16 bits)
23
+ *
24
+ * When IPCMNI extension mode is turned on, the composition changes:
25
+ * bits 0-23: index (16M, 24 bits)
26
+ * bits 24-30: sequence number (128, 7 bits)
27
+ */
28
+#define IPCMNI_SHIFT 15
29
+#define IPCMNI_EXTEND_SHIFT 24
30
+#define IPCMNI_EXTEND_MIN_CYCLE (RADIX_TREE_MAP_SIZE * RADIX_TREE_MAP_SIZE)
31
+#define IPCMNI (1 << IPCMNI_SHIFT)
32
+#define IPCMNI_EXTEND (1 << IPCMNI_EXTEND_SHIFT)
33
+
34
+#ifdef CONFIG_SYSVIPC_SYSCTL
35
+extern int ipc_mni;
36
+extern int ipc_mni_shift;
37
+extern int ipc_min_cycle;
38
+
39
+#define ipcmni_seq_shift() ipc_mni_shift
40
+#define IPCMNI_IDX_MASK ((1 << ipc_mni_shift) - 1)
41
+
42
+#else /* CONFIG_SYSVIPC_SYSCTL */
43
+
44
+#define ipc_mni IPCMNI
45
+#define ipc_min_cycle ((int)RADIX_TREE_MAP_SIZE)
46
+#define ipcmni_seq_shift() IPCMNI_SHIFT
47
+#define IPCMNI_IDX_MASK ((1 << IPCMNI_SHIFT) - 1)
48
+#endif /* CONFIG_SYSVIPC_SYSCTL */
2049
2150 void sem_init(void);
2251 void msg_init(void);
....@@ -96,9 +125,9 @@
96125 #define IPC_MSG_IDS 1
97126 #define IPC_SHM_IDS 2
98127
99
-#define ipcid_to_idx(id) ((id) % SEQ_MULTIPLIER)
100
-#define ipcid_to_seqx(id) ((id) / SEQ_MULTIPLIER)
101
-#define IPCID_SEQ_MAX min_t(int, INT_MAX/SEQ_MULTIPLIER, USHRT_MAX)
128
+#define ipcid_to_idx(id) ((id) & IPCMNI_IDX_MASK)
129
+#define ipcid_to_seqx(id) ((id) >> ipcmni_seq_shift())
130
+#define ipcid_seq_max() (INT_MAX >> ipcmni_seq_shift())
102131
103132 /* must be called with ids->rwsem acquired for writing */
104133 int ipc_addid(struct ipc_ids *, struct kern_ipc_perm *, int);
....@@ -123,8 +152,8 @@
123152 if (ids->in_use == 0)
124153 return -1;
125154
126
- if (ids->in_use == IPCMNI)
127
- return IPCMNI - 1;
155
+ if (ids->in_use == ipc_mni)
156
+ return ipc_mni - 1;
128157
129158 return ids->max_idx;
130159 }
....@@ -160,10 +189,7 @@
160189 }
161190 }
162191
163
-#ifndef CONFIG_ARCH_WANT_IPC_PARSE_VERSION
164
-/* On IA-64, we always use the "64-bit version" of the IPC structures. */
165
-# define ipc_parse_version(cmd) IPC_64
166
-#else
192
+#ifdef CONFIG_ARCH_WANT_IPC_PARSE_VERSION
167193 int ipc_parse_version(int *cmd);
168194 #endif
169195
....@@ -217,6 +243,15 @@
217243 void free_ipcs(struct ipc_namespace *ns, struct ipc_ids *ids,
218244 void (*free)(struct ipc_namespace *, struct kern_ipc_perm *));
219245
246
+static inline int sem_check_semmni(struct ipc_namespace *ns) {
247
+ /*
248
+ * Check semmni range [0, ipc_mni]
249
+ * semmni is the last element of sem_ctls[4] array
250
+ */
251
+ return ((ns->sem_ctls[3] < 0) || (ns->sem_ctls[3] > ipc_mni))
252
+ ? -ERANGE : 0;
253
+}
254
+
220255 #ifdef CONFIG_COMPAT
221256 #include <linux/compat.h>
222257 struct compat_ipc_perm {
....@@ -237,44 +272,19 @@
237272
238273 static inline int compat_ipc_parse_version(int *cmd)
239274 {
240
-#ifdef CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION
241275 int version = *cmd & IPC_64;
242276 *cmd &= ~IPC_64;
243277 return version;
244
-#else
245
- return IPC_64;
246
-#endif
247278 }
248
-#endif
249279
250
-/* for __ARCH_WANT_SYS_IPC */
251
-long ksys_semtimedop(int semid, struct sembuf __user *tsops,
252
- unsigned int nsops,
253
- const struct __kernel_timespec __user *timeout);
254
-long ksys_semget(key_t key, int nsems, int semflg);
255
-long ksys_semctl(int semid, int semnum, int cmd, unsigned long arg);
256
-long ksys_msgget(key_t key, int msgflg);
257
-long ksys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf);
258
-long ksys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz,
259
- long msgtyp, int msgflg);
260
-long ksys_msgsnd(int msqid, struct msgbuf __user *msgp, size_t msgsz,
261
- int msgflg);
262
-long ksys_shmget(key_t key, size_t size, int shmflg);
263
-long ksys_shmdt(char __user *shmaddr);
264
-long ksys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf);
265
-
266
-/* for CONFIG_ARCH_WANT_OLD_COMPAT_IPC */
267
-long compat_ksys_semtimedop(int semid, struct sembuf __user *tsems,
268
- unsigned int nsops,
269
- const struct compat_timespec __user *timeout);
270
-#ifdef CONFIG_COMPAT
271
-long compat_ksys_semctl(int semid, int semnum, int cmd, int arg);
272
-long compat_ksys_msgctl(int msqid, int cmd, void __user *uptr);
280
+long compat_ksys_old_semctl(int semid, int semnum, int cmd, int arg);
281
+long compat_ksys_old_msgctl(int msqid, int cmd, void __user *uptr);
273282 long compat_ksys_msgrcv(int msqid, compat_uptr_t msgp, compat_ssize_t msgsz,
274283 compat_long_t msgtyp, int msgflg);
275284 long compat_ksys_msgsnd(int msqid, compat_uptr_t msgp,
276285 compat_ssize_t msgsz, int msgflg);
277
-long compat_ksys_shmctl(int shmid, int cmd, void __user *uptr);
278
-#endif /* CONFIG_COMPAT */
286
+long compat_ksys_old_shmctl(int shmid, int cmd, void __user *uptr);
287
+
288
+#endif
279289
280290 #endif