~ubuntu-branches/ubuntu/raring/apparmor/raring

« back to all changes in this revision

Viewing changes to module-deprecated/inline.h

  • Committer: Bazaar Package Importer
  • Author(s): Kees Cook
  • Date: 2007-03-23 16:42:01 UTC
  • Revision ID: james.westby@ubuntu.com-20070323164201-jkax6f0oku087b7l
Tags: upstream-2.0.1+510.dfsg
ImportĀ upstreamĀ versionĀ 2.0.1+510.dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *      Copyright (C) 2005 Novell/SUSE
 
3
 *
 
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
 
7
 *      License.
 
8
 */
 
9
 
 
10
#ifndef __INLINE_H
 
11
#define __INLINE_H
 
12
 
 
13
#include <linux/namespace.h>
 
14
 
 
15
static inline int __sd_is_confined(struct subdomain *sd)
 
16
{
 
17
        int rc = 0;
 
18
 
 
19
        if (sd && sd->sd_magic == SD_ID_MAGIC && sd->profile) {
 
20
                BUG_ON(!sd->active);
 
21
                rc = 1;
 
22
        }
 
23
 
 
24
        return rc;
 
25
}
 
26
 
 
27
/**
 
28
 *  sd_is_confined
 
29
 *  @sd: subdomain
 
30
 *
 
31
 *  Check if @sd is confined (contains a valid profile)
 
32
 *  Return 1 if confined, 0 otherwise.
 
33
 */
 
34
static inline int sd_is_confined(void)
 
35
{
 
36
        struct subdomain *sd = SD_SUBDOMAIN(current->security);
 
37
        return __sd_is_confined(sd);
 
38
}
 
39
 
 
40
static inline int __sd_sub_defined(struct subdomain *sd)
 
41
{
 
42
        return __sd_is_confined(sd) && !list_empty(&sd->profile->sub);
 
43
}
 
44
 
 
45
/**
 
46
 * sd_sub_defined
 
47
 * @sd: subdomain
 
48
 *
 
49
 * Check if @sd has at least one subprofile
 
50
 * Return 1 if true, 0 otherwise
 
51
 */
 
52
static inline int sd_sub_defined(void)
 
53
{
 
54
        struct subdomain *sd = SD_SUBDOMAIN(current->security);
 
55
        return __sd_sub_defined(sd);
 
56
}
 
57
 
 
58
/**
 
59
 * get_sdprofile
 
60
 * @p: profile
 
61
 *
 
62
 * Increment refcount on profile
 
63
 */
 
64
static inline struct sdprofile *get_sdprofile(struct sdprofile *p)
 
65
{
 
66
        if (p)
 
67
                atomic_inc(&p->count);
 
68
        return p;
 
69
}
 
70
 
 
71
/**
 
72
 * put_sdprofile
 
73
 * @p: profile
 
74
 *
 
75
 * Decrement refcount on profile
 
76
 */
 
77
static inline void put_sdprofile(struct sdprofile *p)
 
78
{
 
79
        if (p)
 
80
                if (atomic_dec_and_test(&p->count))
 
81
                        free_sdprofile(p);
 
82
}
 
83
 
 
84
/**
 
85
 * cap_is_cached - check if @cap access has already been logged for current
 
86
 * @cap: capability to test if cached
 
87
 */
 
88
static inline int cap_is_cached(int cap)
 
89
{
 
90
        struct subdomain *sd = SD_SUBDOMAIN(current->security);
 
91
        return cap_raised(sd->cached_caps, cap);
 
92
}
 
93
 
 
94
/**
 
95
 * add_to_cached_caps - add a capability to the tasks logged capabilities cache
 
96
 * @cap: the capability to add
 
97
 */
 
98
static inline void add_to_cached_caps(int cap)
 
99
{
 
100
        struct subdomain *sd = SD_SUBDOMAIN(current->security);
 
101
        sd->cached_caps = cap_combine(sd->cached_caps, CAP_TO_MASK(cap));
 
102
}
 
103
 
 
104
/**
 
105
 * clear_cached_caps - clear the tasks logged capabilities cache
 
106
 */
 
107
static inline void clear_cached_caps(struct subdomain *sd)
 
108
{
 
109
        sd->cached_caps = CAP_EMPTY_SET;
 
110
}
 
111
 
 
112
/**
 
113
 * syscall_is_cached - check if @call access has already been logged
 
114
 * @call: syscall to test if cached
 
115
 */
 
116
static inline int syscall_is_cached(enum aasyscall call)
 
117
{
 
118
        struct subdomain *sd = SD_SUBDOMAIN(current->security);
 
119
        return sd->cached_syscalls & AA_SYSCALL_TO_MASK(call);
 
120
}
 
121
 
 
122
/**
 
123
 * add_to_cached_syscalls - add a syscall to the tasks logged syscalls cache
 
124
 * @call: the syscall to add
 
125
 */
 
