162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * AppArmor security module 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * This file contains AppArmor policy loading interface function definitions. 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Copyright (C) 1998-2008 Novell/SUSE 862306a36Sopenharmony_ci * Copyright 2009-2010 Canonical Ltd. 962306a36Sopenharmony_ci */ 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#ifndef __POLICY_INTERFACE_H 1262306a36Sopenharmony_ci#define __POLICY_INTERFACE_H 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#include <linux/list.h> 1562306a36Sopenharmony_ci#include <linux/kref.h> 1662306a36Sopenharmony_ci#include <linux/dcache.h> 1762306a36Sopenharmony_ci#include <linux/workqueue.h> 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_cistruct aa_load_ent { 2162306a36Sopenharmony_ci struct list_head list; 2262306a36Sopenharmony_ci struct aa_profile *new; 2362306a36Sopenharmony_ci struct aa_profile *old; 2462306a36Sopenharmony_ci struct aa_profile *rename; 2562306a36Sopenharmony_ci const char *ns_name; 2662306a36Sopenharmony_ci}; 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_civoid aa_load_ent_free(struct aa_load_ent *ent); 2962306a36Sopenharmony_cistruct aa_load_ent *aa_load_ent_alloc(void); 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci#define PACKED_FLAG_HAT 1 3262306a36Sopenharmony_ci#define PACKED_FLAG_DEBUG1 2 3362306a36Sopenharmony_ci#define PACKED_FLAG_DEBUG2 4 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci#define PACKED_MODE_ENFORCE 0 3662306a36Sopenharmony_ci#define PACKED_MODE_COMPLAIN 1 3762306a36Sopenharmony_ci#define PACKED_MODE_KILL 2 3862306a36Sopenharmony_ci#define PACKED_MODE_UNCONFINED 3 3962306a36Sopenharmony_ci#define PACKED_MODE_USER 4 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_cistruct aa_ns; 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_cienum { 4462306a36Sopenharmony_ci AAFS_LOADDATA_ABI = 0, 4562306a36Sopenharmony_ci AAFS_LOADDATA_REVISION, 4662306a36Sopenharmony_ci AAFS_LOADDATA_HASH, 4762306a36Sopenharmony_ci AAFS_LOADDATA_DATA, 4862306a36Sopenharmony_ci AAFS_LOADDATA_COMPRESSED_SIZE, 4962306a36Sopenharmony_ci AAFS_LOADDATA_DIR, /* must be last actual entry */ 5062306a36Sopenharmony_ci AAFS_LOADDATA_NDENTS /* count of entries */ 5162306a36Sopenharmony_ci}; 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci/* 5462306a36Sopenharmony_ci * The AppArmor interface treats data as a type byte followed by the 5562306a36Sopenharmony_ci * actual data. The interface has the notion of a named entry 5662306a36Sopenharmony_ci * which has a name (AA_NAME typecode followed by name string) followed by 5762306a36Sopenharmony_ci * the entries typecode and data. Named types allow for optional 5862306a36Sopenharmony_ci * elements and extensions to be added and tested for without breaking 5962306a36Sopenharmony_ci * backwards compatibility. 6062306a36Sopenharmony_ci */ 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_cienum aa_code { 6362306a36Sopenharmony_ci AA_U8, 6462306a36Sopenharmony_ci AA_U16, 6562306a36Sopenharmony_ci AA_U32, 6662306a36Sopenharmony_ci AA_U64, 6762306a36Sopenharmony_ci AA_NAME, /* same as string except it is items name */ 6862306a36Sopenharmony_ci AA_STRING, 6962306a36Sopenharmony_ci AA_BLOB, 7062306a36Sopenharmony_ci AA_STRUCT, 7162306a36Sopenharmony_ci AA_STRUCTEND, 7262306a36Sopenharmony_ci AA_LIST, 7362306a36Sopenharmony_ci AA_LISTEND, 7462306a36Sopenharmony_ci AA_ARRAY, 7562306a36Sopenharmony_ci AA_ARRAYEND, 7662306a36Sopenharmony_ci}; 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci/* 7962306a36Sopenharmony_ci * aa_ext is the read of the buffer containing the serialized profile. The 8062306a36Sopenharmony_ci * data is copied into a kernel buffer in apparmorfs and then handed off to 8162306a36Sopenharmony_ci * the unpack routines. 8262306a36Sopenharmony_ci */ 8362306a36Sopenharmony_cistruct aa_ext { 8462306a36Sopenharmony_ci void *start; 8562306a36Sopenharmony_ci void *end; 8662306a36Sopenharmony_ci void *pos; /* pointer to current position in the buffer */ 8762306a36Sopenharmony_ci u32 version; 8862306a36Sopenharmony_ci}; 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci/* 9162306a36Sopenharmony_ci * struct aa_loaddata - buffer of policy raw_data set 9262306a36Sopenharmony_ci * 9362306a36Sopenharmony_ci * there is no loaddata ref for being on ns list, nor a ref from 9462306a36Sopenharmony_ci * d_inode(@dentry) when grab a ref from these, @ns->lock must be held 9562306a36Sopenharmony_ci * && __aa_get_loaddata() needs to be used, and the return value 9662306a36Sopenharmony_ci * checked, if NULL the loaddata is already being reaped and should be 9762306a36Sopenharmony_ci * considered dead. 9862306a36Sopenharmony_ci */ 9962306a36Sopenharmony_cistruct aa_loaddata { 10062306a36Sopenharmony_ci struct kref count; 10162306a36Sopenharmony_ci struct list_head list; 10262306a36Sopenharmony_ci struct work_struct work; 10362306a36Sopenharmony_ci struct dentry *dents[AAFS_LOADDATA_NDENTS]; 10462306a36Sopenharmony_ci struct aa_ns *ns; 10562306a36Sopenharmony_ci char *name; 10662306a36Sopenharmony_ci size_t size; /* the original size of the payload */ 10762306a36Sopenharmony_ci size_t compressed_size; /* the compressed size of the payload */ 10862306a36Sopenharmony_ci long revision; /* the ns policy revision this caused */ 10962306a36Sopenharmony_ci int abi; 11062306a36Sopenharmony_ci unsigned char *hash; 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci /* Pointer to payload. If @compressed_size > 0, then this is the 11362306a36Sopenharmony_ci * compressed version of the payload, else it is the uncompressed 11462306a36Sopenharmony_ci * version (with the size indicated by @size). 11562306a36Sopenharmony_ci */ 11662306a36Sopenharmony_ci char *data; 11762306a36Sopenharmony_ci}; 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ciint aa_unpack(struct aa_loaddata *udata, struct list_head *lh, const char **ns); 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci/** 12262306a36Sopenharmony_ci * __aa_get_loaddata - get a reference count to uncounted data reference 12362306a36Sopenharmony_ci * @data: reference to get a count on 12462306a36Sopenharmony_ci * 12562306a36Sopenharmony_ci * Returns: pointer to reference OR NULL if race is lost and reference is 12662306a36Sopenharmony_ci * being repeated. 12762306a36Sopenharmony_ci * Requires: @data->ns->lock held, and the return code MUST be checked 12862306a36Sopenharmony_ci * 12962306a36Sopenharmony_ci * Use only from inode->i_private and @data->list found references 13062306a36Sopenharmony_ci */ 13162306a36Sopenharmony_cistatic inline struct aa_loaddata * 13262306a36Sopenharmony_ci__aa_get_loaddata(struct aa_loaddata *data) 13362306a36Sopenharmony_ci{ 13462306a36Sopenharmony_ci if (data && kref_get_unless_zero(&(data->count))) 13562306a36Sopenharmony_ci return data; 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci return NULL; 13862306a36Sopenharmony_ci} 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci/** 14162306a36Sopenharmony_ci * aa_get_loaddata - get a reference count from a counted data reference 14262306a36Sopenharmony_ci * @data: reference to get a count on 14362306a36Sopenharmony_ci * 14462306a36Sopenharmony_ci * Returns: point to reference 14562306a36Sopenharmony_ci * Requires: @data to have a valid reference count on it. It is a bug 14662306a36Sopenharmony_ci * if the race to reap can be encountered when it is used. 14762306a36Sopenharmony_ci */ 14862306a36Sopenharmony_cistatic inline struct aa_loaddata * 14962306a36Sopenharmony_ciaa_get_loaddata(struct aa_loaddata *data) 15062306a36Sopenharmony_ci{ 15162306a36Sopenharmony_ci struct aa_loaddata *tmp = __aa_get_loaddata(data); 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci AA_BUG(data && !tmp); 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci return tmp; 15662306a36Sopenharmony_ci} 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_civoid __aa_loaddata_update(struct aa_loaddata *data, long revision); 15962306a36Sopenharmony_cibool aa_rawdata_eq(struct aa_loaddata *l, struct aa_loaddata *r); 16062306a36Sopenharmony_civoid aa_loaddata_kref(struct kref *kref); 16162306a36Sopenharmony_cistruct aa_loaddata *aa_loaddata_alloc(size_t size); 16262306a36Sopenharmony_cistatic inline void aa_put_loaddata(struct aa_loaddata *data) 16362306a36Sopenharmony_ci{ 16462306a36Sopenharmony_ci if (data) 16562306a36Sopenharmony_ci kref_put(&data->count, aa_loaddata_kref); 16662306a36Sopenharmony_ci} 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_KUNIT) 16962306a36Sopenharmony_cibool aa_inbounds(struct aa_ext *e, size_t size); 17062306a36Sopenharmony_cisize_t aa_unpack_u16_chunk(struct aa_ext *e, char **chunk); 17162306a36Sopenharmony_cibool aa_unpack_X(struct aa_ext *e, enum aa_code code); 17262306a36Sopenharmony_cibool aa_unpack_nameX(struct aa_ext *e, enum aa_code code, const char *name); 17362306a36Sopenharmony_cibool aa_unpack_u32(struct aa_ext *e, u32 *data, const char *name); 17462306a36Sopenharmony_cibool aa_unpack_u64(struct aa_ext *e, u64 *data, const char *name); 17562306a36Sopenharmony_cibool aa_unpack_array(struct aa_ext *e, const char *name, u16 *size); 17662306a36Sopenharmony_cisize_t aa_unpack_blob(struct aa_ext *e, char **blob, const char *name); 17762306a36Sopenharmony_ciint aa_unpack_str(struct aa_ext *e, const char **string, const char *name); 17862306a36Sopenharmony_ciint aa_unpack_strdup(struct aa_ext *e, char **string, const char *name); 17962306a36Sopenharmony_ci#endif 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ci#endif /* __POLICY_INTERFACE_H */ 182