2
* Copyright (C) 2005 Novell/SUSE
4
* This program is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU General Public License as
6
* published by the Free Software Foundation, version 2 of the
13
#include <linux/namespace.h>
15
static inline int __sd_is_confined(struct subdomain *sd)
19
if (sd && sd->sd_magic == SD_ID_MAGIC && sd->profile) {
31
* Check if @sd is confined (contains a valid profile)
32
* Return 1 if confined, 0 otherwise.
34
static inline int sd_is_confined(void)
36
struct subdomain *sd = SD_SUBDOMAIN(current->security);
37
return __sd_is_confined(sd);
40
static inline int __sd_sub_defined(struct subdomain *sd)
42
return __sd_is_confined(sd) && !list_empty(&sd->profile->sub);
49
* Check if @sd has at least one subprofile
50
* Return 1 if true, 0 otherwise
52
static inline int sd_sub_defined(void)
54
struct subdomain *sd = SD_SUBDOMAIN(current->security);
55
return __sd_sub_defined(sd);
62
* Increment refcount on profile
64
static inline struct sdprofile *get_sdprofile(struct sdprofile *p)
67
atomic_inc(&p->count);
75
* Decrement refcount on profile
77
static inline void put_sdprofile(struct sdprofile *p)
80
if (atomic_dec_and_test(&p->count))
85
* cap_is_cached - check if @cap access has already been logged for current
86
* @cap: capability to test if cached
88
static inline int cap_is_cached(int cap)
90
struct subdomain *sd = SD_SUBDOMAIN(current->security);
91
return cap_raised(sd->cached_caps, cap);
95
* add_to_cached_caps - add a capability to the tasks logged capabilities cache
96
* @cap: the capability to add
98
static inline void add_to_cached_caps(int cap)
100
struct subdomain *sd = SD_SUBDOMAIN(current->security);
101
sd->cached_caps = cap_combine(sd->cached_caps, CAP_TO_MASK(cap));
105
* clear_cached_caps - clear the tasks logged capabilities cache
107
static inline void clear_cached_caps(struct subdomain *sd)
109
sd->cached_caps = CAP_EMPTY_SET;
113
* syscall_is_cached - check if @call access has already been logged
114
* @call: syscall to test if cached
116
static inline int syscall_is_cached(enum aasyscall call)
118
struct subdomain *sd = SD_SUBDOMAIN(current->security);
119
return sd->cached_syscalls & AA_SYSCALL_TO_MASK(call);
123
* add_to_cached_syscalls - add a syscall to the tasks logged syscalls cache
124
* @call: the syscall to add
126
static inline void add_to_cached_syscalls(enum aasyscall call)
128
struct subdomain *sd = SD_SUBDOMAIN(current->security);
129
sd->cached_syscalls |= AA_SYSCALL_TO_MASK(call);
133
* clear_cached_syscalls - clear the tasks logged syscalls cache
135
static inline void clear_cached_syscalls(struct subdomain *sd)
137
sd->cached_syscalls = 0;
142
* @sd: subdomain to switch
143
* @profile: new profile
144
* @active: new active
146
* Change subdomain to use new profiles.
148
static inline void sd_switch(struct subdomain *sd,
149
struct sdprofile *profile,
150
struct sdprofile *active)
153
put_sdprofile(sd->profile);
154
put_sdprofile(sd->active);
156
sd->profile = get_sdprofile(profile);
157
sd->active = get_sdprofile(active);
158
clear_cached_caps(sd);
159
clear_cached_syscalls(sd);
163
* sd_switch_unconfined
164
* @sd: subdomain to switch
166
* Change subdomain to unconfined
168
static inline void sd_switch_unconfined(struct subdomain *sd)
170
sd_switch(sd, NULL, NULL);
172
/* reset magic in case we were in a subhat before */
173
sd->sd_hat_magic = 0;
180
* Allocate a new subdomain including a backpointer to it's referring task.
182
static inline struct subdomain *alloc_subdomain(struct task_struct *tsk)
184
struct subdomain *sd;
186
sd = kmalloc(sizeof(struct subdomain), GFP_KERNEL);
191
memset(sd, 0, sizeof(struct subdomain));
192
sd->sd_magic = SD_ID_MAGIC;
194
/* back pointer to task */
197
/* any readers of the list must make sure that they can handle
198
* case where sd->profile and sd->active are not yet set (null)
200
sd_subdomainlist_add(sd);
210
* Free a subdomain previously allocated by alloc_subdomain
212
static inline void free_subdomain(struct subdomain *sd)
214
sd_subdomainlist_remove(sd);
221
* Allocate, initialize and return a new zeroed profile.
222
* Returns NULL on failure.
224
static inline struct sdprofile *alloc_sdprofile(void)
226
struct sdprofile *profile;
228
profile = (struct sdprofile *)kmalloc(sizeof(struct sdprofile),
230
SD_DEBUG("%s(%p)\n", __FUNCTION__, profile);
233
memset(profile, 0, sizeof(struct sdprofile));
234
INIT_LIST_HEAD(&profile->list);
235
INIT_LIST_HEAD(&profile->sub);
236
INIT_LIST_HEAD(&profile->file_entry);
237
for (i = 0; i <= POS_SD_FILE_MAX; i++) {
238
INIT_LIST_HEAD(&profile->file_entryp[i]);
246
* @name: name to release.
248
* Release space (free_page) allocated to hold pathname
249
* name may be NULL (checked for by free_page)
251
static inline void sd_put_name(const char *name)
253
free_page((unsigned long)name);
256
/** __sd_find_profile
257
* @name: name of profile to find
258
* @head: list to search
260
* Return reference counted copy of profile. NULL if not found
261
* Caller must hold any necessary locks
263
static inline struct sdprofile *__sd_find_profile(const char *name,
264
struct list_head *head)
271
SD_DEBUG("%s: finding profile %s\n", __FUNCTION__, name);
272
list_for_each_entry(p, head, list) {
273
if (!strcmp(p->name, name)) {
274
/* return refcounted object */
275
p = get_sdprofile(p);
278
SD_DEBUG("%s: skipping %s\n", __FUNCTION__, p->name);
284
static inline struct subdomain *__get_sdcopy(struct subdomain *new,
285
struct task_struct *tsk)
287
struct subdomain *old, *temp = NULL;
289
old = SD_SUBDOMAIN(tsk->security);
292
new->sd_magic = old->sd_magic;
293
new->sd_hat_magic = old->sd_hat_magic;
295
new->active = get_sdprofile(old->active);
297
if (old->profile == old->active)
298
new->profile = new->active;
300
new->profile = get_sdprofile(old->profile);
309
* @new: subdomain to hold copy
311
* Make copy of current subdomain containing refcounted profile and active
312
* Used to protect readers against racing writers (changehat and profile
315
static inline struct subdomain *get_sdcopy(struct subdomain *new)
317
struct subdomain *temp;
320
read_lock_irqsave(&sd_lock, flags);
322
temp = __get_sdcopy(new, current);
324
read_unlock_irqrestore(&sd_lock, flags);
330
* @temp: subdomain to drop refcounts on
332
* Drop refcounted profile/active in copy of subdomain made by get_sdcopy
334
static inline void put_sdcopy(struct subdomain *temp)
337
put_sdprofile(temp->active);
338
if (temp->active != temp->profile)
339
(void)put_sdprofile(temp->profile);
344
* @rdentry: filesystem root dentry (searching for vfsmnts matching this)
345
* @dentry: dentry object to obtain pathname from (relative to matched vfsmnt)
347
* Setup data for iterating over vfsmounts (in current tasks namespace).
349
static inline void sd_path_begin2(struct dentry *rdentry,
350
struct dentry *dentry,
351
struct sd_path_data *data)
353
data->dentry = dentry;
354
data->root = dget(rdentry->d_sb->s_root);
355
data->namespace = current->namespace;
356
data->head = &data->namespace->list;
357
data->pos = data->head->next;
358
prefetch(data->pos->next);
361
down_read(&namespace_sem);
365
* @dentry filesystem root dentry and object to obtain pathname from
367
* Utility function for calling _sd_path_begin for when the dentry we are
368
* looking for and the root are the same (this is the usual case).
370
static inline void sd_path_begin(struct dentry *dentry,
371
struct sd_path_data *data)
373
sd_path_begin2(dentry, dentry, data);
377
* @data: data object previously initialized by sd_path_begin
379
* End iterating over vfsmounts.
380
* If an error occured in begin or get, it is returned. Otherwise 0.
382
static inline int sd_path_end(struct sd_path_data *data)
384
up_read(&namespace_sem);
391
* @data: data object previously initialized by sd_path_begin
393
* Return the next mountpoint which has the same root dentry as data->root.
394
* If no more mount points exist (or in case of error) NULL is returned
395
* (caller should call sd_path_end() and inspect return code to differentiate)
397
static inline char *sd_path_getname(struct sd_path_data *data)
400
struct vfsmount *mnt;
402
while (data->pos != data->head) {
403
mnt = list_entry(data->pos, struct vfsmount, mnt_list);
405
/* advance to next -- so that it is done before we break */
406
data->pos = data->pos->next;
407
prefetch(data->pos->next);
409
if (mnt->mnt_root == data->root) {
410
name = sd_get_name(data->dentry, mnt);
412
data->errno = PTR_ERR(name);
422
#endif /* __INLINE_H__ */