Blame view

ipc/util.h 8.8 KB
b24413180   Greg Kroah-Hartman   License cleanup: ...
1
  /* SPDX-License-Identifier: GPL-2.0 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
5
  /*
   * linux/ipc/util.h
   * Copyright (C) 1999 Christoph Rohland
   *
624dffcbc   Christian Kujau   correct email add...
6
   * ipc helper functions (c) 1999 Manfred Spraul <manfred@colorfullife.com>
73ea41302   Kirill Korotaev   [PATCH] IPC names...
7
8
   * namespaces support.      2006 OpenVZ, SWsoft Inc.
   *                               Pavel Emelianov <xemul@openvz.org>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
9
10
11
12
   */
  
  #ifndef _IPC_UTIL_H
  #define _IPC_UTIL_H
232086b19   Johannes Weiner   ipc: unbreak 32-b...
13
  #include <linux/unistd.h>
023a53557   Nadia Derbey   ipc: integrate ip...
14
  #include <linux/err.h>
15df03c87   Davidlohr Bueso   sysvipc: make get...
15
  #include <linux/ipc_namespace.h>
7ca7e564e   Nadia Derbey   ipc: store ipcs i...
16

f83a396d0   Eric W. Biederman   ipc: Move IPCMNI ...
17
  #define IPCMNI 32768  /* <= MAX_INT limit for ipc arrays (including sysctl changes) */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
18
  #define SEQ_MULTIPLIER	(IPCMNI)
eae04d25a   Davidlohr Bueso   ipc: simplify ipc...
19
20
  void sem_init(void);
  void msg_init(void);
239521f31   Manfred Spraul   ipc: whitespace c...
21
  void shm_init(void);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
22

ae5e1b22f   Pavel Emelyanov   namespaces: move ...
23
  struct ipc_namespace;
03f1fc091   Eric W. Biederman   ipc/util: Helpers...
24
  struct pid_namespace;
ae5e1b22f   Pavel Emelyanov   namespaces: move ...
25

614b84cf4   Serge E. Hallyn   namespaces: mqueu...
26
  #ifdef CONFIG_POSIX_MQUEUE
7eafd7c74   Serge E. Hallyn   namespaces: ipc n...
27
28
  extern void mq_clear_sbinfo(struct ipc_namespace *ns);
  extern void mq_put_mnt(struct ipc_namespace *ns);
614b84cf4   Serge E. Hallyn   namespaces: mqueu...
29
  #else
7eafd7c74   Serge E. Hallyn   namespaces: ipc n...
30
31
  static inline void mq_clear_sbinfo(struct ipc_namespace *ns) { }
  static inline void mq_put_mnt(struct ipc_namespace *ns) { }
614b84cf4   Serge E. Hallyn   namespaces: mqueu...
32
33
34
  #endif
  
  #ifdef CONFIG_SYSVIPC
eae04d25a   Davidlohr Bueso   ipc: simplify ipc...
35
36
37
  void sem_init_ns(struct ipc_namespace *ns);
  void msg_init_ns(struct ipc_namespace *ns);
  void shm_init_ns(struct ipc_namespace *ns);
73ea41302   Kirill Korotaev   [PATCH] IPC names...
38
39
40
41
  
  void sem_exit_ns(struct ipc_namespace *ns);
  void msg_exit_ns(struct ipc_namespace *ns);
  void shm_exit_ns(struct ipc_namespace *ns);
614b84cf4   Serge E. Hallyn   namespaces: mqueu...
42
  #else
eae04d25a   Davidlohr Bueso   ipc: simplify ipc...
43
44
45
  static inline void sem_init_ns(struct ipc_namespace *ns) { }
  static inline void msg_init_ns(struct ipc_namespace *ns) { }
  static inline void shm_init_ns(struct ipc_namespace *ns) { }
614b84cf4   Serge E. Hallyn   namespaces: mqueu...
46
47
48
49
50
  
  static inline void sem_exit_ns(struct ipc_namespace *ns) { }
  static inline void msg_exit_ns(struct ipc_namespace *ns) { }
  static inline void shm_exit_ns(struct ipc_namespace *ns) { }
  #endif
73ea41302   Kirill Korotaev   [PATCH] IPC names...
51

