#include <linux/ctype.h>
#include <linux/security.h>
#include <linux/vmalloc.h>
#include <linux/init.h>
#include <linux/seq_file.h>
#include <linux/uaccess.h>
#include <linux/mount.h>
#include <linux/namei.h>
#include <linux/capability.h>
#include <linux/rcupdate.h>
#include <linux/fs.h>
#include <linux/fs_context.h>
#include <linux/poll.h>
#include <linux/zstd.h>
#include <uapi/linux/major.h>
#include <uapi/linux/magic.h>
#include "include/apparmor.h"
#include "include/apparmorfs.h"
#include "include/audit.h"
#include "include/cred.h"
#include "include/crypto.h"
#include "include/ipc.h"
#include "include/label.h"
#include "include/policy.h"
#include "include/policy_ns.h"
#include "include/resource.h"
#include "include/policy_unpack.h"
#include "include/task.h"
struct rawdata_f_data { … };
#ifdef CONFIG_SECURITY_APPARMOR_EXPORT_BINARY
#define RAWDATA_F_DATA_BUF(p) …
static void rawdata_f_data_free(struct rawdata_f_data *private)
{ … }
static struct rawdata_f_data *rawdata_f_data_alloc(size_t size)
{ … }
#endif
static int mangle_name(const char *name, char *target)
{ … }
#define AAFS_NAME …
static struct vfsmount *aafs_mnt;
static int aafs_count;
static int aafs_show_path(struct seq_file *seq, struct dentry *dentry)
{ … }
static void aafs_free_inode(struct inode *inode)
{ … }
static const struct super_operations aafs_super_ops = …;
static int apparmorfs_fill_super(struct super_block *sb, struct fs_context *fc)
{ … }
static int apparmorfs_get_tree(struct fs_context *fc)
{ … }
static const struct fs_context_operations apparmorfs_context_ops = …;
static int apparmorfs_init_fs_context(struct fs_context *fc)
{ … }
static struct file_system_type aafs_ops = …;
static int __aafs_setup_d_inode(struct inode *dir, struct dentry *dentry,
umode_t mode, void *data, char *link,
const struct file_operations *fops,
const struct inode_operations *iops)
{ … }
static struct dentry *aafs_create(const char *name, umode_t mode,
struct dentry *parent, void *data, void *link,
const struct file_operations *fops,
const struct inode_operations *iops)
{ … }
static struct dentry *aafs_create_file(const char *name, umode_t mode,
struct dentry *parent, void *data,
const struct file_operations *fops)
{ … }
static struct dentry *aafs_create_dir(const char *name, struct dentry *parent)
{ … }
static void aafs_remove(struct dentry *dentry)
{ … }
static struct aa_loaddata *aa_simple_write_to_buffer(const char __user *userbuf,
size_t alloc_size,
size_t copy_size,
loff_t *pos)
{ … }
static ssize_t policy_update(u32 mask, const char __user *buf, size_t size,
loff_t *pos, struct aa_ns *ns)
{ … }
static ssize_t profile_load(struct file *f, const char __user *buf, size_t size,
loff_t *pos)
{ … }
static const struct file_operations aa_fs_profile_load = …;
static ssize_t profile_replace(struct file *f, const char __user *buf,
size_t size, loff_t *pos)
{ … }
static const struct file_operations aa_fs_profile_replace = …;
static ssize_t profile_remove(struct file *f, const char __user *buf,
size_t size, loff_t *pos)
{ … }
static const struct file_operations aa_fs_profile_remove = …;
struct aa_revision { … };
static int ns_revision_release(struct inode *inode, struct file *file)
{ … }
static ssize_t ns_revision_read(struct file *file, char __user *buf,
size_t size, loff_t *ppos)
{ … }
static int ns_revision_open(struct inode *inode, struct file *file)
{ … }
static __poll_t ns_revision_poll(struct file *file, poll_table *pt)
{ … }
void __aa_bump_ns_revision(struct aa_ns *ns)
{ … }
static const struct file_operations aa_fs_ns_revision_fops = …;
static void profile_query_cb(struct aa_profile *profile, struct aa_perms *perms,
const char *match_str, size_t match_len)
{ … }
static ssize_t query_data(char *buf, size_t buf_len,
char *query, size_t query_len)
{ … }
static ssize_t query_label(char *buf, size_t buf_len,
char *query, size_t query_len, bool view_only)
{ … }
struct multi_transaction { … };
#define MULTI_TRANSACTION_LIMIT …
static void multi_transaction_kref(struct kref *kref)
{ … }
static struct multi_transaction *
get_multi_transaction(struct multi_transaction *t)
{ … }
static void put_multi_transaction(struct multi_transaction *t)
{ … }
static void multi_transaction_set(struct file *file,
struct multi_transaction *new, size_t n)
{ … }
static struct multi_transaction *multi_transaction_new(struct file *file,
const char __user *buf,
size_t size)
{ … }
static ssize_t multi_transaction_read(struct file *file, char __user *buf,
size_t size, loff_t *pos)
{ … }
static int multi_transaction_release(struct inode *inode, struct file *file)
{ … }
#define QUERY_CMD_LABEL …
#define QUERY_CMD_LABEL_LEN …
#define QUERY_CMD_PROFILE …
#define QUERY_CMD_PROFILE_LEN …
#define QUERY_CMD_LABELALL …
#define QUERY_CMD_LABELALL_LEN …
#define QUERY_CMD_DATA …
#define QUERY_CMD_DATA_LEN …
static ssize_t aa_write_access(struct file *file, const char __user *ubuf,
size_t count, loff_t *ppos)
{ … }
static const struct file_operations aa_sfs_access = …;
static int aa_sfs_seq_show(struct seq_file *seq, void *v)
{ … }
static int aa_sfs_seq_open(struct inode *inode, struct file *file)
{ … }
const struct file_operations aa_sfs_seq_file_ops = …;
#define SEQ_PROFILE_FOPS(NAME) … \
static int seq_profile_open(struct inode *inode, struct file *file,
int (*show)(struct seq_file *, void *))
{ … }
static int seq_profile_release(struct inode *inode, struct file *file)
{ … }
static int seq_profile_name_show(struct seq_file *seq, void *v)
{ … }
static int seq_profile_mode_show(struct seq_file *seq, void *v)
{ … }
static int seq_profile_attach_show(struct seq_file *seq, void *v)
{ … }
static int seq_profile_hash_show(struct seq_file *seq, void *v)
{ … }
SEQ_PROFILE_FOPS(…);
SEQ_PROFILE_FOPS(…);
SEQ_PROFILE_FOPS(…);
SEQ_PROFILE_FOPS(…);
#define SEQ_NS_FOPS(NAME) … \
static int seq_ns_stacked_show(struct seq_file *seq, void *v)
{ … }
static int seq_ns_nsstacked_show(struct seq_file *seq, void *v)
{ … }
static int seq_ns_level_show(struct seq_file *seq, void *v)
{ … }
static int seq_ns_name_show(struct seq_file *seq, void *v)
{ … }
static int seq_ns_compress_min_show(struct seq_file *seq, void *v)
{ … }
static int seq_ns_compress_max_show(struct seq_file *seq, void *v)
{ … }
SEQ_NS_FOPS(…);
SEQ_NS_FOPS(…);
SEQ_NS_FOPS(…);
SEQ_NS_FOPS(…);
SEQ_NS_FOPS(…);
SEQ_NS_FOPS(…);
#ifdef CONFIG_SECURITY_APPARMOR_EXPORT_BINARY
#define SEQ_RAWDATA_FOPS(NAME) … \
static int seq_rawdata_open(struct inode *inode, struct file *file,
int (*show)(struct seq_file *, void *))
{ … }
static int seq_rawdata_release(struct inode *inode, struct file *file)
{ … }
static int seq_rawdata_abi_show(struct seq_file *seq, void *v)
{ … }
static int seq_rawdata_revision_show(struct seq_file *seq, void *v)
{ … }
static int seq_rawdata_hash_show(struct seq_file *seq, void *v)
{ … }
static int seq_rawdata_compressed_size_show(struct seq_file *seq, void *v)
{ … }
SEQ_RAWDATA_FOPS(…);
SEQ_RAWDATA_FOPS(…);
SEQ_RAWDATA_FOPS(…);
SEQ_RAWDATA_FOPS(…);
static int decompress_zstd(char *src, size_t slen, char *dst, size_t dlen)
{ … }
static ssize_t rawdata_read(struct file *file, char __user *buf, size_t size,
loff_t *ppos)
{ … }
static int rawdata_release(struct inode *inode, struct file *file)
{ … }
static int rawdata_open(struct inode *inode, struct file *file)
{ … }
static const struct file_operations rawdata_fops = …;
static void remove_rawdata_dents(struct aa_loaddata *rawdata)
{ … }
void __aa_fs_remove_rawdata(struct aa_loaddata *rawdata)
{ … }
int __aa_fs_create_rawdata(struct aa_ns *ns, struct aa_loaddata *rawdata)
{ … }
#endif
void __aafs_profile_rmdir(struct aa_profile *profile)
{ … }
void __aafs_profile_migrate_dents(struct aa_profile *old,
struct aa_profile *new)
{ … }
static struct dentry *create_profile_file(struct dentry *dir, const char *name,
struct aa_profile *profile,
const struct file_operations *fops)
{ … }
#ifdef CONFIG_SECURITY_APPARMOR_EXPORT_BINARY
static int profile_depth(struct aa_profile *profile)
{ … }
static char *gen_symlink_name(int depth, const char *dirname, const char *fname)
{ … }
static const char *rawdata_get_link_base(struct dentry *dentry,
struct inode *inode,
struct delayed_call *done,
const char *name)
{ … }
static const char *rawdata_get_link_sha256(struct dentry *dentry,
struct inode *inode,
struct delayed_call *done)
{ … }
static const char *rawdata_get_link_abi(struct dentry *dentry,
struct inode *inode,
struct delayed_call *done)
{ … }
static const char *rawdata_get_link_data(struct dentry *dentry,
struct inode *inode,
struct delayed_call *done)
{ … }
static const struct inode_operations rawdata_link_sha256_iops = …;
static const struct inode_operations rawdata_link_abi_iops = …;
static const struct inode_operations rawdata_link_data_iops = …;
#endif
int __aafs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
{ … }
static int ns_mkdir_op(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, umode_t mode)
{ … }
static int ns_rmdir_op(struct inode *dir, struct dentry *dentry)
{ … }
static const struct inode_operations ns_dir_inode_operations = …;
static void __aa_fs_list_remove_rawdata(struct aa_ns *ns)
{ … }
void __aafs_ns_rmdir(struct aa_ns *ns)
{ … }
static int __aafs_ns_mkdir_entries(struct aa_ns *ns, struct dentry *dir)
{ … }
int __aafs_ns_mkdir(struct aa_ns *ns, struct dentry *parent, const char *name,
struct dentry *dent)
{ … }
static struct aa_ns *__next_ns(struct aa_ns *root, struct aa_ns *ns)
{ … }
static struct aa_profile *__first_profile(struct aa_ns *root,
struct aa_ns *ns)
{ … }
static struct aa_profile *__next_profile(struct aa_profile *p)
{ … }
static struct aa_profile *next_profile(struct aa_ns *root,
struct aa_profile *profile)
{ … }
static void *p_start(struct seq_file *f, loff_t *pos)
{ … }
static void *p_next(struct seq_file *f, void *p, loff_t *pos)
{ … }
static void p_stop(struct seq_file *f, void *p)
{ … }
static int seq_show_profile(struct seq_file *f, void *p)
{ … }
static const struct seq_operations aa_sfs_profiles_op = …;
static int profiles_open(struct inode *inode, struct file *file)
{ … }
static int profiles_release(struct inode *inode, struct file *file)
{ … }
static const struct file_operations aa_sfs_profiles_fops = …;
static struct aa_sfs_entry aa_sfs_entry_file[] = …;
static struct aa_sfs_entry aa_sfs_entry_ptrace[] = …;
static struct aa_sfs_entry aa_sfs_entry_signal[] = …;
static struct aa_sfs_entry aa_sfs_entry_attach[] = …;
static struct aa_sfs_entry aa_sfs_entry_domain[] = …;
static struct aa_sfs_entry aa_sfs_entry_unconfined[] = …;
static struct aa_sfs_entry aa_sfs_entry_versions[] = …;
#define PERMS32STR …
static struct aa_sfs_entry aa_sfs_entry_policy[] = …;
static struct aa_sfs_entry aa_sfs_entry_mount[] = …;
static struct aa_sfs_entry aa_sfs_entry_ns[] = …;
static struct aa_sfs_entry aa_sfs_entry_query_label[] = …;
static struct aa_sfs_entry aa_sfs_entry_query[] = …;
static struct aa_sfs_entry aa_sfs_entry_io_uring[] = …;
static struct aa_sfs_entry aa_sfs_entry_features[] = …;
static struct aa_sfs_entry aa_sfs_entry_apparmor[] = …;
static struct aa_sfs_entry aa_sfs_entry = …;
static int __init entry_create_file(struct aa_sfs_entry *fs_file,
struct dentry *parent)
{ … }
static void __init entry_remove_dir(struct aa_sfs_entry *fs_dir);
static int __init entry_create_dir(struct aa_sfs_entry *fs_dir,
struct dentry *parent)
{ … }
static void __init entry_remove_file(struct aa_sfs_entry *fs_file)
{ … }
static void __init entry_remove_dir(struct aa_sfs_entry *fs_dir)
{ … }
void __init aa_destroy_aafs(void)
{ … }
#define NULL_FILE_NAME …
struct path aa_null;
static int aa_mk_null_file(struct dentry *parent)
{ … }
static const char *policy_get_link(struct dentry *dentry,
struct inode *inode,
struct delayed_call *done)
{ … }
static int policy_readlink(struct dentry *dentry, char __user *buffer,
int buflen)
{ … }
static const struct inode_operations policy_link_iops = …;
static int __init aa_create_aafs(void)
{ … }
fs_initcall(aa_create_aafs);