Path: blob/master/security/apparmor/include/policy_unpack.h
26424 views
/* SPDX-License-Identifier: GPL-2.0-only */1/*2* AppArmor security module3*4* This file contains AppArmor policy loading interface function definitions.5*6* Copyright (C) 1998-2008 Novell/SUSE7* Copyright 2009-2010 Canonical Ltd.8*/910#ifndef __POLICY_INTERFACE_H11#define __POLICY_INTERFACE_H1213#include <linux/list.h>14#include <linux/kref.h>15#include <linux/dcache.h>16#include <linux/workqueue.h>171819struct aa_load_ent {20struct list_head list;21struct aa_profile *new;22struct aa_profile *old;23struct aa_profile *rename;24const char *ns_name;25};2627void aa_load_ent_free(struct aa_load_ent *ent);28struct aa_load_ent *aa_load_ent_alloc(void);2930#define PACKED_FLAG_HAT 131#define PACKED_FLAG_DEBUG1 232#define PACKED_FLAG_DEBUG2 43334#define PACKED_MODE_ENFORCE 035#define PACKED_MODE_COMPLAIN 136#define PACKED_MODE_KILL 237#define PACKED_MODE_UNCONFINED 338#define PACKED_MODE_USER 43940struct aa_ns;4142enum {43AAFS_LOADDATA_ABI = 0,44AAFS_LOADDATA_REVISION,45AAFS_LOADDATA_HASH,46AAFS_LOADDATA_DATA,47AAFS_LOADDATA_COMPRESSED_SIZE,48AAFS_LOADDATA_DIR, /* must be last actual entry */49AAFS_LOADDATA_NDENTS /* count of entries */50};5152/*53* The AppArmor interface treats data as a type byte followed by the54* actual data. The interface has the notion of a named entry55* which has a name (AA_NAME typecode followed by name string) followed by56* the entries typecode and data. Named types allow for optional57* elements and extensions to be added and tested for without breaking58* backwards compatibility.59*/6061enum aa_code {62AA_U8,63AA_U16,64AA_U32,65AA_U64,66AA_NAME, /* same as string except it is items name */67AA_STRING,68AA_BLOB,69AA_STRUCT,70AA_STRUCTEND,71AA_LIST,72AA_LISTEND,73AA_ARRAY,74AA_ARRAYEND,75};7677/*78* aa_ext is the read of the buffer containing the serialized profile. The79* data is copied into a kernel buffer in apparmorfs and then handed off to80* the unpack routines.81*/82struct aa_ext {83void *start;84void *end;85void *pos; /* pointer to current position in the buffer */86u32 version;87};8889/*90* struct aa_loaddata - buffer of policy raw_data set91*92* there is no loaddata ref for being on ns list, nor a ref from93* d_inode(@dentry) when grab a ref from these, @ns->lock must be held94* && __aa_get_loaddata() needs to be used, and the return value95* checked, if NULL the loaddata is already being reaped and should be96* considered dead.97*/98struct aa_loaddata {99struct kref count;100struct list_head list;101struct work_struct work;102struct dentry *dents[AAFS_LOADDATA_NDENTS];103struct aa_ns *ns;104char *name;105size_t size; /* the original size of the payload */106size_t compressed_size; /* the compressed size of the payload */107long revision; /* the ns policy revision this caused */108int abi;109unsigned char *hash;110111/* Pointer to payload. If @compressed_size > 0, then this is the112* compressed version of the payload, else it is the uncompressed113* version (with the size indicated by @size).114*/115char *data;116};117118int aa_unpack(struct aa_loaddata *udata, struct list_head *lh, const char **ns);119120/**121* __aa_get_loaddata - get a reference count to uncounted data reference122* @data: reference to get a count on123*124* Returns: pointer to reference OR NULL if race is lost and reference is125* being repeated.126* Requires: @data->ns->lock held, and the return code MUST be checked127*128* Use only from inode->i_private and @data->list found references129*/130static inline struct aa_loaddata *131__aa_get_loaddata(struct aa_loaddata *data)132{133if (data && kref_get_unless_zero(&(data->count)))134return data;135136return NULL;137}138139/**140* aa_get_loaddata - get a reference count from a counted data reference141* @data: reference to get a count on142*143* Returns: point to reference144* Requires: @data to have a valid reference count on it. It is a bug145* if the race to reap can be encountered when it is used.146*/147static inline struct aa_loaddata *148aa_get_loaddata(struct aa_loaddata *data)149{150struct aa_loaddata *tmp = __aa_get_loaddata(data);151152AA_BUG(data && !tmp);153154return tmp;155}156157void __aa_loaddata_update(struct aa_loaddata *data, long revision);158bool aa_rawdata_eq(struct aa_loaddata *l, struct aa_loaddata *r);159void aa_loaddata_kref(struct kref *kref);160struct aa_loaddata *aa_loaddata_alloc(size_t size);161static inline void aa_put_loaddata(struct aa_loaddata *data)162{163if (data)164kref_put(&data->count, aa_loaddata_kref);165}166167#if IS_ENABLED(CONFIG_KUNIT)168bool aa_inbounds(struct aa_ext *e, size_t size);169size_t aa_unpack_u16_chunk(struct aa_ext *e, char **chunk);170bool aa_unpack_X(struct aa_ext *e, enum aa_code code);171bool aa_unpack_nameX(struct aa_ext *e, enum aa_code code, const char *name);172bool aa_unpack_u32(struct aa_ext *e, u32 *data, const char *name);173bool aa_unpack_u64(struct aa_ext *e, u64 *data, const char *name);174bool aa_unpack_array(struct aa_ext *e, const char *name, u16 *size);175size_t aa_unpack_blob(struct aa_ext *e, char **blob, const char *name);176int aa_unpack_str(struct aa_ext *e, const char **string, const char *name);177int aa_unpack_strdup(struct aa_ext *e, char **string, const char *name);178#endif179180#endif /* __POLICY_INTERFACE_H */181182183