1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /* |
3 | * AppArmor security module |
4 | * |
5 | * This file contains AppArmor policy loading interface function definitions. |
6 | * |
7 | * Copyright (C) 1998-2008 Novell/SUSE |
8 | * Copyright 2009-2010 Canonical Ltd. |
9 | */ |
10 | |
11 | #ifndef __POLICY_INTERFACE_H |
12 | #define __POLICY_INTERFACE_H |
13 | |
14 | #include <linux/list.h> |
15 | #include <linux/kref.h> |
16 | #include <linux/dcache.h> |
17 | #include <linux/workqueue.h> |
18 | |
19 | |
20 | struct aa_load_ent { |
21 | struct list_head list; |
22 | struct aa_profile *new; |
23 | struct aa_profile *old; |
24 | struct aa_profile *rename; |
25 | const char *ns_name; |
26 | }; |
27 | |
28 | void aa_load_ent_free(struct aa_load_ent *ent); |
29 | struct aa_load_ent *aa_load_ent_alloc(void); |
30 | |
31 | #define PACKED_FLAG_HAT 1 |
32 | #define PACKED_FLAG_DEBUG1 2 |
33 | #define PACKED_FLAG_DEBUG2 4 |
34 | |
35 | #define PACKED_MODE_ENFORCE 0 |
36 | #define PACKED_MODE_COMPLAIN 1 |
37 | #define PACKED_MODE_KILL 2 |
38 | #define PACKED_MODE_UNCONFINED 3 |
39 | #define PACKED_MODE_USER 4 |
40 | |
41 | struct aa_ns; |
42 | |
43 | enum { |
44 | AAFS_LOADDATA_ABI = 0, |
45 | AAFS_LOADDATA_REVISION, |
46 | AAFS_LOADDATA_HASH, |
47 | AAFS_LOADDATA_DATA, |
48 | AAFS_LOADDATA_COMPRESSED_SIZE, |
49 | AAFS_LOADDATA_DIR, /* must be last actual entry */ |
50 | AAFS_LOADDATA_NDENTS /* count of entries */ |
51 | }; |
52 | |
53 | /* |
54 | * The AppArmor interface treats data as a type byte followed by the |
55 | * actual data. The interface has the notion of a named entry |
56 | * which has a name (AA_NAME typecode followed by name string) followed by |
57 | * the entries typecode and data. Named types allow for optional |
58 | * elements and extensions to be added and tested for without breaking |
59 | * backwards compatibility. |
60 | */ |
61 | |
62 | enum aa_code { |
63 | AA_U8, |
64 | AA_U16, |
65 | AA_U32, |
66 | AA_U64, |
67 | AA_NAME, /* same as string except it is items name */ |
68 | AA_STRING, |
69 | AA_BLOB, |
70 | AA_STRUCT, |
71 | AA_STRUCTEND, |
72 | AA_LIST, |
73 | AA_LISTEND, |
74 | AA_ARRAY, |
75 | AA_ARRAYEND, |
76 | }; |
77 | |
78 | /* |
79 | * aa_ext is the read of the buffer containing the serialized profile. The |
80 | * data is copied into a kernel buffer in apparmorfs and then handed off to |
81 | * the unpack routines. |
82 | */ |
83 | struct aa_ext { |
84 | void *start; |
85 | void *end; |
86 | void *pos; /* pointer to current position in the buffer */ |
87 | u32 version; |
88 | }; |
89 | |
90 | /* |
91 | * struct aa_loaddata - buffer of policy raw_data set |
92 | * |
93 | * there is no loaddata ref for being on ns list, nor a ref from |
94 | * d_inode(@dentry) when grab a ref from these, @ns->lock must be held |
95 | * && __aa_get_loaddata() needs to be used, and the return value |
96 | * checked, if NULL the loaddata is already being reaped and should be |
97 | * considered dead. |
98 | */ |
99 | struct aa_loaddata { |
100 | struct kref count; |
101 | struct list_head list; |
102 | struct work_struct work; |
103 | struct dentry *dents[AAFS_LOADDATA_NDENTS]; |
104 | struct aa_ns *ns; |
105 | char *name; |
106 | size_t size; /* the original size of the payload */ |
107 | size_t compressed_size; /* the compressed size of the payload */ |
108 | long revision; /* the ns policy revision this caused */ |
109 | int abi; |
110 | unsigned char *hash; |
111 | |
112 | /* Pointer to payload. If @compressed_size > 0, then this is the |
113 | * compressed version of the payload, else it is the uncompressed |
114 | * version (with the size indicated by @size). |
115 | */ |
116 | char *data; |
117 | }; |
118 | |
119 | int aa_unpack(struct aa_loaddata *udata, struct list_head *lh, const char **ns); |
120 | |
121 | /** |
122 | * __aa_get_loaddata - get a reference count to uncounted data reference |
123 | * @data: reference to get a count on |
124 | * |
125 | * Returns: pointer to reference OR NULL if race is lost and reference is |
126 | * being repeated. |
127 | * Requires: @data->ns->lock held, and the return code MUST be checked |
128 | * |
129 | * Use only from inode->i_private and @data->list found references |
130 | */ |
131 | static inline struct aa_loaddata * |
132 | __aa_get_loaddata(struct aa_loaddata *data) |
133 | { |
134 | if (data && kref_get_unless_zero(kref: &(data->count))) |
135 | return data; |
136 | |
137 | return NULL; |
138 | } |
139 | |
140 | /** |
141 | * aa_get_loaddata - get a reference count from a counted data reference |
142 | * @data: reference to get a count on |
143 | * |
144 | * Returns: point to reference |
145 | * Requires: @data to have a valid reference count on it. It is a bug |
146 | * if the race to reap can be encountered when it is used. |
147 | */ |
148 | static inline struct aa_loaddata * |
149 | aa_get_loaddata(struct aa_loaddata *data) |
150 | { |
151 | struct aa_loaddata *tmp = __aa_get_loaddata(data); |
152 | |
153 | AA_BUG(data && !tmp); |
154 | |
155 | return tmp; |
156 | } |
157 | |
158 | void __aa_loaddata_update(struct aa_loaddata *data, long revision); |
159 | bool aa_rawdata_eq(struct aa_loaddata *l, struct aa_loaddata *r); |
160 | void aa_loaddata_kref(struct kref *kref); |
161 | struct aa_loaddata *aa_loaddata_alloc(size_t size); |
162 | static inline void aa_put_loaddata(struct aa_loaddata *data) |
163 | { |
164 | if (data) |
165 | kref_put(kref: &data->count, release: aa_loaddata_kref); |
166 | } |
167 | |
168 | #if IS_ENABLED(CONFIG_KUNIT) |
169 | bool aa_inbounds(struct aa_ext *e, size_t size); |
170 | size_t aa_unpack_u16_chunk(struct aa_ext *e, char **chunk); |
171 | bool aa_unpack_X(struct aa_ext *e, enum aa_code code); |
172 | bool aa_unpack_nameX(struct aa_ext *e, enum aa_code code, const char *name); |
173 | bool aa_unpack_u32(struct aa_ext *e, u32 *data, const char *name); |
174 | bool aa_unpack_u64(struct aa_ext *e, u64 *data, const char *name); |
175 | bool aa_unpack_array(struct aa_ext *e, const char *name, u16 *size); |
176 | size_t aa_unpack_blob(struct aa_ext *e, char **blob, const char *name); |
177 | int aa_unpack_str(struct aa_ext *e, const char **string, const char *name); |
178 | int aa_unpack_strdup(struct aa_ext *e, char **string, const char *name); |
179 | #endif |
180 | |
181 | #endif /* __POLICY_INTERFACE_H */ |
182 | |