| 1 |
|
| 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 | #include "lib.h"
|
| 20 |
|
| 21 | struct aa_load_ent {
|
| 22 | struct list_head list;
|
| 23 | struct aa_profile *new;
|
| 24 | struct aa_profile *old;
|
| 25 | struct aa_profile *rename;
|
| 26 | const char *ns_name;
|
| 27 | };
|
| 28 |
|
| 29 | void aa_load_ent_free(struct aa_load_ent *ent);
|
| 30 | struct aa_load_ent *aa_load_ent_alloc(void);
|
| 31 |
|
| 32 | #define PACKED_FLAG_HAT 1
|
| 33 | #define PACKED_FLAG_DEBUG1 2
|
| 34 | #define PACKED_FLAG_DEBUG2 4
|
| 35 |
|
| 36 | #define PACKED_MODE_ENFORCE 0
|
| 37 | #define PACKED_MODE_COMPLAIN 1
|
| 38 | #define PACKED_MODE_KILL 2
|
| 39 | #define PACKED_MODE_UNCONFINED 3
|
| 40 | #define PACKED_MODE_USER 4
|
| 41 |
|
| 42 | struct aa_ns;
|
| 43 |
|
| 44 | enum {
|
| 45 | AAFS_LOADDATA_ABI = 0,
|
| 46 | AAFS_LOADDATA_REVISION,
|
| 47 | AAFS_LOADDATA_HASH,
|
| 48 | AAFS_LOADDATA_DATA,
|
| 49 | AAFS_LOADDATA_COMPRESSED_SIZE,
|
| 50 | AAFS_LOADDATA_DIR,
|
| 51 | AAFS_LOADDATA_NDENTS
|
| 52 | };
|
| 53 |
|
| 54 | |
| 55 | * The AppArmor interface treats data as a type byte followed by the
|
| 56 | * actual data. The interface has the notion of a named entry
|
| 57 | * which has a name (AA_NAME typecode followed by name string) followed by
|
| 58 | * the entries typecode and data. Named types allow for optional
|
| 59 | * elements and extensions to be added and tested for without breaking
|
| 60 | * backwards compatibility.
|
| 61 |
|
| 62 |
|
| 63 | enum aa_code {
|
| 64 | AA_U8,
|
| 65 | AA_U16,
|
| 66 | AA_U32,
|
| 67 | AA_U64,
|
| 68 | AA_NAME,
|
| 69 | AA_STRING,
|
| 70 | AA_BLOB,
|
| 71 | AA_STRUCT,
|
| 72 | AA_STRUCTEND,
|
| 73 | AA_LIST,
|
| 74 | AA_LISTEND,
|
| 75 | AA_ARRAY,
|
| 76 | AA_ARRAYEND,
|
| 77 | };
|
| 78 |
|
| 79 | |
| 80 | * aa_ext is the read of the buffer containing the serialized profile. The
|
| 81 | * data is copied into a kernel buffer in apparmorfs and then handed off to
|
| 82 | * the unpack routines.
|
| 83 |
|
| 84 | struct aa_ext {
|
| 85 | void *start;
|
| 86 | void *end;
|
| 87 | void *pos;
|
| 88 | u32 version;
|
| 89 | };
|
| 90 |
|
| 91 | |
| 92 | * @count: inode/filesystem refcount - use aa_get_i_loaddata()
|
| 93 | * @pcount: profile refcount - use aa_get_profile_loaddata()
|
| 94 | * @list: list the loaddata is on
|
| 95 | * @work: used to do a delayed cleanup
|
| 96 | * @dents: refs to dents created in aafs
|
| 97 | * @ns: the namespace this loaddata was loaded into
|
| 98 | * @name:
|
| 99 | * @size: the size of the data that was loaded
|
| 100 | * @compressed_size: the size of the data when it is compressed
|
| 101 | * @revision: unique revision count that this data was loaded as
|
| 102 | * @abi: the abi number the loaddata uses
|
| 103 | * @hash: a hash of the loaddata, used to help dedup data
|
| 104 | *
|
| 105 | * There is no loaddata ref for being on ns->rawdata_list, so
|
| 106 | * @ns->lock must be held when walking the list. Dentries and
|
| 107 | * inode opens hold refs on @count; profiles hold refs on @pcount.
|
| 108 | * When the last @pcount drops, do_ploaddata_rmfs() removes the
|
| 109 | * fs entries and drops the associated @count ref.
|
| 110 |
|
| 111 | struct aa_loaddata {
|
| 112 | struct aa_common_ref count;
|
| 113 | struct kref pcount;
|
| 114 | struct list_head list;
|
| 115 | struct work_struct work;
|
| 116 | struct dentry *dents[AAFS_LOADDATA_NDENTS];
|
| 117 | struct aa_ns *ns;
|
| 118 | char *name;
|
| 119 | size_t size;
|
| 120 | size_t compressed_size;
|
| 121 | long revision;
|
| 122 | int abi;
|
| 123 | unsigned char *hash;
|
| 124 |
|
| 125 | |
| 126 | * compressed version of the payload, else it is the uncompressed
|
| 127 | * version (with the size indicated by @size).
|
| 128 |
|
| 129 | char *data;
|
| 130 | };
|
| 131 |
|
| 132 | int aa_unpack(struct aa_loaddata *udata, struct list_head *lh, const char **ns,
|
| 133 | char *compressed_data, size_t compressed_size);
|
| 134 |
|
| 135 | |
| 136 | * aa_get_i_loaddata - get a reference count from a counted data reference
|
| 137 | * @data: reference to get a count on
|
| 138 | *
|
| 139 | * Returns: pointer to reference
|
| 140 | * Requires: @data to have a valid reference count on it. It is a bug
|
| 141 | * if the race to reap can be encountered when it is used.
|
| 142 |
|
| 143 | static inline struct aa_loaddata *
|
| 144 | aa_get_i_loaddata(struct aa_loaddata *data)
|
| 145 | {
|
| 146 |
|
| 147 | if (data)
|
| 148 | kref_get(&(data->count.count));
|
| 149 | return data;
|
| 150 | }
|
| 151 |
|
| 152 |
|
| 153 | |
| 154 | * aa_get_profile_loaddata - get a profile reference count on loaddata
|
| 155 | * @data: reference to get a count on
|
| 156 | *
|
| 157 | * Returns: pointer to reference
|
| 158 | * Requires: @data to have a valid reference count on it.
|
| 159 |
|
| 160 | static inline struct aa_loaddata *
|
| 161 | aa_get_profile_loaddata(struct aa_loaddata *data)
|
| 162 | {
|
| 163 | if (data)
|
| 164 | kref_get(&(data->pcount));
|
| 165 | return data;
|
| 166 | }
|
| 167 |
|
| 168 | |
| 169 | * aa_get_profile_loaddata_not0 - get a profile reference count if not zero
|
| 170 | * @data: reference to get a count on
|
| 171 | *
|
| 172 | * Like aa_get_profile_loaddata(), but safe to call on an entry that may
|
| 173 | * be on a list (e.g. ns->rawdata_list) where the last pcount has already
|
| 174 | * dropped and the deferred cleanup has not yet run.
|
| 175 | *
|
| 176 | * Returns: pointer to reference, or %NULL if @data is NULL or its
|
| 177 | * profile refcount has already reached zero.
|
| 178 |
|
| 179 | static inline struct aa_loaddata *
|
| 180 | aa_get_profile_loaddata_not0(struct aa_loaddata *data)
|
| 181 | {
|
| 182 | if (data && kref_get_unless_zero(&data->pcount))
|
| 183 | return data;
|
| 184 | return NULL;
|
| 185 | }
|
| 186 |
|
| 187 | void __aa_loaddata_update(struct aa_loaddata *data, long revision);
|
| 188 | bool aa_rawdata_eq(struct aa_loaddata *l, struct aa_loaddata *r);
|
| 189 | void aa_loaddata_kref(struct kref *kref);
|
| 190 | void aa_ploaddata_kref(struct kref *kref);
|
| 191 | struct aa_loaddata *aa_loaddata_alloc(size_t size);
|
| 192 | static inline void aa_put_i_loaddata(struct aa_loaddata *data)
|
| 193 | {
|
| 194 | if (data)
|
| 195 | kref_put(&data->count.count, aa_loaddata_kref);
|
| 196 | }
|
| 197 |
|
| 198 | static inline void aa_put_profile_loaddata(struct aa_loaddata *data)
|
| 199 | {
|
| 200 | if (data)
|
| 201 | kref_put(&data->pcount, aa_ploaddata_kref);
|
| 202 | }
|
| 203 |
|
| 204 | #if IS_ENABLED(CONFIG_KUNIT)
|
| 205 | bool aa_inbounds(struct aa_ext *e, size_t size);
|
| 206 | size_t aa_unpack_u16_chunk(struct aa_ext *e, char **chunk);
|
| 207 | bool aa_unpack_X(struct aa_ext *e, enum aa_code code);
|
| 208 | bool aa_unpack_nameX(struct aa_ext *e, enum aa_code code, const char *name);
|
| 209 | bool aa_unpack_u32(struct aa_ext *e, u32 *data, const char *name);
|
| 210 | bool aa_unpack_u64(struct aa_ext *e, u64 *data, const char *name);
|
| 211 | bool aa_unpack_array(struct aa_ext *e, const char *name, u16 *size);
|
| 212 | size_t aa_unpack_blob(struct aa_ext *e, char **blob, const char *name);
|
| 213 | int aa_unpack_str(struct aa_ext *e, const char **string, const char *name);
|
| 214 | int aa_unpack_strdup(struct aa_ext *e, char **string, const char *name);
|
| 215 | #endif
|
| 216 |
|
| 217 | #endif
|