126
static inline void add_to_cached_syscalls(enum aasyscall call)
 
127
{
 
128
        struct subdomain *sd = SD_SUBDOMAIN(current->security);
 
129
        sd->cached_syscalls |= AA_SYSCALL_TO_MASK(call);
 
130
}
 
131
 
 
132
/**
 
133
 * clear_cached_syscalls - clear the tasks logged syscalls cache
 
134
 */
 
135
static inline void clear_cached_syscalls(struct subdomain *sd)
 
136
{
 
137
        sd->cached_syscalls = 0;
 
138
}
 
139
 
 
140
/**
 
141
 * sd_switch
 
142
 * @sd: subdomain to switch
 
143
 * @profile: new profile
 
144
 * @active:  new active
 
145
 *
 
146
 * Change subdomain to use new profiles.
 
147
 */
 
148
static inline void sd_switch(struct subdomain *sd,
 
149
                                 struct sdprofile *profile,
 
150
                                 struct sdprofile *active)
 
151
{
 
152
        /* noop if NULL */
 
153
        put_sdprofile(sd->profile);
 
154
        put_sdprofile(sd->active);
 
155
 
 
156
        sd->profile = get_sdprofile(profile);
 
157
        sd->active = get_sdprofile(active);
 
158
        clear_cached_caps(sd);
 
159
        clear_cached_syscalls(sd);
 
160
}
 
161
 
 
162
/**
 
163
 * sd_switch_unconfined
 
164
 * @sd: subdomain to switch
 
165
 *
 
166
 * Change subdomain to unconfined
 
167
 */
 
168
static inline void sd_switch_unconfined(struct subdomain *sd)
 
169
{
 
170
        sd_switch(sd, NULL, NULL);
 
171
 
 
172
        /* reset magic in case we were in a subhat before */
 
173
        sd->sd_hat_magic = 0;
 
174
}
 
175
 
 
176
/**
 
177
 * alloc_subdomain
 
178
 * @tsk: task struct
 
179
 *
 
180
 * Allocate a new subdomain including a backpointer to it's referring task.
 
181
 */
 
182
static inline struct subdomain *alloc_subdomain(struct task_struct *tsk)
 
183
{
 
184
        struct subdomain *sd;
 
185
 
 
186
        sd = kmalloc(sizeof(struct subdomain), GFP_KERNEL);
 
187
        if (!sd)
 
188
                goto out;
 
189
 
 
190
        /* zero it first */
 
191
        memset(sd, 0, sizeof(struct subdomain));
 
192
        sd->sd_magic = SD_ID_MAGIC;
 
193
 
 
194
        /* back pointer to task */
 
195
        sd->task = tsk;
 
196
 
 
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)
 
199
         */
 
200
        sd_subdomainlist_add(sd);
 
201
 
 
202
out:
 
203
        return sd;
 
204
}
 
205
 
 
206
/**
 
207
 * free_subdomain
 
208
 * @sd: subdomain
 
209
 *
 
210
 * Free a subdomain previously allocated by alloc_subdomain
 
211
 */
 
212
static inline void free_subdomain(struct subdomain *sd)
 
213
{
 
214
        sd_subdomainlist_remove(sd);
 
215
        kfree(sd);
 
216
}
 
217
 
 
218
/**
 
219
 * alloc_sdprofile
 
220
 *
 
221
 * Allocate, initialize and return a new zeroed profile.
 
222
 * Returns NULL on failure.
 
223
 */
 
224
static inline struct sdprofile *alloc_sdprofile(void)
 
225
{
 
226
        struct sdprofile *profile;
 
227
 
 
228
        profile = (struct sdprofile *)kmalloc(sizeof(struct sdprofile),
 
229
                                              GFP_KERNEL);
 
230
        SD_DEBUG("%s(%p)\n", __FUNCTION__, profile);
 
231
        if (profile) {
 
232
                int i;
 
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]);
 
239
                }
 
240
        }
 
241
        return profile;
 
242
}
 
243
 
 
244
/**
 
245
 * sd_put_name
 
246
 * @name: name to release.
 
247
 *
 
248
 * Release space (free_page) allocated to hold pathname
 
249
 * name may be NULL (checked for by free_page)
 
250
 */
 
251
static inline void sd_put_name(const char *name)
 
252
{
 
253
        free_page((unsigned long)name);
 
254
}
 
255
 
 
256
/** __sd_find_profile
 
257
 * @name: name of profile to find
 
258
 * @head: list to search
 
259
 *
 
260
 * Return reference counted copy of profile. NULL if not found
 
261
 * Caller must hold any necessary locks
 
262
 */
 
263
static inline struct sdprofile *__sd_find_profile(const char *name,
 
264
                                                      struct list_head *head)
 
265
{
 
266
        struct sdprofile *p;
 
267
 
 
268
        if (!name || !head)
 
269
                return NULL;
 
270
 
 
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);
 
276
                        return p;
 