7748dbfaa   Nadia Derbey   ipc: unify the sy...
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
  /*
   * Structure that holds the parameters needed by the ipc operations
   * (see after)
   */
  struct ipc_params {
  	key_t key;
  	int flg;
  	union {
  		size_t size;	/* for shared memories */
  		int nsems;	/* for semaphores */
  	} u;			/* holds the getnew() specific param */
  };
  
  /*
   * Structure that holds some ipc operations. This structure is used to unify
   * the calls to sys_msgget(), sys_semget(), sys_shmget()
   *      . routine to call to create a new ipc object. Can be one of newque,
   *        newary, newseg
f4566f048   Nadia Derbey   ipc: fix wrong co...
70
   *      . routine to call to check permissions for a new ipc object.
7748dbfaa   Nadia Derbey   ipc: unify the sy...
71
72
73
74
75
   *        Can be one of security_msg_associate, security_sem_associate,
   *        security_shm_associate
   *      . routine to call for an extra check if needed
   */
  struct ipc_ops {
46c0a8ca3   Paul McQuade   ipc, kernel: clea...
76
77
78
  	int (*getnew)(struct ipc_namespace *, struct ipc_params *);
  	int (*associate)(struct kern_ipc_perm *, int);
  	int (*more_checks)(struct kern_ipc_perm *, struct ipc_params *);
7748dbfaa   Nadia Derbey   ipc: unify the sy...
79
  };
ae7817745   Mike Waychison   [PATCH] ipc: add ...
80
  struct seq_file;
ed2ddbf88   Pierre Peiffer   IPC: make struct ...
81
  struct ipc_ids;
7d69a1f4a   Cedric Le Goater   remove CONFIG_UTS...
82

eae04d25a   Davidlohr Bueso   ipc: simplify ipc...
83
  void ipc_init_ids(struct ipc_ids *ids);
ae7817745   Mike Waychison   [PATCH] ipc: add ...
84
85
  #ifdef CONFIG_PROC_FS
  void __init ipc_init_proc_interface(const char *path, const char *header,
73ea41302   Kirill Korotaev   [PATCH] IPC names...
86
  		int ids, int (*show)(struct seq_file *, void *));
03f1fc091   Eric W. Biederman   ipc/util: Helpers...
87
  struct pid_namespace *ipc_seq_pid_ns(struct seq_file *);
ae7817745   Mike Waychison   [PATCH] ipc: add ...
88
89
90
  #else
  #define ipc_init_proc_interface(path, header, ids, show) do {} while (0)
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
91

73ea41302   Kirill Korotaev   [PATCH] IPC names...
92
93
94
  #define IPC_SEM_IDS	0
  #define IPC_MSG_IDS	1
  #define IPC_SHM_IDS	2
ce621f5ba   Nadia Derbey   ipc: introduce th...
95
  #define ipcid_to_idx(id) ((id) % SEQ_MULTIPLIER)
03f595668   Stanislav Kinsbursky   ipc: add sysctl t...
96
  #define ipcid_to_seqx(id) ((id) / SEQ_MULTIPLIER)
daf948c7d   Davidlohr Bueso   ipc: delete seq_m...
97
  #define IPCID_SEQ_MAX min_t(int, INT_MAX/SEQ_MULTIPLIER, USHRT_MAX)
ce621f5ba   Nadia Derbey   ipc: introduce th...
98

d9a605e40   Davidlohr Bueso   ipc: rename ids->...
99
  /* must be called with ids->rwsem acquired for writing */
7ca7e564e   Nadia Derbey   ipc: store ipcs i...
100
  int ipc_addid(struct ipc_ids *, struct kern_ipc_perm *, int);
3e148c799   Nadia Derbey   fix idr_find() lo...
101

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
102
  /* must be called with both locks acquired. */
