diff options
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/cred.h | 187 | ||||
-rw-r--r-- | include/linux/securebits.h | 2 |
2 files changed, 144 insertions, 45 deletions
diff --git a/include/linux/cred.h b/include/linux/cred.h index a7a686074cb0..4221ec6000c1 100644 --- a/include/linux/cred.h +++ b/include/linux/cred.h | |||
@@ -37,15 +37,16 @@ struct group_info { | |||
37 | * get_group_info - Get a reference to a group info structure | 37 | * get_group_info - Get a reference to a group info structure |
38 | * @group_info: The group info to reference | 38 | * @group_info: The group info to reference |
39 | * | 39 | * |
40 | * This must be called with the owning task locked (via task_lock()) when task | 40 | * This gets a reference to a set of supplementary groups. |
41 | * != current. The reason being that the vast majority of callers are looking | 41 | * |
42 | * at current->group_info, which can not be changed except by the current task. | 42 | * If the caller is accessing a task's credentials, they must hold the RCU read |
43 | * Changing current->group_info requires the task lock, too. | 43 | * lock when reading. |
44 | */ | 44 | */ |
45 | #define get_group_info(group_info) \ | 45 | static inline struct group_info *get_group_info(struct group_info *gi) |
46 | do { \ | 46 | { |
47 | atomic_inc(&(group_info)->usage); \ | 47 | atomic_inc(&gi->usage); |
48 | } while (0) | 48 | return gi; |
49 | } | ||
49 | 50 | ||
50 | /** | 51 | /** |
51 | * put_group_info - Release a reference to a group info structure | 52 | * put_group_info - Release a reference to a group info structure |
@@ -61,7 +62,7 @@ extern struct group_info *groups_alloc(int); | |||
61 | extern void groups_free(struct group_info *); | 62 | extern void groups_free(struct group_info *); |
62 | extern int set_current_groups(struct group_info *); | 63 | extern int set_current_groups(struct group_info *); |
63 | extern int set_groups(struct cred *, struct group_info *); | 64 | extern int set_groups(struct cred *, struct group_info *); |
64 | extern int groups_search(struct group_info *, gid_t); | 65 | extern int groups_search(const struct group_info *, gid_t); |
65 | 66 | ||
66 | /* access the groups "array" with this macro */ | 67 | /* access the groups "array" with this macro */ |
67 | #define GROUP_AT(gi, i) \ | 68 | #define GROUP_AT(gi, i) \ |
@@ -123,41 +124,6 @@ struct cred { | |||
123 | spinlock_t lock; /* lock for pointer changes */ | 124 | spinlock_t lock; /* lock for pointer changes */ |
124 | }; | 125 | }; |
125 | 126 | ||
126 | #define get_current_user() (get_uid(current->cred->user)) | ||
127 | |||
128 | #define task_uid(task) ((task)->cred->uid) | ||
129 | #define task_gid(task) ((task)->cred->gid) | ||
130 | #define task_euid(task) ((task)->cred->euid) | ||
131 | #define task_egid(task) ((task)->cred->egid) | ||
132 | |||
133 | #define current_uid() (current->cred->uid) | ||
134 | #define current_gid() (current->cred->gid) | ||
135 | #define current_euid() (current->cred->euid) | ||
136 | #define current_egid() (current->cred->egid) | ||
137 | #define current_suid() (current->cred->suid) | ||
138 | #define current_sgid() (current->cred->sgid) | ||
139 | #define current_fsuid() (current->cred->fsuid) | ||
140 | #define current_fsgid() (current->cred->fsgid) | ||
141 | #define current_cap() (current->cred->cap_effective) | ||
142 | |||
143 | #define current_uid_gid(_uid, _gid) \ | ||
144 | do { \ | ||
145 | *(_uid) = current->cred->uid; \ | ||
146 | *(_gid) = current->cred->gid; \ | ||
147 | } while(0) | ||
148 | |||
149 | #define current_euid_egid(_uid, _gid) \ | ||
150 | do { \ | ||
151 | *(_uid) = current->cred->euid; \ | ||
152 | *(_gid) = current->cred->egid; \ | ||
153 | } while(0) | ||
154 | |||
155 | #define current_fsuid_fsgid(_uid, _gid) \ | ||
156 | do { \ | ||
157 | *(_uid) = current->cred->fsuid; \ | ||
158 | *(_gid) = current->cred->fsgid; \ | ||
159 | } while(0) | ||
160 | |||
161 | extern void __put_cred(struct cred *); | 127 | extern void __put_cred(struct cred *); |
162 | extern int copy_creds(struct task_struct *, unsigned long); | 128 | extern int copy_creds(struct task_struct *, unsigned long); |
163 | 129 | ||
@@ -187,4 +153,137 @@ static inline void put_cred(struct cred *cred) | |||
187 | __put_cred(cred); | 153 | __put_cred(cred); |
188 | } | 154 | } |
189 | 155 | ||
156 | /** | ||
157 | * current_cred - Access the current task's credentials | ||
158 | * | ||
159 | * Access the credentials of the current task. | ||
160 | */ | ||
161 | #define current_cred() \ | ||
162 | (current->cred) | ||
163 | |||
164 | /** | ||
165 | * __task_cred - Access another task's credentials | ||
166 | * @task: The task to query | ||
167 | * | ||
168 | * Access the credentials of another task. The caller must hold the | ||
169 | * RCU readlock. | ||
170 | * | ||
171 | * The caller must make sure task doesn't go away, either by holding a ref on | ||
172 | * task or by holding tasklist_lock to prevent it from being unlinked. | ||
173 | */ | ||
174 | #define __task_cred(task) \ | ||
175 | ((const struct cred *)(rcu_dereference((task)->cred))) | ||
176 | |||
177 | /** | ||
178 | * get_task_cred - Get another task's credentials | ||
179 | * @task: The task to query | ||
180 | * | ||
181 | * Get the credentials of a task, pinning them so that they can't go away. | ||
182 | * Accessing a task's credentials directly is not permitted. | ||
183 | * | ||
184 | * The caller must make sure task doesn't go away, either by holding a ref on | ||
185 | * task or by holding tasklist_lock to prevent it from being unlinked. | ||
186 | */ | ||
187 | #define get_task_cred(task) \ | ||
188 | ({ \ | ||
189 | struct cred *__cred; \ | ||
190 | rcu_read_lock(); \ | ||
191 | __cred = (struct cred *) __task_cred((task)); \ | ||
192 | get_cred(__cred); \ | ||
193 | rcu_read_unlock(); \ | ||
194 | __cred; \ | ||
195 | }) | ||
196 | |||
197 | /** | ||
198 | * get_current_cred - Get the current task's credentials | ||
199 | * | ||
200 | * Get the credentials of the current task, pinning them so that they can't go | ||
201 | * away. Accessing the current task's credentials directly is not permitted. | ||
202 | */ | ||
203 | #define get_current_cred() \ | ||
204 | (get_cred(current_cred())) | ||
205 | |||
206 | /** | ||
207 | * get_current_user - Get the current task's user_struct | ||
208 | * | ||
209 | * Get the user record of the current task, pinning it so that it can't go | ||
210 | * away. | ||
211 | */ | ||
212 | #define get_current_user() \ | ||
213 | ({ \ | ||
214 | struct user_struct *__u; \ | ||
215 | struct cred *__cred; \ | ||
216 | __cred = (struct cred *) current_cred(); \ | ||
217 | __u = get_uid(__cred->user); \ | ||
218 | __u; \ | ||
219 | }) | ||
220 | |||
221 | /** | ||
222 | * get_current_groups - Get the current task's supplementary group list | ||
223 | * | ||
224 | * Get the supplementary group list of the current task, pinning it so that it | ||
225 | * can't go away. | ||
226 | */ | ||
227 | #define get_current_groups() \ | ||
228 | ({ \ | ||
229 | struct group_info *__groups; \ | ||
230 | struct cred *__cred; \ | ||
231 | __cred = (struct cred *) current_cred(); \ | ||
232 | __groups = get_group_info(__cred->group_info); \ | ||
233 | __groups; \ | ||
234 | }) | ||
235 | |||
236 | #define task_cred_xxx(task, xxx) \ | ||
237 | ({ \ | ||
238 | __typeof__(task->cred->xxx) ___val; \ | ||
239 | rcu_read_lock(); \ | ||
240 | ___val = __task_cred((task))->xxx; \ | ||
241 | rcu_read_unlock(); \ | ||
242 | ___val; \ | ||
243 | }) | ||
244 | |||
245 | #define task_uid(task) (task_cred_xxx((task), uid)) | ||
246 | #define task_euid(task) (task_cred_xxx((task), euid)) | ||
247 | |||
248 | #define current_cred_xxx(xxx) \ | ||
249 | ({ \ | ||
250 | current->cred->xxx; \ | ||
251 | }) | ||
252 | |||
253 | #define current_uid() (current_cred_xxx(uid)) | ||
254 | #define current_gid() (current_cred_xxx(gid)) | ||
255 | #define current_euid() (current_cred_xxx(euid)) | ||
256 | #define current_egid() (current_cred_xxx(egid)) | ||
257 | #define current_suid() (current_cred_xxx(suid)) | ||
258 | #define current_sgid() (current_cred_xxx(sgid)) | ||
259 | #define current_fsuid() (current_cred_xxx(fsuid)) | ||
260 | #define current_fsgid() (current_cred_xxx(fsgid)) | ||
261 | #define current_cap() (current_cred_xxx(cap_effective)) | ||
262 | #define current_user() (current_cred_xxx(user)) | ||
263 | #define current_security() (current_cred_xxx(security)) | ||
264 | |||
265 | #define current_uid_gid(_uid, _gid) \ | ||
266 | do { \ | ||
267 | const struct cred *__cred; \ | ||
268 | __cred = current_cred(); \ | ||
269 | *(_uid) = __cred->uid; \ | ||
270 | *(_gid) = __cred->gid; \ | ||
271 | } while(0) | ||
272 | |||
273 | #define current_euid_egid(_euid, _egid) \ | ||
274 | do { \ | ||
275 | const struct cred *__cred; \ | ||
276 | __cred = current_cred(); \ | ||
277 | *(_euid) = __cred->euid; \ | ||
278 | *(_egid) = __cred->egid; \ | ||
279 | } while(0) | ||
280 | |||
281 | #define current_fsuid_fsgid(_fsuid, _fsgid) \ | ||
282 | do { \ | ||
283 | const struct cred *__cred; \ | ||
284 | __cred = current_cred(); \ | ||
285 | *(_fsuid) = __cred->fsuid; \ | ||
286 | *(_fsgid) = __cred->fsgid; \ | ||
287 | } while(0) | ||
288 | |||
190 | #endif /* _LINUX_CRED_H */ | 289 | #endif /* _LINUX_CRED_H */ |
diff --git a/include/linux/securebits.h b/include/linux/securebits.h index 6d389491bfa2..d2c5ed845bcc 100644 --- a/include/linux/securebits.h +++ b/include/linux/securebits.h | |||
@@ -32,7 +32,7 @@ | |||
32 | setting is locked or not. A setting which is locked cannot be | 32 | setting is locked or not. A setting which is locked cannot be |
33 | changed from user-level. */ | 33 | changed from user-level. */ |
34 | #define issecure_mask(X) (1 << (X)) | 34 | #define issecure_mask(X) (1 << (X)) |
35 | #define issecure(X) (issecure_mask(X) & current->cred->securebits) | 35 | #define issecure(X) (issecure_mask(X) & current_cred_xxx(securebits)) |
36 | 36 | ||
37 | #define SECURE_ALL_BITS (issecure_mask(SECURE_NOROOT) | \ | 37 | #define SECURE_ALL_BITS (issecure_mask(SECURE_NOROOT) | \ |
38 | issecure_mask(SECURE_NO_SETUID_FIXUP) | \ | 38 | issecure_mask(SECURE_NO_SETUID_FIXUP) | \ |