277
                } else {
 
278
                        SD_DEBUG("%s: skipping %s\n", __FUNCTION__, p->name);
 
279
                }
 
280
        }
 
281
        return NULL;
 
282
}
 
283
 
 
284
static inline struct subdomain *__get_sdcopy(struct subdomain *new,
 
285
                                                 struct task_struct *tsk)
 
286
{
 
287
        struct subdomain *old, *temp = NULL;
 
288
 
 
289
        old = SD_SUBDOMAIN(tsk->security);
 
290
 
 
291
        if (old) {
 
292
                new->sd_magic = old->sd_magic;
 
293
                new->sd_hat_magic = old->sd_hat_magic;
 
294
 
 
295
                new->active = get_sdprofile(old->active);
 
296
 
 
297
                if (old->profile == old->active)
 
298
                        new->profile = new->active;
 
299
                else
 
300
                        new->profile = get_sdprofile(old->profile);
 
301
 
 
302
                temp = new;
 
303
        }
 
304
 
 
305
        return temp;
 
306
}
 
307
 
 
308
/** get_sdcopy
 
309
 * @new: subdomain to hold copy
 
310
 *
 
311
 * Make copy of current subdomain containing refcounted profile and active
 
312
 * Used to protect readers against racing writers (changehat and profile
 
313
 * replacement).
 
314
 */
 
315
static inline struct subdomain *get_sdcopy(struct subdomain *new)
 
316
{
 
317
        struct subdomain *temp;
 
318
        unsigned long flags;
 
319
 
 
320
        read_lock_irqsave(&sd_lock, flags);
 
321
 
 
322
        temp = __get_sdcopy(new, current);
 
323
 
 
324
        read_unlock_irqrestore(&sd_lock, flags);
 
325
 
 
326
        return temp;
 
327
}
 
328
 
 
329
/** get_sdcopy
 
330
 * @temp: subdomain to drop refcounts on
 
331
 *
 
332
 * Drop refcounted profile/active in copy of subdomain made by get_sdcopy
 
333
 */
 
334
static inline void put_sdcopy(struct subdomain *temp)
 
335
{
 
336
        if (temp) {
 
337
                put_sdprofile(temp->active);
 
338
                if (temp->active != temp->profile)
 
339
                        (void)put_sdprofile(temp->profile);
 
340
        }
 
341
}
 
342
 
 
343
/** sd_path_begin2
 
344
 * @rdentry: filesystem root dentry (searching for vfsmnts matching this)
 
345
 * @dentry: dentry object to obtain pathname from (relative to matched vfsmnt)
 
346
 *
 
347
 * Setup data for iterating over vfsmounts (in current tasks namespace).
 
348
 */
 
349
static inline void sd_path_begin2(struct dentry *rdentry,
 
350
                                      struct dentry *dentry,
 
351
                                      struct sd_path_data *data)
 
352
{
 
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);
 
359
        data->errno = 0;
 
360
 
 
361
        down_read(&namespace_sem);
 
362
}
 
363
 
 
364
/** sd_path_begin
 
365
 * @dentry filesystem root dentry and object to obtain pathname from
 
366
 *
 
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).
 
369
 */
 
370
static inline void sd_path_begin(struct dentry *dentry,
 
371
                                     struct sd_path_data *data)
 
372
{
 
373
        sd_path_begin2(dentry, dentry, data);
 
374
}
 
375
 
 
376
/** sd_path_end
 
377
 * @data: data object previously initialized by sd_path_begin
 
378
 *
 
379
 * End iterating over vfsmounts.
 
380
 * If an error occured in begin or get, it is returned. Otherwise 0.
 
381
 */
 
382
static inline int sd_path_end(struct sd_path_data *data)
 
383
{
 
384
        up_read(&namespace_sem);
 
385
        dput(data->root);
 
386
 
 
387
        return data->errno;
 
388
}
 
389
 
 
390
/** sd_path_getname
 
391
 * @data: data object previously initialized by sd_path_begin
 
392
 *
 
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)
 
396
 */
 
397
static inline char *sd_path_getname(struct sd_path_data *data)
 
398
{
 
399
        char *name = NULL;
 
400
        struct vfsmount *mnt;
 
401
 
 
402
        while (data->pos != data->head) {
 
403
                mnt = list_entry(data->pos, struct vfsmount, mnt_list);
 
404
 
 
405
                /* advance to next -- so that it is done before we break */
 
406
                data->pos = data->pos->next;
 
407
                prefetch(data->pos->next);
 
408
 
 
409
                if (mnt->mnt_root == data->root) {
 
410
                        name = sd_get_name(data->dentry, mnt);
 
411
                        if (IS_ERR(name)) {
 
412
                                data->errno = PTR_ERR(name);
 
413
                                name = NULL;
 
414
                        }
 
415
                        break;
 
416
                }
 
417
        }
 
418
 
 
419
        return name;
 
420
}
 
421
 
 
422
#endif /* __INLINE_H__ */