^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * AppArmor security module
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * This file contains AppArmor /sys/kernel/security/apparmor interface functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 1998-2008 Novell/SUSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright 2009-2010 Canonical Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/security.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/mount.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/namei.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/capability.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/rcupdate.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/fs_context.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/poll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/zlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <uapi/linux/major.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <uapi/linux/magic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include "include/apparmor.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include "include/apparmorfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include "include/audit.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include "include/cred.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include "include/crypto.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include "include/ipc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include "include/label.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include "include/policy.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include "include/policy_ns.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include "include/resource.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include "include/policy_unpack.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * The apparmor filesystem interface used for policy load and introspection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * The interface is split into two main components based on their function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * a securityfs component:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * used for static files that are always available, and which allows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * userspace to specificy the location of the security filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * fns and data are prefixed with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * aa_sfs_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * an apparmorfs component:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * used loaded policy content and introspection. It is not part of a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * regular mounted filesystem and is available only through the magic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * policy symlink in the root of the securityfs apparmor/ directory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * Tasks queries will be magically redirected to the correct portion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * of the policy tree based on their confinement.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * fns and data are prefixed with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * aafs_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * The aa_fs_ prefix is used to indicate the fn is used by both the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * securityfs and apparmorfs filesystems.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * support fns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct rawdata_f_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct aa_loaddata *loaddata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define RAWDATA_F_DATA_BUF(p) (char *)(p + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) static void rawdata_f_data_free(struct rawdata_f_data *private)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (!private)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) aa_put_loaddata(private->loaddata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) kvfree(private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static struct rawdata_f_data *rawdata_f_data_alloc(size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct rawdata_f_data *ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) if (size > SIZE_MAX - sizeof(*ret))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) ret = kvzalloc(sizeof(*ret) + size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * aa_mangle_name - mangle a profile name to std profile layout form
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * @name: profile name to mangle (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * @target: buffer to store mangled name, same length as @name (MAYBE NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * Returns: length of mangled name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static int mangle_name(const char *name, char *target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) char *t = target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) while (*name == '/' || *name == '.')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) name++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (target) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) for (; *name; name++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) if (*name == '/')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) *(t)++ = '.';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) else if (isspace(*name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) *(t)++ = '_';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) else if (isalnum(*name) || strchr("._-", *name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) *(t)++ = *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) *t = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) int len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) for (; *name; name++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (isalnum(*name) || isspace(*name) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) strchr("/._-", *name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) len++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return t - target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * aafs - core fns and data for the policy tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define AAFS_NAME "apparmorfs"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) static struct vfsmount *aafs_mnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static int aafs_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) static int aafs_show_path(struct seq_file *seq, struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) seq_printf(seq, "%s:[%lu]", AAFS_NAME, d_inode(dentry)->i_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) static void aafs_free_inode(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (S_ISLNK(inode->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) kfree(inode->i_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) free_inode_nonrcu(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static const struct super_operations aafs_super_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) .statfs = simple_statfs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) .free_inode = aafs_free_inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) .show_path = aafs_show_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) static int apparmorfs_fill_super(struct super_block *sb, struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) static struct tree_descr files[] = { {""} };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) error = simple_fill_super(sb, AAFS_MAGIC, files);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) sb->s_op = &aafs_super_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static int apparmorfs_get_tree(struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return get_tree_single(fc, apparmorfs_fill_super);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) static const struct fs_context_operations apparmorfs_context_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) .get_tree = apparmorfs_get_tree,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) static int apparmorfs_init_fs_context(struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) fc->ops = &apparmorfs_context_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) static struct file_system_type aafs_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) .name = AAFS_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) .init_fs_context = apparmorfs_init_fs_context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) .kill_sb = kill_anon_super,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * __aafs_setup_d_inode - basic inode setup for apparmorfs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * @dir: parent directory for the dentry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * @dentry: dentry we are seting the inode up for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * @mode: permissions the file should have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * @data: data to store on inode.i_private, available in open()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * @link: if symlink, symlink target string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * @fops: struct file_operations that should be used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) * @iops: struct of inode_operations that should be used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) static int __aafs_setup_d_inode(struct inode *dir, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) umode_t mode, void *data, char *link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) const struct file_operations *fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) const struct inode_operations *iops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) struct inode *inode = new_inode(dir->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) AA_BUG(!dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) AA_BUG(!dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (!inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) inode->i_ino = get_next_ino();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) inode->i_mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) inode->i_private = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (S_ISDIR(mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) inode->i_op = iops ? iops : &simple_dir_inode_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) inode->i_fop = &simple_dir_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) inc_nlink(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) inc_nlink(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) } else if (S_ISLNK(mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) inode->i_op = iops ? iops : &simple_symlink_inode_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) inode->i_link = link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) inode->i_fop = fops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) d_instantiate(dentry, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) dget(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) * aafs_create - create a dentry in the apparmorfs filesystem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * @name: name of dentry to create
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * @mode: permissions the file should have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) * @parent: parent directory for this dentry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * @data: data to store on inode.i_private, available in open()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * @link: if symlink, symlink target string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) * @fops: struct file_operations that should be used for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * @iops: struct of inode_operations that should be used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * This is the basic "create a xxx" function for apparmorfs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * Returns a pointer to a dentry if it succeeds, that must be free with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * aafs_remove(). Will return ERR_PTR on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) static struct dentry *aafs_create(const char *name, umode_t mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) struct dentry *parent, void *data, void *link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) const struct file_operations *fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) const struct inode_operations *iops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) struct dentry *dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) struct inode *dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) AA_BUG(!name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) AA_BUG(!parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (!(mode & S_IFMT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) mode = (mode & S_IALLUGO) | S_IFREG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) error = simple_pin_fs(&aafs_ops, &aafs_mnt, &aafs_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) return ERR_PTR(error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) dir = d_inode(parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) inode_lock(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) dentry = lookup_one_len(name, parent, strlen(name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (IS_ERR(dentry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) error = PTR_ERR(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) goto fail_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (d_really_is_positive(dentry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) error = -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) goto fail_dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) error = __aafs_setup_d_inode(dir, dentry, mode, data, link, fops, iops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) goto fail_dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) inode_unlock(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) return dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) fail_dentry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) dput(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) fail_lock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) inode_unlock(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) simple_release_fs(&aafs_mnt, &aafs_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return ERR_PTR(error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * aafs_create_file - create a file in the apparmorfs filesystem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * @name: name of dentry to create
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * @mode: permissions the file should have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) * @parent: parent directory for this dentry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * @data: data to store on inode.i_private, available in open()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * @fops: struct file_operations that should be used for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * see aafs_create
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) static struct dentry *aafs_create_file(const char *name, umode_t mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) struct dentry *parent, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) const struct file_operations *fops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) return aafs_create(name, mode, parent, data, NULL, fops, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) * aafs_create_dir - create a directory in the apparmorfs filesystem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) * @name: name of dentry to create
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) * @parent: parent directory for this dentry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) * see aafs_create
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) static struct dentry *aafs_create_dir(const char *name, struct dentry *parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return aafs_create(name, S_IFDIR | 0755, parent, NULL, NULL, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) * aafs_remove - removes a file or directory from the apparmorfs filesystem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) * @dentry: dentry of the file/directory/symlink to removed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) static void aafs_remove(struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) struct inode *dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (!dentry || IS_ERR(dentry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) dir = d_inode(dentry->d_parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) inode_lock(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (simple_positive(dentry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) if (d_is_dir(dentry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) simple_rmdir(dir, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) simple_unlink(dir, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) d_delete(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) dput(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) inode_unlock(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) simple_release_fs(&aafs_mnt, &aafs_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) * aa_fs - policy load/replace/remove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) * aa_simple_write_to_buffer - common routine for getting policy from user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) * @userbuf: user buffer to copy data from (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) * @alloc_size: size of user buffer (REQUIRES: @alloc_size >= @copy_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) * @copy_size: size of data to copy from user buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) * @pos: position write is at in the file (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) * Returns: kernel buffer containing copy of user buffer data or an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) * ERR_PTR on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) static struct aa_loaddata *aa_simple_write_to_buffer(const char __user *userbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) size_t alloc_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) size_t copy_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) struct aa_loaddata *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) AA_BUG(copy_size > alloc_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) if (*pos != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) /* only writes from pos 0, that is complete writes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) return ERR_PTR(-ESPIPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) /* freed by caller to simple_write_to_buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) data = aa_loaddata_alloc(alloc_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (IS_ERR(data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) data->size = copy_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if (copy_from_user(data->data, userbuf, copy_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) kvfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) return ERR_PTR(-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) static ssize_t policy_update(u32 mask, const char __user *buf, size_t size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) loff_t *pos, struct aa_ns *ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) struct aa_loaddata *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) struct aa_label *label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) ssize_t error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) label = begin_current_label_crit_section();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) /* high level check about policy management - fine grained in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) * below after unpack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) error = aa_may_manage_policy(label, ns, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) goto end_section;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) data = aa_simple_write_to_buffer(buf, size, size, pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) error = PTR_ERR(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (!IS_ERR(data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) error = aa_replace_profiles(ns, label, mask, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) aa_put_loaddata(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) end_section:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) end_current_label_crit_section(label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) /* .load file hook fn to load policy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) static ssize_t profile_load(struct file *f, const char __user *buf, size_t size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) struct aa_ns *ns = aa_get_ns(f->f_inode->i_private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) int error = policy_update(AA_MAY_LOAD_POLICY, buf, size, pos, ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) aa_put_ns(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) static const struct file_operations aa_fs_profile_load = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) .write = profile_load,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) .llseek = default_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) /* .replace file hook fn to load and/or replace policy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) static ssize_t profile_replace(struct file *f, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) size_t size, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) struct aa_ns *ns = aa_get_ns(f->f_inode->i_private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) int error = policy_update(AA_MAY_LOAD_POLICY | AA_MAY_REPLACE_POLICY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) buf, size, pos, ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) aa_put_ns(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) static const struct file_operations aa_fs_profile_replace = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) .write = profile_replace,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) .llseek = default_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) /* .remove file hook fn to remove loaded policy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) static ssize_t profile_remove(struct file *f, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) size_t size, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) struct aa_loaddata *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) struct aa_label *label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) ssize_t error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) struct aa_ns *ns = aa_get_ns(f->f_inode->i_private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) label = begin_current_label_crit_section();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) /* high level check about policy management - fine grained in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) * below after unpack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) error = aa_may_manage_policy(label, ns, AA_MAY_REMOVE_POLICY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) * aa_remove_profile needs a null terminated string so 1 extra
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) * byte is allocated and the copied data is null terminated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) data = aa_simple_write_to_buffer(buf, size + 1, size, pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) error = PTR_ERR(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (!IS_ERR(data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) data->data[size] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) error = aa_remove_profiles(ns, label, data->data, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) aa_put_loaddata(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) end_current_label_crit_section(label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) aa_put_ns(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) static const struct file_operations aa_fs_profile_remove = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) .write = profile_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) .llseek = default_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) struct aa_revision {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) struct aa_ns *ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) long last_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) /* revision file hook fn for policy loads */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) static int ns_revision_release(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) struct aa_revision *rev = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (rev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) aa_put_ns(rev->ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) kfree(rev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) static ssize_t ns_revision_read(struct file *file, char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) size_t size, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) struct aa_revision *rev = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) char buffer[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) long last_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) int avail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) mutex_lock_nested(&rev->ns->lock, rev->ns->level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) last_read = rev->last_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) if (last_read == rev->ns->revision) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) mutex_unlock(&rev->ns->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) if (file->f_flags & O_NONBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (wait_event_interruptible(rev->ns->wait,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) last_read !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) READ_ONCE(rev->ns->revision)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) return -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) mutex_lock_nested(&rev->ns->lock, rev->ns->level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) avail = sprintf(buffer, "%ld\n", rev->ns->revision);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (*ppos + size > avail) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) rev->last_read = rev->ns->revision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) *ppos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) mutex_unlock(&rev->ns->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) return simple_read_from_buffer(buf, size, ppos, buffer, avail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) static int ns_revision_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) struct aa_revision *rev = kzalloc(sizeof(*rev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) if (!rev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) rev->ns = aa_get_ns(inode->i_private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) if (!rev->ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) rev->ns = aa_get_current_ns();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) file->private_data = rev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) static __poll_t ns_revision_poll(struct file *file, poll_table *pt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) struct aa_revision *rev = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) __poll_t mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) if (rev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) mutex_lock_nested(&rev->ns->lock, rev->ns->level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) poll_wait(file, &rev->ns->wait, pt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) if (rev->last_read < rev->ns->revision)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) mask |= EPOLLIN | EPOLLRDNORM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) mutex_unlock(&rev->ns->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) return mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) void __aa_bump_ns_revision(struct aa_ns *ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) WRITE_ONCE(ns->revision, READ_ONCE(ns->revision) + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) wake_up_interruptible(&ns->wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) static const struct file_operations aa_fs_ns_revision_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) .open = ns_revision_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) .poll = ns_revision_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) .read = ns_revision_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) .llseek = generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) .release = ns_revision_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) static void profile_query_cb(struct aa_profile *profile, struct aa_perms *perms,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) const char *match_str, size_t match_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) struct aa_perms tmp = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) struct aa_dfa *dfa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) unsigned int state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (profile_unconfined(profile))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) if (profile->file.dfa && *match_str == AA_CLASS_FILE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) dfa = profile->file.dfa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) state = aa_dfa_match_len(dfa, profile->file.start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) match_str + 1, match_len - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) if (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) struct path_cond cond = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) tmp = aa_compute_fperms(dfa, state, &cond);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) } else if (profile->policy.dfa) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) if (!PROFILE_MEDIATES(profile, *match_str))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) return; /* no change to current perms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) dfa = profile->policy.dfa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) state = aa_dfa_match_len(dfa, profile->policy.start[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) match_str, match_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) if (state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) aa_compute_perms(dfa, state, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) aa_apply_modes_to_perms(profile, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) aa_perms_accum_raw(perms, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) * query_data - queries a policy and writes its data to buf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) * @buf: the resulting data is stored here (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) * @buf_len: size of buf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) * @query: query string used to retrieve data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) * @query_len: size of query including second NUL byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) * The buffers pointed to by buf and query may overlap. The query buffer is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) * parsed before buf is written to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) * The query should look like "<LABEL>\0<KEY>\0", where <LABEL> is the name of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) * the security confinement context and <KEY> is the name of the data to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) * retrieve. <LABEL> and <KEY> must not be NUL-terminated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) * Don't expect the contents of buf to be preserved on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) * Returns: number of characters written to buf or -errno on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) static ssize_t query_data(char *buf, size_t buf_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) char *query, size_t query_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) char *out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) const char *key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) struct label_it i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) struct aa_label *label, *curr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) struct aa_profile *profile;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) struct aa_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) u32 bytes, blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) __le32 outle32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) if (!query_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) return -EINVAL; /* need a query */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) key = query + strnlen(query, query_len) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) if (key + 1 >= query + query_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) return -EINVAL; /* not enough space for a non-empty key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) if (key + strnlen(key, query + query_len - key) >= query + query_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) return -EINVAL; /* must end with NUL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) if (buf_len < sizeof(bytes) + sizeof(blocks))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) return -EINVAL; /* not enough space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) curr = begin_current_label_crit_section();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) label = aa_label_parse(curr, query, GFP_KERNEL, false, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) end_current_label_crit_section(curr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if (IS_ERR(label))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) return PTR_ERR(label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) /* We are going to leave space for two numbers. The first is the total
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) * number of bytes we are writing after the first number. This is so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) * users can read the full output without reallocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) * The second number is the number of data blocks we're writing. An
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) * application might be confined by multiple policies having data in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) * the same key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) memset(buf, 0, sizeof(bytes) + sizeof(blocks));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) out = buf + sizeof(bytes) + sizeof(blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) blocks = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) label_for_each_confined(i, label, profile) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) if (!profile->data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) data = rhashtable_lookup_fast(profile->data, &key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) profile->data->p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if (data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) if (out + sizeof(outle32) + data->size > buf +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) buf_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) aa_put_label(label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) return -EINVAL; /* not enough space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) outle32 = __cpu_to_le32(data->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) memcpy(out, &outle32, sizeof(outle32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) out += sizeof(outle32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) memcpy(out, data->data, data->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) out += data->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) blocks++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) aa_put_label(label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) outle32 = __cpu_to_le32(out - buf - sizeof(bytes));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) memcpy(buf, &outle32, sizeof(outle32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) outle32 = __cpu_to_le32(blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) memcpy(buf + sizeof(bytes), &outle32, sizeof(outle32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) return out - buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) * query_label - queries a label and writes permissions to buf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) * @buf: the resulting permissions string is stored here (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) * @buf_len: size of buf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) * @query: binary query string to match against the dfa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) * @query_len: size of query
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) * @view_only: only compute for querier's view
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) * The buffers pointed to by buf and query may overlap. The query buffer is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) * parsed before buf is written to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) * The query should look like "LABEL_NAME\0DFA_STRING" where LABEL_NAME is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) * the name of the label, in the current namespace, that is to be queried and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) * DFA_STRING is a binary string to match against the label(s)'s DFA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) * LABEL_NAME must be NUL terminated. DFA_STRING may contain NUL characters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) * but must *not* be NUL terminated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) * Returns: number of characters written to buf or -errno on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) static ssize_t query_label(char *buf, size_t buf_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) char *query, size_t query_len, bool view_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) struct aa_profile *profile;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) struct aa_label *label, *curr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) char *label_name, *match_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) size_t label_name_len, match_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) struct aa_perms perms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) struct label_it i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) if (!query_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) label_name = query;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) label_name_len = strnlen(query, query_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) if (!label_name_len || label_name_len == query_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) * The extra byte is to account for the null byte between the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) * profile name and dfa string. profile_name_len is greater
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) * than zero and less than query_len, so a byte can be safely
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) * added or subtracted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) match_str = label_name + label_name_len + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) match_len = query_len - label_name_len - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) curr = begin_current_label_crit_section();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) label = aa_label_parse(curr, label_name, GFP_KERNEL, false, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) end_current_label_crit_section(curr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) if (IS_ERR(label))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) return PTR_ERR(label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) perms = allperms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) if (view_only) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) label_for_each_in_ns(i, labels_ns(label), label, profile) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) profile_query_cb(profile, &perms, match_str, match_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) label_for_each(i, label, profile) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) profile_query_cb(profile, &perms, match_str, match_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) aa_put_label(label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) return scnprintf(buf, buf_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) "allow 0x%08x\ndeny 0x%08x\naudit 0x%08x\nquiet 0x%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) perms.allow, perms.deny, perms.audit, perms.quiet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) * Transaction based IO.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) * The file expects a write which triggers the transaction, and then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) * possibly a read(s) which collects the result - which is stored in a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) * file-local buffer. Once a new write is performed, a new set of results
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) * are stored in the file-local buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) struct multi_transaction {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) struct kref count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) ssize_t size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) char data[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) #define MULTI_TRANSACTION_LIMIT (PAGE_SIZE - sizeof(struct multi_transaction))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) /* TODO: replace with per file lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) static DEFINE_SPINLOCK(multi_transaction_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) static void multi_transaction_kref(struct kref *kref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) struct multi_transaction *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) t = container_of(kref, struct multi_transaction, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) free_page((unsigned long) t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) static struct multi_transaction *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) get_multi_transaction(struct multi_transaction *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) if (t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) kref_get(&(t->count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) return t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) static void put_multi_transaction(struct multi_transaction *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) if (t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) kref_put(&(t->count), multi_transaction_kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) /* does not increment @new's count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) static void multi_transaction_set(struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) struct multi_transaction *new, size_t n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) struct multi_transaction *old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) AA_BUG(n > MULTI_TRANSACTION_LIMIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) new->size = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) spin_lock(&multi_transaction_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) old = (struct multi_transaction *) file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) file->private_data = new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) spin_unlock(&multi_transaction_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) put_multi_transaction(old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) static struct multi_transaction *multi_transaction_new(struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) struct multi_transaction *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) if (size > MULTI_TRANSACTION_LIMIT - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) return ERR_PTR(-EFBIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) t = (struct multi_transaction *)get_zeroed_page(GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) if (!t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) kref_init(&t->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) if (copy_from_user(t->data, buf, size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) return ERR_PTR(-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) return t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) static ssize_t multi_transaction_read(struct file *file, char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) size_t size, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) struct multi_transaction *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) spin_lock(&multi_transaction_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) t = get_multi_transaction(file->private_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) spin_unlock(&multi_transaction_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) if (!t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) ret = simple_read_from_buffer(buf, size, pos, t->data, t->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) put_multi_transaction(t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) static int multi_transaction_release(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) put_multi_transaction(file->private_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) #define QUERY_CMD_LABEL "label\0"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) #define QUERY_CMD_LABEL_LEN 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) #define QUERY_CMD_PROFILE "profile\0"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) #define QUERY_CMD_PROFILE_LEN 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) #define QUERY_CMD_LABELALL "labelall\0"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) #define QUERY_CMD_LABELALL_LEN 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) #define QUERY_CMD_DATA "data\0"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) #define QUERY_CMD_DATA_LEN 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) * aa_write_access - generic permissions and data query
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) * @file: pointer to open apparmorfs/access file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) * @ubuf: user buffer containing the complete query string (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) * @count: size of ubuf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) * @ppos: position in the file (MUST BE ZERO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) * Allows for one permissions or data query per open(), write(), and read()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) * sequence. The only queries currently supported are label-based queries for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) * permissions or data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) * For permissions queries, ubuf must begin with "label\0", followed by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) * profile query specific format described in the query_label() function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) * documentation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) * For data queries, ubuf must have the form "data\0<LABEL>\0<KEY>\0", where
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) * <LABEL> is the name of the security confinement context and <KEY> is the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) * name of the data to retrieve.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) * Returns: number of bytes written or -errno on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) static ssize_t aa_write_access(struct file *file, const char __user *ubuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) struct multi_transaction *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) ssize_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) if (*ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) return -ESPIPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) t = multi_transaction_new(file, ubuf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) if (IS_ERR(t))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) return PTR_ERR(t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) if (count > QUERY_CMD_PROFILE_LEN &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) !memcmp(t->data, QUERY_CMD_PROFILE, QUERY_CMD_PROFILE_LEN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) len = query_label(t->data, MULTI_TRANSACTION_LIMIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) t->data + QUERY_CMD_PROFILE_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) count - QUERY_CMD_PROFILE_LEN, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) } else if (count > QUERY_CMD_LABEL_LEN &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) !memcmp(t->data, QUERY_CMD_LABEL, QUERY_CMD_LABEL_LEN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) len = query_label(t->data, MULTI_TRANSACTION_LIMIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) t->data + QUERY_CMD_LABEL_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) count - QUERY_CMD_LABEL_LEN, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) } else if (count > QUERY_CMD_LABELALL_LEN &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) !memcmp(t->data, QUERY_CMD_LABELALL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) QUERY_CMD_LABELALL_LEN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) len = query_label(t->data, MULTI_TRANSACTION_LIMIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) t->data + QUERY_CMD_LABELALL_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) count - QUERY_CMD_LABELALL_LEN, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) } else if (count > QUERY_CMD_DATA_LEN &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) !memcmp(t->data, QUERY_CMD_DATA, QUERY_CMD_DATA_LEN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) len = query_data(t->data, MULTI_TRANSACTION_LIMIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) t->data + QUERY_CMD_DATA_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) count - QUERY_CMD_DATA_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) len = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) if (len < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) put_multi_transaction(t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) multi_transaction_set(file, t, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) static const struct file_operations aa_sfs_access = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) .write = aa_write_access,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) .read = multi_transaction_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) .release = multi_transaction_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) .llseek = generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) static int aa_sfs_seq_show(struct seq_file *seq, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) struct aa_sfs_entry *fs_file = seq->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) if (!fs_file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) switch (fs_file->v_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) case AA_SFS_TYPE_BOOLEAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) seq_printf(seq, "%s\n", fs_file->v.boolean ? "yes" : "no");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) case AA_SFS_TYPE_STRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) seq_printf(seq, "%s\n", fs_file->v.string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) case AA_SFS_TYPE_U64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) seq_printf(seq, "%#08lx\n", fs_file->v.u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) /* Ignore unpritable entry types. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) static int aa_sfs_seq_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) return single_open(file, aa_sfs_seq_show, inode->i_private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) const struct file_operations aa_sfs_seq_file_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) .open = aa_sfs_seq_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) .read = seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) .llseek = seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) .release = single_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) * profile based file operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) * policy/profiles/XXXX/profiles/ *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) #define SEQ_PROFILE_FOPS(NAME) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) static int seq_profile_ ##NAME ##_open(struct inode *inode, struct file *file)\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) return seq_profile_open(inode, file, seq_profile_ ##NAME ##_show); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) static const struct file_operations seq_profile_ ##NAME ##_fops = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) .owner = THIS_MODULE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) .open = seq_profile_ ##NAME ##_open, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) .read = seq_read, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) .llseek = seq_lseek, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) .release = seq_profile_release, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) static int seq_profile_open(struct inode *inode, struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) int (*show)(struct seq_file *, void *))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) struct aa_proxy *proxy = aa_get_proxy(inode->i_private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) int error = single_open(file, show, proxy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) file->private_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) aa_put_proxy(proxy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) static int seq_profile_release(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) struct seq_file *seq = (struct seq_file *) file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) if (seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) aa_put_proxy(seq->private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) return single_release(inode, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) static int seq_profile_name_show(struct seq_file *seq, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) struct aa_proxy *proxy = seq->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) struct aa_label *label = aa_get_label_rcu(&proxy->label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) struct aa_profile *profile = labels_profile(label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) seq_printf(seq, "%s\n", profile->base.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) aa_put_label(label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) static int seq_profile_mode_show(struct seq_file *seq, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) struct aa_proxy *proxy = seq->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) struct aa_label *label = aa_get_label_rcu(&proxy->label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) struct aa_profile *profile = labels_profile(label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) seq_printf(seq, "%s\n", aa_profile_mode_names[profile->mode]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) aa_put_label(label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) static int seq_profile_attach_show(struct seq_file *seq, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) struct aa_proxy *proxy = seq->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) struct aa_label *label = aa_get_label_rcu(&proxy->label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) struct aa_profile *profile = labels_profile(label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) if (profile->attach)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) seq_printf(seq, "%s\n", profile->attach);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) else if (profile->xmatch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) seq_puts(seq, "<unknown>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) seq_printf(seq, "%s\n", profile->base.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) aa_put_label(label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) static int seq_profile_hash_show(struct seq_file *seq, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) struct aa_proxy *proxy = seq->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) struct aa_label *label = aa_get_label_rcu(&proxy->label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) struct aa_profile *profile = labels_profile(label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) unsigned int i, size = aa_hash_size();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) if (profile->hash) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) for (i = 0; i < size; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) seq_printf(seq, "%.2x", profile->hash[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) seq_putc(seq, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) aa_put_label(label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) SEQ_PROFILE_FOPS(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) SEQ_PROFILE_FOPS(mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) SEQ_PROFILE_FOPS(attach);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) SEQ_PROFILE_FOPS(hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) * namespace based files
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) * several root files and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) * policy/ *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) #define SEQ_NS_FOPS(NAME) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) static int seq_ns_ ##NAME ##_open(struct inode *inode, struct file *file) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) return single_open(file, seq_ns_ ##NAME ##_show, inode->i_private); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) static const struct file_operations seq_ns_ ##NAME ##_fops = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) .owner = THIS_MODULE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) .open = seq_ns_ ##NAME ##_open, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) .read = seq_read, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) .llseek = seq_lseek, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) .release = single_release, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) static int seq_ns_stacked_show(struct seq_file *seq, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) struct aa_label *label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) label = begin_current_label_crit_section();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) seq_printf(seq, "%s\n", label->size > 1 ? "yes" : "no");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) end_current_label_crit_section(label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) static int seq_ns_nsstacked_show(struct seq_file *seq, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) struct aa_label *label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) struct aa_profile *profile;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) struct label_it it;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) int count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) label = begin_current_label_crit_section();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) if (label->size > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) label_for_each(it, label, profile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) if (profile->ns != labels_ns(label)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) seq_printf(seq, "%s\n", count > 1 ? "yes" : "no");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) end_current_label_crit_section(label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) static int seq_ns_level_show(struct seq_file *seq, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) struct aa_label *label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) label = begin_current_label_crit_section();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) seq_printf(seq, "%d\n", labels_ns(label)->level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) end_current_label_crit_section(label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) static int seq_ns_name_show(struct seq_file *seq, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) struct aa_label *label = begin_current_label_crit_section();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) seq_printf(seq, "%s\n", labels_ns(label)->base.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) end_current_label_crit_section(label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) SEQ_NS_FOPS(stacked);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) SEQ_NS_FOPS(nsstacked);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) SEQ_NS_FOPS(level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) SEQ_NS_FOPS(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) /* policy/raw_data/ * file ops */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) #define SEQ_RAWDATA_FOPS(NAME) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) static int seq_rawdata_ ##NAME ##_open(struct inode *inode, struct file *file)\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) return seq_rawdata_open(inode, file, seq_rawdata_ ##NAME ##_show); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) static const struct file_operations seq_rawdata_ ##NAME ##_fops = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) .owner = THIS_MODULE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) .open = seq_rawdata_ ##NAME ##_open, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) .read = seq_read, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) .llseek = seq_lseek, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) .release = seq_rawdata_release, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) static int seq_rawdata_open(struct inode *inode, struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) int (*show)(struct seq_file *, void *))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) struct aa_loaddata *data = __aa_get_loaddata(inode->i_private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) /* lost race this ent is being reaped */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) error = single_open(file, show, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) AA_BUG(file->private_data &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) ((struct seq_file *)file->private_data)->private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) aa_put_loaddata(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) static int seq_rawdata_release(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) struct seq_file *seq = (struct seq_file *) file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) if (seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) aa_put_loaddata(seq->private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) return single_release(inode, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) static int seq_rawdata_abi_show(struct seq_file *seq, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) struct aa_loaddata *data = seq->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) seq_printf(seq, "v%d\n", data->abi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) static int seq_rawdata_revision_show(struct seq_file *seq, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) struct aa_loaddata *data = seq->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) seq_printf(seq, "%ld\n", data->revision);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) static int seq_rawdata_hash_show(struct seq_file *seq, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) struct aa_loaddata *data = seq->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) unsigned int i, size = aa_hash_size();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) if (data->hash) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) for (i = 0; i < size; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) seq_printf(seq, "%.2x", data->hash[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) seq_putc(seq, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) static int seq_rawdata_compressed_size_show(struct seq_file *seq, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) struct aa_loaddata *data = seq->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) seq_printf(seq, "%zu\n", data->compressed_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) SEQ_RAWDATA_FOPS(abi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) SEQ_RAWDATA_FOPS(revision);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) SEQ_RAWDATA_FOPS(hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) SEQ_RAWDATA_FOPS(compressed_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) static int deflate_decompress(char *src, size_t slen, char *dst, size_t dlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) struct z_stream_s strm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) if (aa_g_rawdata_compression_level == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) if (dlen < slen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) memcpy(dst, src, slen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) memset(&strm, 0, sizeof(strm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) strm.workspace = kvzalloc(zlib_inflate_workspacesize(), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) if (!strm.workspace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) strm.next_in = src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) strm.avail_in = slen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) error = zlib_inflateInit(&strm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) if (error != Z_OK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) goto fail_inflate_init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) strm.next_out = dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) strm.avail_out = dlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) error = zlib_inflate(&strm, Z_FINISH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) if (error != Z_STREAM_END)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) zlib_inflateEnd(&strm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) fail_inflate_init:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) kvfree(strm.workspace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) static ssize_t rawdata_read(struct file *file, char __user *buf, size_t size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) struct rawdata_f_data *private = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) return simple_read_from_buffer(buf, size, ppos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) RAWDATA_F_DATA_BUF(private),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) private->loaddata->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) static int rawdata_release(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) rawdata_f_data_free(file->private_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) static int rawdata_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) struct aa_loaddata *loaddata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) struct rawdata_f_data *private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) if (!policy_view_capable(NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) loaddata = __aa_get_loaddata(inode->i_private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) if (!loaddata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) /* lost race: this entry is being reaped */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) private = rawdata_f_data_alloc(loaddata->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) if (IS_ERR(private)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) error = PTR_ERR(private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) goto fail_private_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) private->loaddata = loaddata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) error = deflate_decompress(loaddata->data, loaddata->compressed_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) RAWDATA_F_DATA_BUF(private),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) loaddata->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) goto fail_decompress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) file->private_data = private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) fail_decompress:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) rawdata_f_data_free(private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) fail_private_alloc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) aa_put_loaddata(loaddata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) static const struct file_operations rawdata_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) .open = rawdata_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) .read = rawdata_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) .llseek = generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) .release = rawdata_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) static void remove_rawdata_dents(struct aa_loaddata *rawdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) for (i = 0; i < AAFS_LOADDATA_NDENTS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) if (!IS_ERR_OR_NULL(rawdata->dents[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) /* no refcounts on i_private */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) aafs_remove(rawdata->dents[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) rawdata->dents[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) void __aa_fs_remove_rawdata(struct aa_loaddata *rawdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) AA_BUG(rawdata->ns && !mutex_is_locked(&rawdata->ns->lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) if (rawdata->ns) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) remove_rawdata_dents(rawdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) list_del_init(&rawdata->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) aa_put_ns(rawdata->ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) rawdata->ns = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) int __aa_fs_create_rawdata(struct aa_ns *ns, struct aa_loaddata *rawdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) struct dentry *dent, *dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) AA_BUG(!ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) AA_BUG(!rawdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) AA_BUG(!mutex_is_locked(&ns->lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) AA_BUG(!ns_subdata_dir(ns));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) * just use ns revision dir was originally created at. This is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) * under ns->lock and if load is successful revision will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) * bumped and is guaranteed to be unique
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) rawdata->name = kasprintf(GFP_KERNEL, "%ld", ns->revision);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) if (!rawdata->name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) dir = aafs_create_dir(rawdata->name, ns_subdata_dir(ns));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) if (IS_ERR(dir))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) /* ->name freed when rawdata freed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) return PTR_ERR(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) rawdata->dents[AAFS_LOADDATA_DIR] = dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) dent = aafs_create_file("abi", S_IFREG | 0444, dir, rawdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) &seq_rawdata_abi_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) if (IS_ERR(dent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) rawdata->dents[AAFS_LOADDATA_ABI] = dent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) dent = aafs_create_file("revision", S_IFREG | 0444, dir, rawdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) &seq_rawdata_revision_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) if (IS_ERR(dent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) rawdata->dents[AAFS_LOADDATA_REVISION] = dent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) if (aa_g_hash_policy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) dent = aafs_create_file("sha1", S_IFREG | 0444, dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) rawdata, &seq_rawdata_hash_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) if (IS_ERR(dent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) rawdata->dents[AAFS_LOADDATA_HASH] = dent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) dent = aafs_create_file("compressed_size", S_IFREG | 0444, dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) rawdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) &seq_rawdata_compressed_size_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) if (IS_ERR(dent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) rawdata->dents[AAFS_LOADDATA_COMPRESSED_SIZE] = dent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) dent = aafs_create_file("raw_data", S_IFREG | 0444,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) dir, rawdata, &rawdata_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) if (IS_ERR(dent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) rawdata->dents[AAFS_LOADDATA_DATA] = dent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) d_inode(dent)->i_size = rawdata->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) rawdata->ns = aa_get_ns(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) list_add(&rawdata->list, &ns->rawdata_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) /* no refcount on inode rawdata */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) remove_rawdata_dents(rawdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) return PTR_ERR(dent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) /** fns to setup dynamic per profile/namespace files **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) * Requires: @profile->ns->lock held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) void __aafs_profile_rmdir(struct aa_profile *profile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) struct aa_profile *child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) if (!profile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) list_for_each_entry(child, &profile->base.profiles, base.list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) __aafs_profile_rmdir(child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) for (i = AAFS_PROF_SIZEOF - 1; i >= 0; --i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) struct aa_proxy *proxy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) if (!profile->dents[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) proxy = d_inode(profile->dents[i])->i_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) aafs_remove(profile->dents[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) aa_put_proxy(proxy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) profile->dents[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) * Requires: @old->ns->lock held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) void __aafs_profile_migrate_dents(struct aa_profile *old,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) struct aa_profile *new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) AA_BUG(!old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) AA_BUG(!new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) AA_BUG(!mutex_is_locked(&profiles_ns(old)->lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) for (i = 0; i < AAFS_PROF_SIZEOF; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) new->dents[i] = old->dents[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) if (new->dents[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) new->dents[i]->d_inode->i_mtime = current_time(new->dents[i]->d_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) old->dents[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) static struct dentry *create_profile_file(struct dentry *dir, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) struct aa_profile *profile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) const struct file_operations *fops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) struct aa_proxy *proxy = aa_get_proxy(profile->label.proxy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) struct dentry *dent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) dent = aafs_create_file(name, S_IFREG | 0444, dir, proxy, fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) if (IS_ERR(dent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) aa_put_proxy(proxy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) return dent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) static int profile_depth(struct aa_profile *profile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) int depth = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) for (depth = 0; profile; profile = rcu_access_pointer(profile->parent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) depth++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) return depth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) static char *gen_symlink_name(int depth, const char *dirname, const char *fname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) char *buffer, *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) int size = depth * 6 + strlen(dirname) + strlen(fname) + 11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) s = buffer = kmalloc(size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) if (!buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) for (; depth > 0; depth--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) strcpy(s, "../../");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) s += 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) size -= 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) error = snprintf(s, size, "raw_data/%s/%s", dirname, fname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) if (error >= size || error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) kfree(buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) return ERR_PTR(-ENAMETOOLONG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) return buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) static void rawdata_link_cb(void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) kfree(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) static const char *rawdata_get_link_base(struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) struct delayed_call *done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) struct aa_proxy *proxy = inode->i_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) struct aa_label *label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) struct aa_profile *profile;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) char *target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) int depth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) if (!dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) return ERR_PTR(-ECHILD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) label = aa_get_label_rcu(&proxy->label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) profile = labels_profile(label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) depth = profile_depth(profile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) target = gen_symlink_name(depth, profile->rawdata->name, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) aa_put_label(label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) if (IS_ERR(target))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) return target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) set_delayed_call(done, rawdata_link_cb, target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) return target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) static const char *rawdata_get_link_sha1(struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) struct delayed_call *done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) return rawdata_get_link_base(dentry, inode, done, "sha1");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) static const char *rawdata_get_link_abi(struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) struct delayed_call *done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) return rawdata_get_link_base(dentry, inode, done, "abi");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) static const char *rawdata_get_link_data(struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) struct delayed_call *done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) return rawdata_get_link_base(dentry, inode, done, "raw_data");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) static const struct inode_operations rawdata_link_sha1_iops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) .get_link = rawdata_get_link_sha1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) static const struct inode_operations rawdata_link_abi_iops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) .get_link = rawdata_get_link_abi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) static const struct inode_operations rawdata_link_data_iops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) .get_link = rawdata_get_link_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) * Requires: @profile->ns->lock held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) int __aafs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) struct aa_profile *child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) struct dentry *dent = NULL, *dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) AA_BUG(!profile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) AA_BUG(!mutex_is_locked(&profiles_ns(profile)->lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) if (!parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) struct aa_profile *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) p = aa_deref_parent(profile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) dent = prof_dir(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) /* adding to parent that previously didn't have children */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) dent = aafs_create_dir("profiles", dent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) if (IS_ERR(dent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) prof_child_dir(p) = parent = dent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) if (!profile->dirname) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) int len, id_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) len = mangle_name(profile->base.name, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) id_len = snprintf(NULL, 0, ".%ld", profile->ns->uniq_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) profile->dirname = kmalloc(len + id_len + 1, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) if (!profile->dirname) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) goto fail2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) mangle_name(profile->base.name, profile->dirname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) sprintf(profile->dirname + len, ".%ld", profile->ns->uniq_id++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) dent = aafs_create_dir(profile->dirname, parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) if (IS_ERR(dent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) prof_dir(profile) = dir = dent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) dent = create_profile_file(dir, "name", profile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) &seq_profile_name_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) if (IS_ERR(dent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) profile->dents[AAFS_PROF_NAME] = dent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) dent = create_profile_file(dir, "mode", profile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) &seq_profile_mode_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) if (IS_ERR(dent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) profile->dents[AAFS_PROF_MODE] = dent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) dent = create_profile_file(dir, "attach", profile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) &seq_profile_attach_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) if (IS_ERR(dent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) profile->dents[AAFS_PROF_ATTACH] = dent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) if (profile->hash) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) dent = create_profile_file(dir, "sha1", profile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) &seq_profile_hash_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) if (IS_ERR(dent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) profile->dents[AAFS_PROF_HASH] = dent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) if (profile->rawdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) dent = aafs_create("raw_sha1", S_IFLNK | 0444, dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) profile->label.proxy, NULL, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) &rawdata_link_sha1_iops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) if (IS_ERR(dent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) aa_get_proxy(profile->label.proxy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) profile->dents[AAFS_PROF_RAW_HASH] = dent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) dent = aafs_create("raw_abi", S_IFLNK | 0444, dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) profile->label.proxy, NULL, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) &rawdata_link_abi_iops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) if (IS_ERR(dent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) aa_get_proxy(profile->label.proxy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) profile->dents[AAFS_PROF_RAW_ABI] = dent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) dent = aafs_create("raw_data", S_IFLNK | 0444, dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) profile->label.proxy, NULL, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) &rawdata_link_data_iops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) if (IS_ERR(dent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) aa_get_proxy(profile->label.proxy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) profile->dents[AAFS_PROF_RAW_DATA] = dent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) list_for_each_entry(child, &profile->base.profiles, base.list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) error = __aafs_profile_mkdir(child, prof_child_dir(profile));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) goto fail2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) error = PTR_ERR(dent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) fail2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) __aafs_profile_rmdir(profile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) static int ns_mkdir_op(struct inode *dir, struct dentry *dentry, umode_t mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) struct aa_ns *ns, *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) /* TODO: improve permission check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) struct aa_label *label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) label = begin_current_label_crit_section();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) error = aa_may_manage_policy(label, NULL, AA_MAY_LOAD_POLICY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) end_current_label_crit_section(label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) parent = aa_get_ns(dir->i_private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) AA_BUG(d_inode(ns_subns_dir(parent)) != dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) /* we have to unlock and then relock to get locking order right
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) * for pin_fs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) inode_unlock(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) error = simple_pin_fs(&aafs_ops, &aafs_mnt, &aafs_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) mutex_lock_nested(&parent->lock, parent->level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) inode_lock_nested(dir, I_MUTEX_PARENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) error = __aafs_setup_d_inode(dir, dentry, mode | S_IFDIR, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) NULL, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) goto out_pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) ns = __aa_find_or_create_ns(parent, READ_ONCE(dentry->d_name.name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) if (IS_ERR(ns)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) error = PTR_ERR(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) ns = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) aa_put_ns(ns); /* list ref remains */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) out_pin:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) simple_release_fs(&aafs_mnt, &aafs_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) mutex_unlock(&parent->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) aa_put_ns(parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) static int ns_rmdir_op(struct inode *dir, struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) struct aa_ns *ns, *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) /* TODO: improve permission check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) struct aa_label *label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) label = begin_current_label_crit_section();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) error = aa_may_manage_policy(label, NULL, AA_MAY_LOAD_POLICY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) end_current_label_crit_section(label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) parent = aa_get_ns(dir->i_private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) /* rmdir calls the generic securityfs functions to remove files
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) * from the apparmor dir. It is up to the apparmor ns locking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) * to avoid races.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) inode_unlock(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) inode_unlock(dentry->d_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) mutex_lock_nested(&parent->lock, parent->level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) ns = aa_get_ns(__aa_findn_ns(&parent->sub_ns, dentry->d_name.name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) dentry->d_name.len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) if (!ns) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) error = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) AA_BUG(ns_dir(ns) != dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) __aa_remove_ns(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) aa_put_ns(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) mutex_unlock(&parent->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) inode_lock_nested(dir, I_MUTEX_PARENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) inode_lock(dentry->d_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) aa_put_ns(parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) static const struct inode_operations ns_dir_inode_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) .lookup = simple_lookup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) .mkdir = ns_mkdir_op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) .rmdir = ns_rmdir_op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) static void __aa_fs_list_remove_rawdata(struct aa_ns *ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) struct aa_loaddata *ent, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) AA_BUG(!mutex_is_locked(&ns->lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) list_for_each_entry_safe(ent, tmp, &ns->rawdata_list, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) __aa_fs_remove_rawdata(ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) * Requires: @ns->lock held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) void __aafs_ns_rmdir(struct aa_ns *ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) struct aa_ns *sub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) struct aa_profile *child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) if (!ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) AA_BUG(!mutex_is_locked(&ns->lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) list_for_each_entry(child, &ns->base.profiles, base.list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) __aafs_profile_rmdir(child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) list_for_each_entry(sub, &ns->sub_ns, base.list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) mutex_lock_nested(&sub->lock, sub->level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) __aafs_ns_rmdir(sub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) mutex_unlock(&sub->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) __aa_fs_list_remove_rawdata(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) if (ns_subns_dir(ns)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) sub = d_inode(ns_subns_dir(ns))->i_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) aa_put_ns(sub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) if (ns_subload(ns)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) sub = d_inode(ns_subload(ns))->i_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) aa_put_ns(sub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) if (ns_subreplace(ns)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) sub = d_inode(ns_subreplace(ns))->i_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) aa_put_ns(sub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) if (ns_subremove(ns)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) sub = d_inode(ns_subremove(ns))->i_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) aa_put_ns(sub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) if (ns_subrevision(ns)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) sub = d_inode(ns_subrevision(ns))->i_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) aa_put_ns(sub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) for (i = AAFS_NS_SIZEOF - 1; i >= 0; --i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) aafs_remove(ns->dents[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) ns->dents[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) /* assumes cleanup in caller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) static int __aafs_ns_mkdir_entries(struct aa_ns *ns, struct dentry *dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) struct dentry *dent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) AA_BUG(!ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) AA_BUG(!dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) dent = aafs_create_dir("profiles", dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) if (IS_ERR(dent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) return PTR_ERR(dent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) ns_subprofs_dir(ns) = dent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) dent = aafs_create_dir("raw_data", dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) if (IS_ERR(dent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) return PTR_ERR(dent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) ns_subdata_dir(ns) = dent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) dent = aafs_create_file("revision", 0444, dir, ns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) &aa_fs_ns_revision_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) if (IS_ERR(dent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) return PTR_ERR(dent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) aa_get_ns(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) ns_subrevision(ns) = dent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) dent = aafs_create_file(".load", 0640, dir, ns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) &aa_fs_profile_load);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) if (IS_ERR(dent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) return PTR_ERR(dent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) aa_get_ns(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) ns_subload(ns) = dent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) dent = aafs_create_file(".replace", 0640, dir, ns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) &aa_fs_profile_replace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) if (IS_ERR(dent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) return PTR_ERR(dent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) aa_get_ns(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) ns_subreplace(ns) = dent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) dent = aafs_create_file(".remove", 0640, dir, ns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) &aa_fs_profile_remove);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) if (IS_ERR(dent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) return PTR_ERR(dent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) aa_get_ns(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) ns_subremove(ns) = dent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) /* use create_dentry so we can supply private data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) dent = aafs_create("namespaces", S_IFDIR | 0755, dir, ns, NULL, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) &ns_dir_inode_operations);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) if (IS_ERR(dent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) return PTR_ERR(dent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) aa_get_ns(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) ns_subns_dir(ns) = dent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) * Requires: @ns->lock held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) int __aafs_ns_mkdir(struct aa_ns *ns, struct dentry *parent, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) struct dentry *dent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) struct aa_ns *sub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) struct aa_profile *child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) struct dentry *dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) AA_BUG(!ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) AA_BUG(!parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) AA_BUG(!mutex_is_locked(&ns->lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) if (!name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) name = ns->base.name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) if (!dent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) /* create ns dir if it doesn't already exist */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) dent = aafs_create_dir(name, parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) if (IS_ERR(dent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) dget(dent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) ns_dir(ns) = dir = dent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) error = __aafs_ns_mkdir_entries(ns, dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) goto fail2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) /* profiles */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) list_for_each_entry(child, &ns->base.profiles, base.list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) error = __aafs_profile_mkdir(child, ns_subprofs_dir(ns));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) goto fail2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) /* subnamespaces */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) list_for_each_entry(sub, &ns->sub_ns, base.list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) mutex_lock_nested(&sub->lock, sub->level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) error = __aafs_ns_mkdir(sub, ns_subns_dir(ns), NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) mutex_unlock(&sub->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) goto fail2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) error = PTR_ERR(dent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) fail2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) __aafs_ns_rmdir(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) #define list_entry_is_head(pos, head, member) (&pos->member == (head))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) * __next_ns - find the next namespace to list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) * @root: root namespace to stop search at (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) * @ns: current ns position (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) * Find the next namespace from @ns under @root and handle all locking needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) * while switching current namespace.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) * Returns: next namespace or NULL if at last namespace under @root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) * Requires: ns->parent->lock to be held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) * NOTE: will not unlock root->lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) static struct aa_ns *__next_ns(struct aa_ns *root, struct aa_ns *ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) struct aa_ns *parent, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) AA_BUG(!root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) AA_BUG(!ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) AA_BUG(ns != root && !mutex_is_locked(&ns->parent->lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) /* is next namespace a child */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) if (!list_empty(&ns->sub_ns)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) next = list_first_entry(&ns->sub_ns, typeof(*ns), base.list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) mutex_lock_nested(&next->lock, next->level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) return next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) /* check if the next ns is a sibling, parent, gp, .. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) parent = ns->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) while (ns != root) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) mutex_unlock(&ns->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) next = list_next_entry(ns, base.list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) if (!list_entry_is_head(next, &parent->sub_ns, base.list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) mutex_lock_nested(&next->lock, next->level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) return next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) ns = parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) parent = parent->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) * __first_profile - find the first profile in a namespace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) * @root: namespace that is root of profiles being displayed (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) * @ns: namespace to start in (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) * Returns: unrefcounted profile or NULL if no profile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) * Requires: profile->ns.lock to be held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) static struct aa_profile *__first_profile(struct aa_ns *root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) struct aa_ns *ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) AA_BUG(!root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) AA_BUG(ns && !mutex_is_locked(&ns->lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) for (; ns; ns = __next_ns(root, ns)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) if (!list_empty(&ns->base.profiles))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) return list_first_entry(&ns->base.profiles,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) struct aa_profile, base.list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) * __next_profile - step to the next profile in a profile tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) * @profile: current profile in tree (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) * Perform a depth first traversal on the profile tree in a namespace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) * Returns: next profile or NULL if done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) * Requires: profile->ns.lock to be held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) static struct aa_profile *__next_profile(struct aa_profile *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) struct aa_profile *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) struct aa_ns *ns = p->ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) AA_BUG(!mutex_is_locked(&profiles_ns(p)->lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) /* is next profile a child */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) if (!list_empty(&p->base.profiles))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) return list_first_entry(&p->base.profiles, typeof(*p),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) base.list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) /* is next profile a sibling, parent sibling, gp, sibling, .. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) parent = rcu_dereference_protected(p->parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) mutex_is_locked(&p->ns->lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) while (parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) p = list_next_entry(p, base.list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) if (!list_entry_is_head(p, &parent->base.profiles, base.list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) p = parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) parent = rcu_dereference_protected(parent->parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) mutex_is_locked(&parent->ns->lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) /* is next another profile in the namespace */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) p = list_next_entry(p, base.list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) if (!list_entry_is_head(p, &ns->base.profiles, base.list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) * next_profile - step to the next profile in where ever it may be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) * @root: root namespace (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) * @profile: current profile (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) * Returns: next profile or NULL if there isn't one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) static struct aa_profile *next_profile(struct aa_ns *root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) struct aa_profile *profile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) struct aa_profile *next = __next_profile(profile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) if (next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) return next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) /* finished all profiles in namespace move to next namespace */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) return __first_profile(root, __next_ns(root, profile->ns));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) * p_start - start a depth first traversal of profile tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) * @f: seq_file to fill
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) * @pos: current position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) * Returns: first profile under current namespace or NULL if none found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) * acquires first ns->lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) static void *p_start(struct seq_file *f, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) struct aa_profile *profile = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) struct aa_ns *root = aa_get_current_ns();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) loff_t l = *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) f->private = root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) /* find the first profile */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) mutex_lock_nested(&root->lock, root->level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) profile = __first_profile(root, root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) /* skip to position */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) for (; profile && l > 0; l--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) profile = next_profile(root, profile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) return profile;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) * p_next - read the next profile entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) * @f: seq_file to fill
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) * @p: profile previously returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) * @pos: current position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) * Returns: next profile after @p or NULL if none
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) * may acquire/release locks in namespace tree as necessary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) static void *p_next(struct seq_file *f, void *p, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) struct aa_profile *profile = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) struct aa_ns *ns = f->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) (*pos)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) return next_profile(ns, profile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) * p_stop - stop depth first traversal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) * @f: seq_file we are filling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) * @p: the last profile writen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) * Release all locking done by p_start/p_next on namespace tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) static void p_stop(struct seq_file *f, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) struct aa_profile *profile = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) struct aa_ns *root = f->private, *ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) if (profile) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) for (ns = profile->ns; ns && ns != root; ns = ns->parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) mutex_unlock(&ns->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) mutex_unlock(&root->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) aa_put_ns(root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) * seq_show_profile - show a profile entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) * @f: seq_file to file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) * @p: current position (profile) (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) * Returns: error on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) static int seq_show_profile(struct seq_file *f, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) struct aa_profile *profile = (struct aa_profile *)p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) struct aa_ns *root = f->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) aa_label_seq_xprint(f, root, &profile->label,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) FLAG_SHOW_MODE | FLAG_VIEW_SUBNS, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) seq_putc(f, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) static const struct seq_operations aa_sfs_profiles_op = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) .start = p_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) .next = p_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) .stop = p_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) .show = seq_show_profile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) static int profiles_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) if (!policy_view_capable(NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) return seq_open(file, &aa_sfs_profiles_op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) static int profiles_release(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) return seq_release(inode, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) static const struct file_operations aa_sfs_profiles_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) .open = profiles_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) .read = seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) .llseek = seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) .release = profiles_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) /** Base file system setup **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) static struct aa_sfs_entry aa_sfs_entry_file[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) AA_SFS_FILE_STRING("mask",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) "create read write exec append mmap_exec link lock"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) static struct aa_sfs_entry aa_sfs_entry_ptrace[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) AA_SFS_FILE_STRING("mask", "read trace"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) static struct aa_sfs_entry aa_sfs_entry_signal[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) AA_SFS_FILE_STRING("mask", AA_SFS_SIG_MASK),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) static struct aa_sfs_entry aa_sfs_entry_attach[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) AA_SFS_FILE_BOOLEAN("xattr", 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) static struct aa_sfs_entry aa_sfs_entry_domain[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) AA_SFS_FILE_BOOLEAN("change_hat", 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) AA_SFS_FILE_BOOLEAN("change_hatv", 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) AA_SFS_FILE_BOOLEAN("change_onexec", 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) AA_SFS_FILE_BOOLEAN("change_profile", 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) AA_SFS_FILE_BOOLEAN("stack", 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) AA_SFS_FILE_BOOLEAN("fix_binfmt_elf_mmap", 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) AA_SFS_FILE_BOOLEAN("post_nnp_subset", 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) AA_SFS_FILE_BOOLEAN("computed_longest_left", 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) AA_SFS_DIR("attach_conditions", aa_sfs_entry_attach),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) AA_SFS_FILE_STRING("version", "1.2"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) static struct aa_sfs_entry aa_sfs_entry_versions[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) AA_SFS_FILE_BOOLEAN("v5", 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) AA_SFS_FILE_BOOLEAN("v6", 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) AA_SFS_FILE_BOOLEAN("v7", 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) AA_SFS_FILE_BOOLEAN("v8", 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) static struct aa_sfs_entry aa_sfs_entry_policy[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) AA_SFS_DIR("versions", aa_sfs_entry_versions),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) AA_SFS_FILE_BOOLEAN("set_load", 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) /* number of out of band transitions supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) AA_SFS_FILE_U64("outofband", MAX_OOB_SUPPORTED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) static struct aa_sfs_entry aa_sfs_entry_mount[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) AA_SFS_FILE_STRING("mask", "mount umount pivot_root"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) static struct aa_sfs_entry aa_sfs_entry_ns[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) AA_SFS_FILE_BOOLEAN("profile", 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) AA_SFS_FILE_BOOLEAN("pivot_root", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) static struct aa_sfs_entry aa_sfs_entry_query_label[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) AA_SFS_FILE_STRING("perms", "allow deny audit quiet"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) AA_SFS_FILE_BOOLEAN("data", 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) AA_SFS_FILE_BOOLEAN("multi_transaction", 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) static struct aa_sfs_entry aa_sfs_entry_query[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) AA_SFS_DIR("label", aa_sfs_entry_query_label),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) static struct aa_sfs_entry aa_sfs_entry_features[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) AA_SFS_DIR("policy", aa_sfs_entry_policy),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) AA_SFS_DIR("domain", aa_sfs_entry_domain),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) AA_SFS_DIR("file", aa_sfs_entry_file),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) AA_SFS_DIR("network_v8", aa_sfs_entry_network),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) AA_SFS_DIR("mount", aa_sfs_entry_mount),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) AA_SFS_DIR("namespaces", aa_sfs_entry_ns),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) AA_SFS_FILE_U64("capability", VFS_CAP_FLAGS_MASK),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) AA_SFS_DIR("rlimit", aa_sfs_entry_rlimit),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) AA_SFS_DIR("caps", aa_sfs_entry_caps),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) AA_SFS_DIR("ptrace", aa_sfs_entry_ptrace),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) AA_SFS_DIR("signal", aa_sfs_entry_signal),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) AA_SFS_DIR("query", aa_sfs_entry_query),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) static struct aa_sfs_entry aa_sfs_entry_apparmor[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) AA_SFS_FILE_FOPS(".access", 0666, &aa_sfs_access),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) AA_SFS_FILE_FOPS(".stacked", 0444, &seq_ns_stacked_fops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) AA_SFS_FILE_FOPS(".ns_stacked", 0444, &seq_ns_nsstacked_fops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) AA_SFS_FILE_FOPS(".ns_level", 0444, &seq_ns_level_fops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) AA_SFS_FILE_FOPS(".ns_name", 0444, &seq_ns_name_fops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) AA_SFS_FILE_FOPS("profiles", 0444, &aa_sfs_profiles_fops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) AA_SFS_DIR("features", aa_sfs_entry_features),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) static struct aa_sfs_entry aa_sfs_entry =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) AA_SFS_DIR("apparmor", aa_sfs_entry_apparmor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) * entry_create_file - create a file entry in the apparmor securityfs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) * @fs_file: aa_sfs_entry to build an entry for (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) * @parent: the parent dentry in the securityfs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) * Use entry_remove_file to remove entries created with this fn.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) static int __init entry_create_file(struct aa_sfs_entry *fs_file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) struct dentry *parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) int error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) fs_file->dentry = securityfs_create_file(fs_file->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) S_IFREG | fs_file->mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) parent, fs_file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) fs_file->file_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) if (IS_ERR(fs_file->dentry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) error = PTR_ERR(fs_file->dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) fs_file->dentry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) static void __init entry_remove_dir(struct aa_sfs_entry *fs_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) * entry_create_dir - recursively create a directory entry in the securityfs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) * @fs_dir: aa_sfs_entry (and all child entries) to build (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) * @parent: the parent dentry in the securityfs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) * Use entry_remove_dir to remove entries created with this fn.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) static int __init entry_create_dir(struct aa_sfs_entry *fs_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) struct dentry *parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) struct aa_sfs_entry *fs_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) struct dentry *dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) dir = securityfs_create_dir(fs_dir->name, parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) if (IS_ERR(dir))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) return PTR_ERR(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) fs_dir->dentry = dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) for (fs_file = fs_dir->v.files; fs_file && fs_file->name; ++fs_file) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) if (fs_file->v_type == AA_SFS_TYPE_DIR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) error = entry_create_dir(fs_file, fs_dir->dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) error = entry_create_file(fs_file, fs_dir->dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) entry_remove_dir(fs_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) * entry_remove_file - drop a single file entry in the apparmor securityfs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) * @fs_file: aa_sfs_entry to detach from the securityfs (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) static void __init entry_remove_file(struct aa_sfs_entry *fs_file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) if (!fs_file->dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) securityfs_remove(fs_file->dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) fs_file->dentry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) * entry_remove_dir - recursively drop a directory entry from the securityfs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) * @fs_dir: aa_sfs_entry (and all child entries) to detach (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) static void __init entry_remove_dir(struct aa_sfs_entry *fs_dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) struct aa_sfs_entry *fs_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) for (fs_file = fs_dir->v.files; fs_file && fs_file->name; ++fs_file) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) if (fs_file->v_type == AA_SFS_TYPE_DIR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) entry_remove_dir(fs_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) entry_remove_file(fs_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) entry_remove_file(fs_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) * aa_destroy_aafs - cleanup and free aafs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) * releases dentries allocated by aa_create_aafs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) void __init aa_destroy_aafs(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) entry_remove_dir(&aa_sfs_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) #define NULL_FILE_NAME ".null"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) struct path aa_null;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) static int aa_mk_null_file(struct dentry *parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) struct vfsmount *mount = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) struct dentry *dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) int count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) int error = simple_pin_fs(parent->d_sb->s_type, &mount, &count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) inode_lock(d_inode(parent));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) dentry = lookup_one_len(NULL_FILE_NAME, parent, strlen(NULL_FILE_NAME));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) if (IS_ERR(dentry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) error = PTR_ERR(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) inode = new_inode(parent->d_inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) if (!inode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) goto out1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) inode->i_ino = get_next_ino();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) inode->i_mode = S_IFCHR | S_IRUGO | S_IWUGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) init_special_inode(inode, S_IFCHR | S_IRUGO | S_IWUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) MKDEV(MEM_MAJOR, 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) d_instantiate(dentry, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) aa_null.dentry = dget(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) aa_null.mnt = mntget(mount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) out1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) dput(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) inode_unlock(d_inode(parent));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) simple_release_fs(&mount, &count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) static const char *policy_get_link(struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) struct delayed_call *done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) struct aa_ns *ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) struct path path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) if (!dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) return ERR_PTR(-ECHILD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) ns = aa_get_current_ns();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) path.mnt = mntget(aafs_mnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) path.dentry = dget(ns_dir(ns));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) error = nd_jump_link(&path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) aa_put_ns(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) return ERR_PTR(error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) static int policy_readlink(struct dentry *dentry, char __user *buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) int buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) char name[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) res = snprintf(name, sizeof(name), "%s:[%lu]", AAFS_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) d_inode(dentry)->i_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) if (res > 0 && res < sizeof(name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) res = readlink_copy(buffer, buflen, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) res = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) static const struct inode_operations policy_link_iops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) .readlink = policy_readlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) .get_link = policy_get_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) * aa_create_aafs - create the apparmor security filesystem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) * dentries created here are released by aa_destroy_aafs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) * Returns: error on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) static int __init aa_create_aafs(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) struct dentry *dent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) if (!apparmor_initialized)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) if (aa_sfs_entry.dentry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) AA_ERROR("%s: AppArmor securityfs already exists\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) return -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) /* setup apparmorfs used to virtualize policy/ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) aafs_mnt = kern_mount(&aafs_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) if (IS_ERR(aafs_mnt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) panic("can't set apparmorfs up\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) aafs_mnt->mnt_sb->s_flags &= ~SB_NOUSER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) /* Populate fs tree. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) error = entry_create_dir(&aa_sfs_entry, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) dent = securityfs_create_file(".load", 0666, aa_sfs_entry.dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) NULL, &aa_fs_profile_load);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) if (IS_ERR(dent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) goto dent_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) ns_subload(root_ns) = dent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) dent = securityfs_create_file(".replace", 0666, aa_sfs_entry.dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) NULL, &aa_fs_profile_replace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) if (IS_ERR(dent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) goto dent_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) ns_subreplace(root_ns) = dent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) dent = securityfs_create_file(".remove", 0666, aa_sfs_entry.dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) NULL, &aa_fs_profile_remove);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) if (IS_ERR(dent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) goto dent_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) ns_subremove(root_ns) = dent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) dent = securityfs_create_file("revision", 0444, aa_sfs_entry.dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) NULL, &aa_fs_ns_revision_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) if (IS_ERR(dent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) goto dent_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) ns_subrevision(root_ns) = dent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) /* policy tree referenced by magic policy symlink */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) mutex_lock_nested(&root_ns->lock, root_ns->level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) error = __aafs_ns_mkdir(root_ns, aafs_mnt->mnt_root, ".policy",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) aafs_mnt->mnt_root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) mutex_unlock(&root_ns->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) /* magic symlink similar to nsfs redirects based on task policy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) dent = securityfs_create_symlink("policy", aa_sfs_entry.dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) NULL, &policy_link_iops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) if (IS_ERR(dent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) goto dent_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) error = aa_mk_null_file(aa_sfs_entry.dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) /* TODO: add default profile to apparmorfs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) /* Report that AppArmor fs is enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) aa_info_message("AppArmor Filesystem Enabled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) dent_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) error = PTR_ERR(dent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) aa_destroy_aafs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) AA_ERROR("Error creating AppArmor securityfs\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) fs_initcall(aa_create_aafs);