xref: /linux/ipc/util.h (revision efad798b9f01300565f65058b153250cc49d58f2)
1  /*
2   * linux/ipc/util.h
3   * Copyright (C) 1999 Christoph Rohland
4   *
5   * ipc helper functions (c) 1999 Manfred Spraul <manfred@colorfullife.com>
6   * namespaces support.      2006 OpenVZ, SWsoft Inc.
7   *                               Pavel Emelianov <xemul@openvz.org>
8   */
9  
10  #ifndef _IPC_UTIL_H
11  #define _IPC_UTIL_H
12  
13  #include <linux/idr.h>
14  #include <linux/err.h>
15  
16  #define USHRT_MAX 0xffff
17  #define SEQ_MULTIPLIER	(IPCMNI)
18  
19  void sem_init (void);
20  void msg_init (void);
21  void shm_init (void);
22  
23  int sem_init_ns(struct ipc_namespace *ns);
24  int msg_init_ns(struct ipc_namespace *ns);
25  int shm_init_ns(struct ipc_namespace *ns);
26  
27  void sem_exit_ns(struct ipc_namespace *ns);
28  void msg_exit_ns(struct ipc_namespace *ns);
29  void shm_exit_ns(struct ipc_namespace *ns);
30  
31  struct ipc_ids {
32  	int in_use;
33  	unsigned short seq;
34  	unsigned short seq_max;
35  	struct rw_semaphore rw_mutex;
36  	struct idr ipcs_idr;
37  };
38  
39  /*
40   * Structure that holds the parameters needed by the ipc operations
41   * (see after)
42   */
43  struct ipc_params {
44  	key_t key;
45  	int flg;
46  	union {
47  		size_t size;	/* for shared memories */
48  		int nsems;	/* for semaphores */
49  	} u;			/* holds the getnew() specific param */
50  };
51  
52  /*
53   * Structure that holds some ipc operations. This structure is used to unify
54   * the calls to sys_msgget(), sys_semget(), sys_shmget()
55   *      . routine to call to create a new ipc object. Can be one of newque,
56   *        newary, newseg
57   *      . routine to call to check permissions for a new ipc object.
58   *        Can be one of security_msg_associate, security_sem_associate,
59   *        security_shm_associate
60   *      . routine to call for an extra check if needed
61   */
62  struct ipc_ops {
63  	int (*getnew) (struct ipc_namespace *, struct ipc_params *);
64  	int (*associate) (struct kern_ipc_perm *, int);
65  	int (*more_checks) (struct kern_ipc_perm *, struct ipc_params *);
66  };
67  
68  struct seq_file;
69  
70  void ipc_init_ids(struct ipc_ids *);
71  #ifdef CONFIG_PROC_FS
72  void __init ipc_init_proc_interface(const char *path, const char *header,
73  		int ids, int (*show)(struct seq_file *, void *));
74  #else
75  #define ipc_init_proc_interface(path, header, ids, show) do {} while (0)
76  #endif
77  
78  #define IPC_SEM_IDS	0
79  #define IPC_MSG_IDS	1
80  #define IPC_SHM_IDS	2
81  
82  #define ipcid_to_idx(id) ((id) % SEQ_MULTIPLIER)
83  
84  /* must be called with ids->rw_mutex acquired for writing */
85  int ipc_addid(struct ipc_ids *, struct kern_ipc_perm *, int);
86  
87  /* must be called with ids->rw_mutex acquired for reading */
88  int ipc_get_maxid(struct ipc_ids *);
89  
90  /* must be called with both locks acquired. */
91  void ipc_rmid(struct ipc_ids *, struct kern_ipc_perm *);
92  
93  /* must be called with ipcp locked */
94  int ipcperms(struct kern_ipc_perm *ipcp, short flg);
95  
96  /* for rare, potentially huge allocations.
97   * both function can sleep
98   */
99  void* ipc_alloc(int size);
100  void ipc_free(void* ptr, int size);
101  
102  /*
103   * For allocation that need to be freed by RCU.
104   * Objects are reference counted, they start with reference count 1.
105   * getref increases the refcount, the putref call that reduces the recount
106   * to 0 schedules the rcu destruction. Caller must guarantee locking.
107   */
108  void* ipc_rcu_alloc(int size);
109  void ipc_rcu_getref(void *ptr);
110  void ipc_rcu_putref(void *ptr);
111  
112  /*
113   * ipc_lock_down: called with rw_mutex held
114   * ipc_lock: called without that lock held
115   */
116  struct kern_ipc_perm *ipc_lock_down(struct ipc_ids *, int);
117  struct kern_ipc_perm *ipc_lock(struct ipc_ids *, int);
118  
119  void kernel_to_ipc64_perm(struct kern_ipc_perm *in, struct ipc64_perm *out);
120  void ipc64_perm_to_ipc_perm(struct ipc64_perm *in, struct ipc_perm *out);
121  
122  #if defined(__ia64__) || defined(__x86_64__) || defined(__hppa__) || defined(__XTENSA__)
123    /* On IA-64, we always use the "64-bit version" of the IPC structures.  */
124  # define ipc_parse_version(cmd)	IPC_64
125  #else
126  int ipc_parse_version (int *cmd);
127  #endif
128  
129  extern void free_msg(struct msg_msg *msg);
130  extern struct msg_msg *load_msg(const void __user *src, int len);
131  extern int store_msg(void __user *dest, struct msg_msg *msg, int len);
132  extern int ipcget_new(struct ipc_namespace *, struct ipc_ids *,
133  			struct ipc_ops *, struct ipc_params *);
134  extern int ipcget_public(struct ipc_namespace *, struct ipc_ids *,
135  			struct ipc_ops *, struct ipc_params *);
136  
137  static inline int ipc_buildid(int id, int seq)
138  {
139  	return SEQ_MULTIPLIER * seq + id;
140  }
141  
142  /*
143   * Must be called with ipcp locked
144   */
145  static inline int ipc_checkid(struct kern_ipc_perm *ipcp, int uid)
146  {
147  	if (uid / SEQ_MULTIPLIER != ipcp->seq)
148  		return 1;
149  	return 0;
150  }
151  
152  static inline void ipc_lock_by_ptr(struct kern_ipc_perm *perm)
153  {
154  	rcu_read_lock();
155  	spin_lock(&perm->lock);
156  }
157  
158  static inline void ipc_unlock(struct kern_ipc_perm *perm)
159  {
160  	spin_unlock(&perm->lock);
161  	rcu_read_unlock();
162  }
163  
164  static inline struct kern_ipc_perm *ipc_lock_check_down(struct ipc_ids *ids,
165  						int id)
166  {
167  	struct kern_ipc_perm *out;
168  
169  	out = ipc_lock_down(ids, id);
170  	if (IS_ERR(out))
171  		return out;
172  
173  	if (ipc_checkid(out, id)) {
174  		ipc_unlock(out);
175  		return ERR_PTR(-EIDRM);
176  	}
177  
178  	return out;
179  }
180  
181  static inline struct kern_ipc_perm *ipc_lock_check(struct ipc_ids *ids,
182  						int id)
183  {
184  	struct kern_ipc_perm *out;
185  
186  	out = ipc_lock(ids, id);
187  	if (IS_ERR(out))
188  		return out;
189  
190  	if (ipc_checkid(out, id)) {
191  		ipc_unlock(out);
192  		return ERR_PTR(-EIDRM);
193  	}
194  
195  	return out;
196  }
197  
198  /**
199   * ipcget - Common sys_*get() code
200   * @ns : namsepace
201   * @ids : IPC identifier set
202   * @ops : operations to be called on ipc object creation, permission checks
203   *        and further checks
204   * @params : the parameters needed by the previous operations.
205   *
206   * Common routine called by sys_msgget(), sys_semget() and sys_shmget().
207   */
208  static inline int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids,
209  			struct ipc_ops *ops, struct ipc_params *params)
210  {
211  	if (params->key == IPC_PRIVATE)
212  		return ipcget_new(ns, ids, ops, params);
213  	else
214  		return ipcget_public(ns, ids, ops, params);
215  }
216  
217  #endif
218