7ca7e564e   Nadia Derbey   ipc: store ipcs i...
103
  void ipc_rmid(struct ipc_ids *, struct kern_ipc_perm *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
104

0cfb6aee7   Guillaume Knispel   ipc: optimize sem...
105
106
  /* must be called with both locks acquired. */
  void ipc_set_key_private(struct ipc_ids *, struct kern_ipc_perm *);
f4566f048   Nadia Derbey   ipc: fix wrong co...
107
  /* must be called with ipcp locked */
b0e77598f   Serge E. Hallyn   userns: user name...
108
  int ipcperms(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp, short flg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
109

15df03c87   Davidlohr Bueso   sysvipc: make get...
110
  /**
27c331a17   Manfred Spraul   ipc/util.c: furth...
111
   * ipc_get_maxidx - get the highest assigned index
15df03c87   Davidlohr Bueso   sysvipc: make get...
112
113
114
115
   * @ids: ipc identifier set
   *
   * Called with ipc_ids.rwsem held for reading.
   */
27c331a17   Manfred Spraul   ipc/util.c: furth...
116
  static inline int ipc_get_maxidx(struct ipc_ids *ids)
15df03c87   Davidlohr Bueso   sysvipc: make get...
117
118
119
120
121
122
  {
  	if (ids->in_use == 0)
  		return -1;
  
  	if (ids->in_use == IPCMNI)
  		return IPCMNI - 1;
27c331a17   Manfred Spraul   ipc/util.c: furth...
123
  	return ids->max_idx;
15df03c87   Davidlohr Bueso   sysvipc: make get...
124
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
125
126
127
128
129
  /*
   * For allocation that need to be freed by RCU.
   * Objects are reference counted, they start with reference count 1.
   * getref increases the refcount, the putref call that reduces the recount
   * to 0 schedules the rcu destruction. Caller must guarantee locking.
62b49c990   Manfred Spraul   ipc/util.h: updat...
130
131
132
   *
   * refcount is initialized by ipc_addid(), before that point call_rcu()
   * must be used.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
133
   */
2a9d64810   Manfred Spraul   ipc/util.c: updat...
134
  bool ipc_rcu_getref(struct kern_ipc_perm *ptr);
dba4cdd39   Manfred Spraul   ipc: merge ipc_rc...
135
136
  void ipc_rcu_putref(struct kern_ipc_perm *ptr,
  			void (*func)(struct rcu_head *head));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
137

55b7ae501   Davidlohr Bueso   ipc: rename ipc_o...
138
  struct kern_ipc_perm *ipc_obtain_object_idr(struct ipc_ids *ids, int id);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
139
140
141
  
  void kernel_to_ipc64_perm(struct kern_ipc_perm *in, struct ipc64_perm *out);
  void ipc64_perm_to_ipc_perm(struct ipc64_perm *in, struct ipc_perm *out);
1efdb69b0   Eric W. Biederman   userns: Convert i...
142
  int ipc_update_perm(struct ipc64_perm *in, struct kern_ipc_perm *out);
4241c1a30   Manfred Spraul   ipc: rename ipcct...
143
  struct kern_ipc_perm *ipcctl_obtain_check(struct ipc_namespace *ns,
444d0f621   Davidlohr Bueso   ipc: introduce lo...
144
145
  					     struct ipc_ids *ids, int id, int cmd,
  					     struct ipc64_perm *perm, int extra_perm);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
146

03f1fc091   Eric W. Biederman   ipc/util: Helpers...
147
148
149
150
151
152
153
154
  static inline void ipc_update_pid(struct pid **pos, struct pid *pid)
  {
  	struct pid *old = *pos;
  	if (old != pid) {
  		*pos = get_pid(pid);
  		put_pid(old);
  	}
  }
c1d7e01d7   Will Deacon   ipc: use Kconfig ...
155
  #ifndef CONFIG_ARCH_WANT_IPC_PARSE_VERSION
46c0a8ca3   Paul McQuade   ipc, kernel: clea...
156
  /* On IA-64, we always use the "64-bit version" of the IPC structures.  */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
157
158
  # define ipc_parse_version(cmd)	IPC_64
  #else
239521f31   Manfred Spraul   ipc: whitespace c...
159
  int ipc_parse_version(int *cmd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
160
161
162
  #endif
  
  extern void free_msg(struct msg_msg *msg);
4e9b45a19   Mathias Krause   ipc, msg: fix mes...
163
  extern struct msg_msg *load_msg(const void __user *src, size_t len);
4a674f34b   Stanislav Kinsbursky   ipc: introduce me...
164
  extern struct msg_msg *copy_msg(struct msg_msg *src, struct msg_msg *dst);
4e9b45a19   Mathias Krause   ipc, msg: fix mes...
165
  extern int store_msg(void __user *dest, struct msg_msg *msg, size_t len);
7748dbfaa   Nadia Derbey   ipc: unify the sy...
166

27c331a17   Manfred Spraul   ipc/util.c: furth...
167
  static inline int ipc_checkid(struct kern_ipc_perm *ipcp, int id)
023a53557   Nadia Derbey   ipc: integrate ip...
168
  {
27c331a17   Manfred Spraul   ipc/util.c: furth...
169
  	return ipcid_to_seqx(id) != ipcp->seq;
023a53557   Nadia Derbey   ipc: integrate ip...
170
  }
1ca7003ab   Davidlohr Bueso   ipc: introduce ip...
171
  static inline void ipc_lock_object(struct kern_ipc_perm *perm)
023a53557   Nadia Derbey   ipc: integrate ip...
172
  {
023a53557   Nadia Derbey   ipc: integrate ip...
173
174
  	spin_lock(&perm->lock);
  }
1ca7003ab   Davidlohr Bueso   ipc: introduce ip...
175
  static inline void ipc_unlock_object(struct kern_ipc_perm *perm)
023a53557   Nadia Derbey   ipc: integrate ip...
176
177
  {
  	spin_unlock(&perm->lock);
023a53557   Nadia Derbey   ipc: integrate ip...
178
  }
1ca7003ab   Davidlohr Bueso   ipc: introduce ip...
179
  static inline void ipc_assert_locked_object(struct kern_ipc_perm *perm)
16df3674e   Davidlohr Bueso   ipc,sem: do not h...
180
  {
1ca7003ab   Davidlohr Bueso   ipc: introduce ip...
181
182
  	assert_spin_locked(&perm->lock);
  }
1ca7003ab   Davidlohr Bueso   ipc: introduce ip...
183
184
  static inline void ipc_unlock(struct kern_ipc_perm *perm)
  {
cf9d5d78d   Davidlohr Bueso   ipc: close open c...
185
  	ipc_unlock_object(perm);
1ca7003ab   Davidlohr Bueso   ipc: introduce ip...
186
187
  	rcu_read_unlock();
  }
0f3d2b013   Rafael Aquini   ipc: introduce ip...
188
189
190
191
192
193
194
195
196
197
  /*
   * ipc_valid_object() - helper to sort out IPC_RMID races for codepaths
   * where the respective ipc_ids.rwsem is not being held down.
   * Checks whether the ipc object is still around or if it's gone already, as
   * ipc_rmid() may have already freed the ID while the ipc lock was spinning.
   * Needs to be called with kern_ipc_perm.lock held -- exception made for one
   * checkpoint case at sys_semtimedop() as noted in code commentary.
   */
  static inline bool ipc_valid_object(struct kern_ipc_perm *perm)
  {
72a8ff2f9   Rafael Aquini   ipc: change kern_...
198
  	return !perm->deleted;
0f3d2b013   Rafael Aquini   ipc: introduce ip...
199
  }
4d2bff5eb   Davidlohr Bueso   ipc: introduce ob...
200
  struct kern_ipc_perm *ipc_obtain_object_check(struct ipc_ids *ids, int id);
b2d75cddc   Pavel Emelyanov   ipc: uninline som...
201
  int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids,
eb66ec44f   Mathias Krause   ipc: constify ipc...
202
  			const struct ipc_ops *ops, struct ipc_params *params);
665c7741f   Alexey Dobriyan   ipcns: move free_...
203
204
  void free_ipcs(struct ipc_namespace *ns, struct ipc_ids *ids,
  		void (*free)(struct ipc_namespace *, struct kern_ipc_perm *));
553f770ef   Al Viro   ipc: move compat ...
205
206
207
208
209
210
211
212
213
214
215
216
  
  #ifdef CONFIG_COMPAT
  #include <linux/compat.h>
  struct compat_ipc_perm {
  	key_t key;
  	__compat_uid_t uid;
  	__compat_gid_t gid;
  	__compat_uid_t cuid;
  	__compat_gid_t cgid;
  	compat_mode_t mode;
  	unsigned short seq;
  };
c0ebccb6f   Al Viro   semctl(): move co...
217
218
219
220
221
  void to_compat_ipc_perm(struct compat_ipc_perm *, struct ipc64_perm *);
  void to_compat_ipc64_perm(struct compat_ipc64_perm *, struct ipc64_perm *);
  int get_compat_ipc_perm(struct ipc64_perm *, struct compat_ipc_perm __user *);
  int get_compat_ipc64_perm(struct ipc64_perm *,
  			  struct compat_ipc64_perm __user *);
553f770ef   Al Viro   ipc: move compat ...
222
223
224
225
226
227
228
229
230
231
232
  static inline int compat_ipc_parse_version(int *cmd)
  {
  #ifdef	CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION
  	int version = *cmd & IPC_64;
  	*cmd &= ~IPC_64;
  	return version;
  #else
  	return IPC_64;
  #endif
  }
  #endif
41f4f0e2f   Dominik Brodowski   ipc: add semtimed...
233
234
235
236
  
  /* for __ARCH_WANT_SYS_IPC */
  long ksys_semtimedop(int semid, struct sembuf __user *tsops,
  		     unsigned int nsops,
21fc538d8   Arnd Bergmann   y2038: ipc: Use _...
237
  		     const struct __kernel_timespec __user *timeout);
69894718a   Dominik Brodowski   ipc: add semget s...
238
  long ksys_semget(key_t key, int nsems, int semflg);
d969c6fa7   Dominik Brodowski   ipc: add semctl s...
239
  long ksys_semctl(int semid, int semnum, int cmd, unsigned long arg);
3d65661a4   Dominik Brodowski   ipc: add msgget s...
240
  long ksys_msgget(key_t key, int msgflg);
e340db564   Dominik Brodowski   ipc: add msgctl s...
241
  long ksys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf);
078faac9e   Dominik Brodowski   ipc: add msgrcv s...
242
243
  long ksys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz,
  		 long msgtyp, int msgflg);
31c213f21   Dominik Brodowski   ipc: add msgsnd s...
244
245
  long ksys_msgsnd(int msqid, struct msgbuf __user *msgp, size_t msgsz,
  		 int msgflg);
65749e0bb   Dominik Brodowski   ipc: add shmget s...
246
  long ksys_shmget(key_t key, size_t size, int shmflg);
da1e27443   Dominik Brodowski   ipc: add shmdt sy...
247
  long ksys_shmdt(char __user *shmaddr);
c84d0791d   Dominik Brodowski   ipc: add shmctl s...
248
  long ksys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf);
