xref: /linux/security/apparmor/include/policy_unpack.h (revision 281f36d4a9970c206c2c44042904d4e34c092fbe)
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 /* struct aa_loaddata - buffer of policy raw_data set
91  * @count: inode/filesystem refcount - use aa_get_i_loaddata()
92  * @pcount: profile refcount - use aa_get_profile_loaddata()
93  * @list: list the loaddata is on
94  * @work: used to do a delayed cleanup
95  * @dents: refs to dents created in aafs
96  * @ns: the namespace this loaddata was loaded into
97  * @name:
98  * @size: the size of the data that was loaded
99  * @compressed_size: the size of the data when it is compressed
100  * @revision: unique revision count that this data was loaded as
101  * @abi: the abi number the loaddata uses
102  * @hash: a hash of the loaddata, used to help dedup data
103  *
104  * There is no loaddata ref for being on ns->rawdata_list, so
105  * @ns->lock must be held when walking the list. Dentries and
106  * inode opens hold refs on @count; profiles hold refs on @pcount.
107  * When the last @pcount drops, do_ploaddata_rmfs() removes the
108  * fs entries and drops the associated @count ref.
109  */
110 struct aa_loaddata {
111 	struct aa_common_ref count;
112 	struct kref pcount;
113 	struct list_head list;
114 	struct work_struct work;
115 	struct dentry *dents[AAFS_LOADDATA_NDENTS];
116 	struct aa_ns *ns;
117 	char *name;
118 	size_t size;			/* the original size of the payload */
119 	size_t compressed_size;		/* the compressed size of the payload */
120 	long revision;			/* the ns policy revision this caused */
121 	int abi;
122 	unsigned char *hash;
123 
124 	/* Pointer to payload. If @compressed_size > 0, then this is the
125 	 * compressed version of the payload, else it is the uncompressed
126 	 * version (with the size indicated by @size).
127 	 */
128 	char *data;
129 };
130 
131 int aa_unpack(struct aa_loaddata *udata, struct list_head *lh, const char **ns);
132 
133 /**
134  * aa_get_loaddata - get a reference count from a counted data reference
135  * @data: reference to get a count on
136  *
137  * Returns: pointer to reference
138  * Requires: @data to have a valid reference count on it. It is a bug
139  *           if the race to reap can be encountered when it is used.
140  */
141 static inline struct aa_loaddata *
aa_get_i_loaddata(struct aa_loaddata * data)142 aa_get_i_loaddata(struct aa_loaddata *data)
143 {
144 
145 	if (data)
146 		kref_get(&(data->count.count));
147 	return data;
148 }
149 
150 
151 /**
152  * aa_get_profile_loaddata - get a profile reference count on loaddata
153  * @data: reference to get a count on
154  *
155  * Returns: pointer to reference
156  * Requires: @data to have a valid reference count on it.
157  */
158 static inline struct aa_loaddata *
aa_get_profile_loaddata(struct aa_loaddata * data)159 aa_get_profile_loaddata(struct aa_loaddata *data)
160 {
161 	if (data)
162 		kref_get(&(data->pcount));
163 	return data;
164 }
165 
166 void __aa_loaddata_update(struct aa_loaddata *data, long revision);
167 bool aa_rawdata_eq(struct aa_loaddata *l, struct aa_loaddata *r);
168 void aa_loaddata_kref(struct kref *kref);
169 void aa_ploaddata_kref(struct kref *kref);
170 struct aa_loaddata *aa_loaddata_alloc(size_t size);
aa_put_i_loaddata(struct aa_loaddata * data)171 static inline void aa_put_i_loaddata(struct aa_loaddata *data)
172 {
173 	if (data)
174 		kref_put(&data->count.count, aa_loaddata_kref);
175 }
176 
aa_put_profile_loaddata(struct aa_loaddata * data)177 static inline void aa_put_profile_loaddata(struct aa_loaddata *data)
178 {
179 	if (data)
180 		kref_put(&data->pcount, aa_ploaddata_kref);
181 }
182 
183 #if IS_ENABLED(CONFIG_KUNIT)
184 bool aa_inbounds(struct aa_ext *e, size_t size);
185 size_t aa_unpack_u16_chunk(struct aa_ext *e, char **chunk);
186 bool aa_unpack_X(struct aa_ext *e, enum aa_code code);
187 bool aa_unpack_nameX(struct aa_ext *e, enum aa_code code, const char *name);
188 bool aa_unpack_u32(struct aa_ext *e, u32 *data, const char *name);
189 bool aa_unpack_u64(struct aa_ext *e, u64 *data, const char *name);
190 bool aa_unpack_array(struct aa_ext *e, const char *name, u16 *size);
191 size_t aa_unpack_blob(struct aa_ext *e, char **blob, const char *name);
192 int aa_unpack_str(struct aa_ext *e, const char **string, const char *name);
193 int aa_unpack_strdup(struct aa_ext *e, char **string, const char *name);
194 #endif
195 
196 #endif /* __POLICY_INTERFACE_H */
197