Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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);