41f4f0e2f   Dominik Brodowski   ipc: add semtimed...
249
250
  
  /* for CONFIG_ARCH_WANT_OLD_COMPAT_IPC */
41f4f0e2f   Dominik Brodowski   ipc: add semtimed...
251
252
253
  long compat_ksys_semtimedop(int semid, struct sembuf __user *tsems,
  			    unsigned int nsops,
  			    const struct compat_timespec __user *timeout);
b0d175781   Arnd Bergmann   y2038: ipc: Enabl...
254
  #ifdef CONFIG_COMPAT
d969c6fa7   Dominik Brodowski   ipc: add semctl s...
255
  long compat_ksys_semctl(int semid, int semnum, int cmd, int arg);
e340db564   Dominik Brodowski   ipc: add msgctl s...
256
  long compat_ksys_msgctl(int msqid, int cmd, void __user *uptr);
078faac9e   Dominik Brodowski   ipc: add msgrcv s...
257
258
  long compat_ksys_msgrcv(int msqid, compat_uptr_t msgp, compat_ssize_t msgsz,
  			compat_long_t msgtyp, int msgflg);
31c213f21   Dominik Brodowski   ipc: add msgsnd s...
259
260
  long compat_ksys_msgsnd(int msqid, compat_uptr_t msgp,
  		       compat_ssize_t msgsz, int msgflg);
c84d0791d   Dominik Brodowski   ipc: add shmctl s...
261
  long compat_ksys_shmctl(int shmid, int cmd, void __user *uptr);
41f4f0e2f   Dominik Brodowski   ipc: add semtimed...
262
  #endif /* CONFIG_COMPAT */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
263
  #endif