David Brazdil | 0f672f6 | 2019-12-10 10:32:29 +0000 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
Andrew Scull | b4b6d4a | 2019-01-02 15:54:55 +0000 | [diff] [blame] | 2 | /* |
| 3 | * AppArmor security module |
| 4 | * |
| 5 | * This file contains AppArmor basic path manipulation function definitions. |
| 6 | * |
| 7 | * Copyright (C) 1998-2008 Novell/SUSE |
| 8 | * Copyright 2009-2010 Canonical Ltd. |
Andrew Scull | b4b6d4a | 2019-01-02 15:54:55 +0000 | [diff] [blame] | 9 | */ |
| 10 | |
| 11 | #ifndef __AA_PATH_H |
| 12 | #define __AA_PATH_H |
| 13 | |
| 14 | |
| 15 | enum path_flags { |
| 16 | PATH_IS_DIR = 0x1, /* path is a directory */ |
| 17 | PATH_CONNECT_PATH = 0x4, /* connect disconnected paths to / */ |
| 18 | PATH_CHROOT_REL = 0x8, /* do path lookup relative to chroot */ |
| 19 | PATH_CHROOT_NSCONNECT = 0x10, /* connect paths that are at ns root */ |
| 20 | |
| 21 | PATH_DELEGATE_DELETED = 0x08000, /* delegate deleted files */ |
| 22 | PATH_MEDIATE_DELETED = 0x10000, /* mediate deleted paths */ |
| 23 | }; |
| 24 | |
| 25 | int aa_path_name(const struct path *path, int flags, char *buffer, |
| 26 | const char **name, const char **info, |
| 27 | const char *disconnected); |
| 28 | |
| 29 | #define MAX_PATH_BUFFERS 2 |
| 30 | |
| 31 | /* Per cpu buffers used during mediation */ |
| 32 | /* preallocated buffers to use during path lookups */ |
| 33 | struct aa_buffers { |
| 34 | char *buf[MAX_PATH_BUFFERS]; |
| 35 | }; |
| 36 | |
| 37 | #include <linux/percpu.h> |
| 38 | #include <linux/preempt.h> |
| 39 | |
| 40 | DECLARE_PER_CPU(struct aa_buffers, aa_buffers); |
| 41 | |
| 42 | #define ASSIGN(FN, A, X, N) ((X) = FN(A, N)) |
| 43 | #define EVAL1(FN, A, X) ASSIGN(FN, A, X, 0) /*X = FN(0)*/ |
| 44 | #define EVAL2(FN, A, X, Y...) \ |
| 45 | do { ASSIGN(FN, A, X, 1); EVAL1(FN, A, Y); } while (0) |
| 46 | #define EVAL(FN, A, X...) CONCATENATE(EVAL, COUNT_ARGS(X))(FN, A, X) |
| 47 | |
| 48 | #define for_each_cpu_buffer(I) for ((I) = 0; (I) < MAX_PATH_BUFFERS; (I)++) |
| 49 | |
| 50 | #ifdef CONFIG_DEBUG_PREEMPT |
| 51 | #define AA_BUG_PREEMPT_ENABLED(X) AA_BUG(preempt_count() <= 0, X) |
| 52 | #else |
| 53 | #define AA_BUG_PREEMPT_ENABLED(X) /* nop */ |
| 54 | #endif |
| 55 | |
| 56 | #define __get_buffer(C, N) ({ \ |
| 57 | AA_BUG_PREEMPT_ENABLED("__get_buffer without preempt disabled"); \ |
| 58 | (C)->buf[(N)]; }) |
| 59 | |
| 60 | #define __get_buffers(C, X...) EVAL(__get_buffer, C, X) |
| 61 | |
| 62 | #define __put_buffers(X, Y...) ((void)&(X)) |
| 63 | |
| 64 | #define get_buffers(X...) \ |
| 65 | do { \ |
| 66 | struct aa_buffers *__cpu_var = get_cpu_ptr(&aa_buffers); \ |
| 67 | __get_buffers(__cpu_var, X); \ |
| 68 | } while (0) |
| 69 | |
| 70 | #define put_buffers(X, Y...) \ |
| 71 | do { \ |
| 72 | __put_buffers(X, Y); \ |
| 73 | put_cpu_ptr(&aa_buffers); \ |
| 74 | } while (0) |
| 75 | |
| 76 | #endif /* __AA_PATH_H */ |