~ubuntu-branches/ubuntu/wily/apparmor/wily

« back to all changes in this revision

Viewing changes to module-deprecated/inline.h

  • Committer: Bazaar Package Importer
  • Author(s): Kees Cook
  • Date: 2011-04-27 10:38:07 UTC
  • mfrom: (5.1.118 natty)
  • Revision ID: james.westby@ubuntu.com-20110427103807-ym3rhwys6o84ith0
Tags: 2.6.1-2
debian/copyright: clarify for some full organization names.

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__ */