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)  * Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * Authors:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * 	Casey Schaufler <casey@schaufler-ca.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  * 	Ahmed S. Darwish <darwish.07@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  * Special thanks to the authors of selinuxfs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  *	Karl MacMillan <kmacmillan@tresys.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  *	James Morris <jmorris@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <linux/security.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <net/net_namespace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <net/cipso_ipv4.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include <linux/audit.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include <linux/magic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include <linux/fs_context.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #include "smack.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #define BEBITS	(sizeof(__be32) * 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31)  * smackfs pseudo filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) enum smk_inos {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) 	SMK_ROOT_INO	= 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) 	SMK_LOAD	= 3,	/* load policy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) 	SMK_CIPSO	= 4,	/* load label -> CIPSO mapping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) 	SMK_DOI		= 5,	/* CIPSO DOI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) 	SMK_DIRECT	= 6,	/* CIPSO level indicating direct label */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 	SMK_AMBIENT	= 7,	/* internet ambient label */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) 	SMK_NET4ADDR	= 8,	/* single label hosts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) 	SMK_ONLYCAP	= 9,	/* the only "capable" label */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 	SMK_LOGGING	= 10,	/* logging */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 	SMK_LOAD_SELF	= 11,	/* task specific rules */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 	SMK_ACCESSES	= 12,	/* access policy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 	SMK_MAPPED	= 13,	/* CIPSO level indicating mapped label */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) 	SMK_LOAD2	= 14,	/* load policy with long labels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) 	SMK_LOAD_SELF2	= 15,	/* load task specific rules with long labels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 	SMK_ACCESS2	= 16,	/* make an access check with long labels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 	SMK_CIPSO2	= 17,	/* load long label -> CIPSO mapping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 	SMK_REVOKE_SUBJ	= 18,	/* set rules with subject label to '-' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 	SMK_CHANGE_RULE	= 19,	/* change or add rules (long labels) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 	SMK_SYSLOG	= 20,	/* change syslog label) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 	SMK_PTRACE	= 21,	/* set ptrace rule */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) #ifdef CONFIG_SECURITY_SMACK_BRINGUP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 	SMK_UNCONFINED	= 22,	/* define an unconfined label */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 	SMK_NET6ADDR	= 23,	/* single label IPv6 hosts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) #endif /* CONFIG_IPV6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 	SMK_RELABEL_SELF = 24, /* relabel possible without CAP_MAC_ADMIN */
^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)  * List locks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) static DEFINE_MUTEX(smack_cipso_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) static DEFINE_MUTEX(smack_ambient_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) static DEFINE_MUTEX(smk_net4addr_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) static DEFINE_MUTEX(smk_net6addr_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) #endif /* CONFIG_IPV6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75)  * This is the "ambient" label for network traffic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76)  * If it isn't somehow marked, use this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77)  * It can be reset via smackfs/ambient
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) struct smack_known *smack_net_ambient;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82)  * This is the level in a CIPSO header that indicates a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83)  * smack label is contained directly in the category set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84)  * It can be reset via smackfs/direct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) int smack_cipso_direct = SMACK_CIPSO_DIRECT_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89)  * This is the level in a CIPSO header that indicates a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90)  * secid is contained directly in the category set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91)  * It can be reset via smackfs/mapped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) int smack_cipso_mapped = SMACK_CIPSO_MAPPED_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) #ifdef CONFIG_SECURITY_SMACK_BRINGUP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97)  * Allow one label to be unconfined. This is for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98)  * debugging and application bring-up purposes only.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99)  * It is bad and wrong, but everyone seems to expect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100)  * to have it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) struct smack_known *smack_unconfined;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106)  * If this value is set restrict syslog use to the label specified.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107)  * It can be reset via smackfs/syslog
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) struct smack_known *smack_syslog_label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112)  * Ptrace current rule
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113)  * SMACK_PTRACE_DEFAULT    regular smack ptrace rules (/proc based)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114)  * SMACK_PTRACE_EXACT      labels must match, but can be overriden with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115)  *			   CAP_SYS_PTRACE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116)  * SMACK_PTRACE_DRACONIAN  lables must match, CAP_SYS_PTRACE has no effect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) int smack_ptrace_rule = SMACK_PTRACE_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121)  * Certain IP addresses may be designated as single label hosts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122)  * Packets are sent there unlabeled, but only from tasks that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123)  * can write to the specified label.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) LIST_HEAD(smk_net4addr_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) LIST_HEAD(smk_net6addr_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) #endif /* CONFIG_IPV6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132)  * Rule lists are maintained for each label.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) struct smack_parsed_rule {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 	struct smack_known	*smk_subject;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 	struct smack_known	*smk_object;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 	int			smk_access1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	int			smk_access2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144)  * Values for parsing cipso rules
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145)  * SMK_DIGITLEN: Length of a digit field in a rule.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146)  * SMK_CIPSOMIN: Minimum possible cipso rule length.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147)  * SMK_CIPSOMAX: Maximum possible cipso rule length.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) #define SMK_DIGITLEN 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) #define SMK_CIPSOMIN (SMK_LABELLEN + 2 * SMK_DIGITLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) #define SMK_CIPSOMAX (SMK_CIPSOMIN + SMACK_CIPSO_MAXCATNUM * SMK_DIGITLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154)  * Values for parsing MAC rules
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155)  * SMK_ACCESS: Maximum possible combination of access permissions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156)  * SMK_ACCESSLEN: Maximum length for a rule access field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157)  * SMK_LOADLEN: Smack rule length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) #define SMK_OACCESS	"rwxa"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) #define SMK_ACCESS	"rwxatl"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) #define SMK_OACCESSLEN	(sizeof(SMK_OACCESS) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) #define SMK_ACCESSLEN	(sizeof(SMK_ACCESS) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) #define SMK_OLOADLEN	(SMK_LABELLEN + SMK_LABELLEN + SMK_OACCESSLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) #define SMK_LOADLEN	(SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167)  * Stricly for CIPSO level manipulation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168)  * Set the category bit number in a smack label sized buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) static inline void smack_catset_bit(unsigned int cat, char *catsetp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 	if (cat == 0 || cat > (SMK_CIPSOLEN * 8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	catsetp[(cat - 1) / 8] |= 0x80 >> ((cat - 1) % 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) }
^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)  * smk_netlabel_audit_set - fill a netlbl_audit struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180)  * @nap: structure to fill
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) static void smk_netlabel_audit_set(struct netlbl_audit *nap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	struct smack_known *skp = smk_of_current();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	nap->loginuid = audit_get_loginuid(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 	nap->sessionid = audit_get_sessionid(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	nap->secid = skp->smk_secid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192)  * Value for parsing single label host rules
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193)  * "1.2.3.4 X"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) #define SMK_NETLBLADDRMIN	9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198)  * smk_set_access - add a rule to the rule list or replace an old rule
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199)  * @srp: the rule to add or replace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200)  * @rule_list: the list of rules
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201)  * @rule_lock: the rule list lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203)  * Looks through the current subject/object/access list for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204)  * the subject/object pair and replaces the access that was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205)  * there. If the pair isn't found add it with the specified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206)  * access.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208)  * Returns 0 if nothing goes wrong or -ENOMEM if it fails
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209)  * during the allocation of the new pair to add.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) static int smk_set_access(struct smack_parsed_rule *srp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 				struct list_head *rule_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 				struct mutex *rule_lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	struct smack_rule *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	int found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	mutex_lock(rule_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	 * Because the object label is less likely to match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	 * than the subject label check it first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	list_for_each_entry_rcu(sp, rule_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 		if (sp->smk_object == srp->smk_object &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 		    sp->smk_subject == srp->smk_subject) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 			found = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 			sp->smk_access |= srp->smk_access1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 			sp->smk_access &= ~srp->smk_access2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	if (found == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 		sp = kmem_cache_zalloc(smack_rule_cache, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 		if (sp == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 			rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 		sp->smk_subject = srp->smk_subject;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 		sp->smk_object = srp->smk_object;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 		sp->smk_access = srp->smk_access1 & ~srp->smk_access2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 		list_add_rcu(&sp->list, rule_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 	mutex_unlock(rule_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255)  * smk_perm_from_str - parse smack accesses from a text string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256)  * @string: a text string that contains a Smack accesses code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258)  * Returns an integer with respective bits set for specified accesses.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) static int smk_perm_from_str(const char *string)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 	int perm = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 	const char *cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 	for (cp = string; ; cp++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 		switch (*cp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 		case '-':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 		case 'r':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 		case 'R':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 			perm |= MAY_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 		case 'w':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 		case 'W':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 			perm |= MAY_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 		case 'x':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 		case 'X':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 			perm |= MAY_EXEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 		case 'a':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 		case 'A':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 			perm |= MAY_APPEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 		case 't':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 		case 'T':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 			perm |= MAY_TRANSMUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 		case 'l':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 		case 'L':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 			perm |= MAY_LOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 		case 'b':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 		case 'B':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 			perm |= MAY_BRINGUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 			return perm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303)  * smk_fill_rule - Fill Smack rule from strings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304)  * @subject: subject label string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305)  * @object: object label string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306)  * @access1: access string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307)  * @access2: string with permissions to be removed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308)  * @rule: Smack rule
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309)  * @import: if non-zero, import labels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310)  * @len: label length limit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312)  * Returns 0 on success, appropriate error code on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) static int smk_fill_rule(const char *subject, const char *object,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 				const char *access1, const char *access2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 				struct smack_parsed_rule *rule, int import,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 				int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 	const char *cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 	struct smack_known *skp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 	if (import) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 		rule->smk_subject = smk_import_entry(subject, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 		if (IS_ERR(rule->smk_subject))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 			return PTR_ERR(rule->smk_subject);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 		rule->smk_object = smk_import_entry(object, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 		if (IS_ERR(rule->smk_object))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 			return PTR_ERR(rule->smk_object);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 		cp = smk_parse_smack(subject, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 		if (IS_ERR(cp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 			return PTR_ERR(cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 		skp = smk_find_entry(cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 		kfree(cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 		if (skp == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 			return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 		rule->smk_subject = skp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 		cp = smk_parse_smack(object, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 		if (IS_ERR(cp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 			return PTR_ERR(cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 		skp = smk_find_entry(cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 		kfree(cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 		if (skp == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 			return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 		rule->smk_object = skp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	rule->smk_access1 = smk_perm_from_str(access1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	if (access2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 		rule->smk_access2 = smk_perm_from_str(access2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 		rule->smk_access2 = ~rule->smk_access1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360)  * smk_parse_rule - parse Smack rule from load string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361)  * @data: string to be parsed whose size is SMK_LOADLEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362)  * @rule: Smack rule
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363)  * @import: if non-zero, import labels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365)  * Returns 0 on success, -1 on errors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) static int smk_parse_rule(const char *data, struct smack_parsed_rule *rule,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 				int import)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	rc = smk_fill_rule(data, data + SMK_LABELLEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 			   data + SMK_LABELLEN + SMK_LABELLEN, NULL, rule,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 			   import, SMK_LABELLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379)  * smk_parse_long_rule - parse Smack rule from rule string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380)  * @data: string to be parsed, null terminated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381)  * @rule: Will be filled with Smack parsed rule
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382)  * @import: if non-zero, import labels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383)  * @tokens: numer of substrings expected in data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385)  * Returns number of processed bytes on success, -ERRNO on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) static ssize_t smk_parse_long_rule(char *data, struct smack_parsed_rule *rule,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 				int import, int tokens)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 	ssize_t cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 	char *tok[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	 * Parsing the rule in-place, filling all white-spaces with '\0'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 	for (i = 0; i < tokens; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 		while (isspace(data[cnt]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 			data[cnt++] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 		if (data[cnt] == '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 			/* Unexpected end of data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 		tok[i] = data + cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 		while (data[cnt] && !isspace(data[cnt]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 			++cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 	while (isspace(data[cnt]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 		data[cnt++] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 	while (i < 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 		tok[i++] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	rc = smk_fill_rule(tok[0], tok[1], tok[2], tok[3], rule, import, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	return rc == 0 ? cnt : rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) #define SMK_FIXED24_FMT	0	/* Fixed 24byte label format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) #define SMK_LONG_FMT	1	/* Variable long label format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) #define SMK_CHANGE_FMT	2	/* Rule modification format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425)  * smk_write_rules_list - write() for any /smack rule file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426)  * @file: file pointer, not actually used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427)  * @buf: where to get the data from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428)  * @count: bytes sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429)  * @ppos: where to start - must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430)  * @rule_list: the list of rules to write to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431)  * @rule_lock: lock for the rule list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432)  * @format: /smack/load or /smack/load2 or /smack/change-rule format.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434)  * Get one smack access rule from above.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435)  * The format for SMK_LONG_FMT is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436)  *	"subject<whitespace>object<whitespace>access[<whitespace>...]"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437)  * The format for SMK_FIXED24_FMT is exactly:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438)  *	"subject                 object                  rwxat"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439)  * The format for SMK_CHANGE_FMT is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440)  *	"subject<whitespace>object<whitespace>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441)  *	 acc_enable<whitespace>acc_disable[<whitespace>...]"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 					size_t count, loff_t *ppos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 					struct list_head *rule_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 					struct mutex *rule_lock, int format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 	struct smack_parsed_rule rule;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 	char *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	int trunc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	int tokens;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	ssize_t cnt = 0;
^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) 	 * No partial writes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 	 * Enough data must be present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 	if (*ppos != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 	if (format == SMK_FIXED24_FMT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 		 * Minor hack for backward compatibility
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 		if (count < SMK_OLOADLEN || count > SMK_LOADLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 		if (count >= PAGE_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 			count = PAGE_SIZE - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 			trunc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	data = memdup_user_nul(buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 	if (IS_ERR(data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 		return PTR_ERR(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 	 * In case of parsing only part of user buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 	 * avoid having partial rule at the data buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 	if (trunc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 		while (count > 0 && (data[count - 1] != '\n'))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 			--count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 		if (count == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 			rc = -EINVAL;
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 	data[count] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	tokens = (format == SMK_CHANGE_FMT ? 4 : 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	while (cnt < count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 		if (format == SMK_FIXED24_FMT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 			rc = smk_parse_rule(data, &rule, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 			if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 			cnt = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 			rc = smk_parse_long_rule(data + cnt, &rule, 1, tokens);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 			if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 			if (rc == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 				rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 			cnt += rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 		if (rule_list == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 			rc = smk_set_access(&rule, &rule.smk_subject->smk_rules,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 				&rule.smk_subject->smk_rules_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 			rc = smk_set_access(&rule, rule_list, rule_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 	rc = cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 	kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) }
^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)  * Core logic for smackfs seq list operations.
^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 void *smk_seq_start(struct seq_file *s, loff_t *pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 				struct list_head *head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	struct list_head *list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 	int i = *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 	for (list = rcu_dereference(list_next_rcu(head));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 		list != head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 		list = rcu_dereference(list_next_rcu(list))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 		if (i-- == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 			return list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) static void *smk_seq_next(struct seq_file *s, void *v, loff_t *pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 				struct list_head *head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	struct list_head *list = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	++*pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	list = rcu_dereference(list_next_rcu(list));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 	return (list == head) ? NULL : list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) static void smk_seq_stop(struct seq_file *s, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	 * Don't show any rules with label names too long for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	 * interface file (/smack/load or /smack/load2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	 * because you should expect to be able to write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	 * anything you read back.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 	if (strlen(srp->smk_subject->smk_known) >= max ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	    strlen(srp->smk_object->smk_known) >= max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	if (srp->smk_access == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	seq_printf(s, "%s %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 		   srp->smk_subject->smk_known,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 		   srp->smk_object->smk_known);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	seq_putc(s, ' ');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	if (srp->smk_access & MAY_READ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 		seq_putc(s, 'r');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	if (srp->smk_access & MAY_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 		seq_putc(s, 'w');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	if (srp->smk_access & MAY_EXEC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 		seq_putc(s, 'x');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 	if (srp->smk_access & MAY_APPEND)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 		seq_putc(s, 'a');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 	if (srp->smk_access & MAY_TRANSMUTE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 		seq_putc(s, 't');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 	if (srp->smk_access & MAY_LOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 		seq_putc(s, 'l');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 	if (srp->smk_access & MAY_BRINGUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 		seq_putc(s, 'b');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 	seq_putc(s, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604)  * Seq_file read operations for /smack/load
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) static void *load2_seq_start(struct seq_file *s, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	return smk_seq_start(s, pos, &smack_known_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) static void *load2_seq_next(struct seq_file *s, void *v, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	return smk_seq_next(s, v, pos, &smack_known_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) static int load_seq_show(struct seq_file *s, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	struct list_head *list = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 	struct smack_rule *srp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 	struct smack_known *skp =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 		list_entry_rcu(list, struct smack_known, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	list_for_each_entry_rcu(srp, &skp->smk_rules, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 		smk_rule_show(s, srp, SMK_LABELLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) static const struct seq_operations load_seq_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 	.start = load2_seq_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 	.next  = load2_seq_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 	.show  = load_seq_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 	.stop  = smk_seq_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638)  * smk_open_load - open() for /smack/load
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639)  * @inode: inode structure representing file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640)  * @file: "load" file pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642)  * For reading, use load_seq_* seq_file reading operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) static int smk_open_load(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 	return seq_open(file, &load_seq_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650)  * smk_write_load - write() for /smack/load
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651)  * @file: file pointer, not actually used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652)  * @buf: where to get the data from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653)  * @count: bytes sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654)  * @ppos: where to start - must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) static ssize_t smk_write_load(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 			      size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 	 * Must have privilege.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 	 * No partial writes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 	 * Enough data must be present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 	if (!smack_privileged(CAP_MAC_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 	return smk_write_rules_list(file, buf, count, ppos, NULL, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 				    SMK_FIXED24_FMT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) static const struct file_operations smk_load_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 	.open           = smk_open_load,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	.read		= seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 	.llseek         = seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 	.write		= smk_write_load,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 	.release        = seq_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681)  * smk_cipso_doi - initialize the CIPSO domain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) static void smk_cipso_doi(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	struct cipso_v4_doi *doip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	struct netlbl_audit nai;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	smk_netlabel_audit_set(&nai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 	rc = netlbl_cfg_map_del(NULL, PF_INET, NULL, NULL, &nai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 	if (rc != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 		printk(KERN_WARNING "%s:%d remove rc = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 		       __func__, __LINE__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 	doip = kmalloc(sizeof(struct cipso_v4_doi), GFP_KERNEL | __GFP_NOFAIL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 	doip->map.std = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 	doip->doi = smk_cipso_doi_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 	doip->type = CIPSO_V4_MAP_PASS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 	doip->tags[0] = CIPSO_V4_TAG_RBITMAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	for (rc = 1; rc < CIPSO_V4_TAG_MAXCNT; rc++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 		doip->tags[rc] = CIPSO_V4_TAG_INVALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 	rc = netlbl_cfg_cipsov4_add(doip, &nai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 	if (rc != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 		printk(KERN_WARNING "%s:%d cipso add rc = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 		       __func__, __LINE__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 		kfree(doip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	rc = netlbl_cfg_cipsov4_map_add(doip->doi, NULL, NULL, NULL, &nai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 	if (rc != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 		printk(KERN_WARNING "%s:%d map add rc = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 		       __func__, __LINE__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 		netlbl_cfg_cipsov4_del(doip->doi, &nai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) }
^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)  * smk_unlbl_ambient - initialize the unlabeled domain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722)  * @oldambient: previous domain string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) static void smk_unlbl_ambient(char *oldambient)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 	struct netlbl_audit nai;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 	smk_netlabel_audit_set(&nai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 	if (oldambient != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 		rc = netlbl_cfg_map_del(oldambient, PF_INET, NULL, NULL, &nai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 		if (rc != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 			printk(KERN_WARNING "%s:%d remove rc = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 			       __func__, __LINE__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 	if (smack_net_ambient == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 		smack_net_ambient = &smack_known_floor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 	rc = netlbl_cfg_unlbl_map_add(smack_net_ambient->smk_known, PF_INET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 				      NULL, NULL, &nai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 	if (rc != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 		printk(KERN_WARNING "%s:%d add rc = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 		       __func__, __LINE__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748)  * Seq_file read operations for /smack/cipso
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) static void *cipso_seq_start(struct seq_file *s, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 	return smk_seq_start(s, pos, &smack_known_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) static void *cipso_seq_next(struct seq_file *s, void *v, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 	return smk_seq_next(s, v, pos, &smack_known_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762)  * Print cipso labels in format:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763)  * label level[/cat[,cat]]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) static int cipso_seq_show(struct seq_file *s, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 	struct list_head  *list = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 	struct smack_known *skp =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 		list_entry_rcu(list, struct smack_known, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 	struct netlbl_lsm_catmap *cmp = skp->smk_netlabel.attr.mls.cat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 	char sep = '/';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 	 * Don't show a label that could not have been set using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 	 * /smack/cipso. This is in support of the notion that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 	 * anything read from /smack/cipso ought to be writeable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 	 * to /smack/cipso.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 	 * /smack/cipso2 should be used instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 	if (strlen(skp->smk_known) >= SMK_LABELLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 	seq_printf(s, "%s %3d", skp->smk_known, skp->smk_netlabel.attr.mls.lvl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 	for (i = netlbl_catmap_walk(cmp, 0); i >= 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	     i = netlbl_catmap_walk(cmp, i + 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 		seq_printf(s, "%c%d", sep, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 		sep = ',';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	seq_putc(s, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) static const struct seq_operations cipso_seq_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 	.start = cipso_seq_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 	.next  = cipso_seq_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 	.show  = cipso_seq_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 	.stop  = smk_seq_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806)  * smk_open_cipso - open() for /smack/cipso
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807)  * @inode: inode structure representing file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808)  * @file: "cipso" file pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810)  * Connect our cipso_seq_* operations with /smack/cipso
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811)  * file_operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) static int smk_open_cipso(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 	return seq_open(file, &cipso_seq_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819)  * smk_set_cipso - do the work for write() for cipso and cipso2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820)  * @file: file pointer, not actually used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821)  * @buf: where to get the data from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822)  * @count: bytes sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823)  * @ppos: where to start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824)  * @format: /smack/cipso or /smack/cipso2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826)  * Accepts only one cipso rule per write call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827)  * Returns number of bytes written or error code, as appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 				size_t count, loff_t *ppos, int format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 	struct netlbl_lsm_catmap *old_cat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	struct smack_known *skp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 	struct netlbl_lsm_secattr ncats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	char mapcatset[SMK_CIPSOLEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 	int maplevel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 	unsigned int cat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 	int catlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 	ssize_t rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 	char *data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 	char *rule;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 	 * Must have privilege.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 	 * No partial writes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 	 * Enough data must be present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	if (!smack_privileged(CAP_MAC_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	if (*ppos != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	if (format == SMK_FIXED24_FMT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	    (count < SMK_CIPSOMIN || count > SMK_CIPSOMAX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	if (count > PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 	data = memdup_user_nul(buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 	if (IS_ERR(data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 		return PTR_ERR(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 	rule = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	 * Only allow one writer at a time. Writes should be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	 * quite rare and small in any case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 	mutex_lock(&smack_cipso_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 	skp = smk_import_entry(rule, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 	if (IS_ERR(skp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 		rc = PTR_ERR(skp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	if (format == SMK_FIXED24_FMT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 		rule += SMK_LABELLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 		rule += strlen(skp->smk_known) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	if (rule > data + count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 		rc = -EOVERFLOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 	ret = sscanf(rule, "%d", &maplevel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	if (ret != 1 || maplevel < 0 || maplevel > SMACK_CIPSO_MAXLEVEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 	rule += SMK_DIGITLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 	if (rule > data + count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 		rc = -EOVERFLOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 	ret = sscanf(rule, "%d", &catlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	if (ret != 1 || catlen > SMACK_CIPSO_MAXCATNUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 	if (format == SMK_FIXED24_FMT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 	    count != (SMK_CIPSOMIN + catlen * SMK_DIGITLEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	memset(mapcatset, 0, sizeof(mapcatset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	for (i = 0; i < catlen; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 		rule += SMK_DIGITLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 		if (rule > data + count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 			rc = -EOVERFLOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 		ret = sscanf(rule, "%u", &cat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 		if (ret != 1 || cat > SMACK_CIPSO_MAXCATNUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 		smack_catset_bit(cat, mapcatset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 	rc = smk_netlbl_mls(maplevel, mapcatset, &ncats, SMK_CIPSOLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	if (rc >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 		old_cat = skp->smk_netlabel.attr.mls.cat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 		skp->smk_netlabel.attr.mls.cat = ncats.attr.mls.cat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 		skp->smk_netlabel.attr.mls.lvl = ncats.attr.mls.lvl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 		synchronize_rcu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 		netlbl_catmap_free(old_cat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 		rc = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 		 * This mapping may have been cached, so clear the cache.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 		netlbl_cache_invalidate();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	mutex_unlock(&smack_cipso_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941)  * smk_write_cipso - write() for /smack/cipso
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942)  * @file: file pointer, not actually used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943)  * @buf: where to get the data from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944)  * @count: bytes sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945)  * @ppos: where to start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947)  * Accepts only one cipso rule per write call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948)  * Returns number of bytes written or error code, as appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) static ssize_t smk_write_cipso(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 			       size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	return smk_set_cipso(file, buf, count, ppos, SMK_FIXED24_FMT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) static const struct file_operations smk_cipso_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	.open           = smk_open_cipso,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	.read		= seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	.llseek         = seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	.write		= smk_write_cipso,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	.release        = seq_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965)  * Seq_file read operations for /smack/cipso2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969)  * Print cipso labels in format:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970)  * label level[/cat[,cat]]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) static int cipso2_seq_show(struct seq_file *s, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 	struct list_head  *list = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 	struct smack_known *skp =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 		list_entry_rcu(list, struct smack_known, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 	struct netlbl_lsm_catmap *cmp = skp->smk_netlabel.attr.mls.cat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	char sep = '/';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	seq_printf(s, "%s %3d", skp->smk_known, skp->smk_netlabel.attr.mls.lvl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	for (i = netlbl_catmap_walk(cmp, 0); i >= 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	     i = netlbl_catmap_walk(cmp, i + 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 		seq_printf(s, "%c%d", sep, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 		sep = ',';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 	seq_putc(s, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) static const struct seq_operations cipso2_seq_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	.start = cipso_seq_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	.next  = cipso_seq_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	.show  = cipso2_seq_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	.stop  = smk_seq_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)  * smk_open_cipso2 - open() for /smack/cipso2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)  * @inode: inode structure representing file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)  * @file: "cipso2" file pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)  * Connect our cipso_seq_* operations with /smack/cipso2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)  * file_operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) static int smk_open_cipso2(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	return seq_open(file, &cipso2_seq_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) }
^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)  * smk_write_cipso2 - write() for /smack/cipso2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)  * @file: file pointer, not actually used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)  * @buf: where to get the data from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)  * @count: bytes sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)  * @ppos: where to start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)  * Accepts only one cipso rule per write call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)  * Returns number of bytes written or error code, as appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) static ssize_t smk_write_cipso2(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 			      size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	return smk_set_cipso(file, buf, count, ppos, SMK_LONG_FMT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) static const struct file_operations smk_cipso2_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	.open           = smk_open_cipso2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 	.read		= seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	.llseek         = seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	.write		= smk_write_cipso2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 	.release        = seq_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)  * Seq_file read operations for /smack/netlabel
^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 void *net4addr_seq_start(struct seq_file *s, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 	return smk_seq_start(s, pos, &smk_net4addr_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) static void *net4addr_seq_next(struct seq_file *s, void *v, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	return smk_seq_next(s, v, pos, &smk_net4addr_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) }
^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)  * Print host/label pairs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) static int net4addr_seq_show(struct seq_file *s, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	struct list_head *list = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 	struct smk_net4addr *skp =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 			list_entry_rcu(list, struct smk_net4addr, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 	char *kp = SMACK_CIPSO_OPTION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	if (skp->smk_label != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 		kp = skp->smk_label->smk_known;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 	seq_printf(s, "%pI4/%d %s\n", &skp->smk_host.s_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 			skp->smk_masks, kp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) static const struct seq_operations net4addr_seq_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 	.start = net4addr_seq_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	.next  = net4addr_seq_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	.show  = net4addr_seq_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 	.stop  = smk_seq_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)  * smk_open_net4addr - open() for /smack/netlabel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)  * @inode: inode structure representing file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)  * @file: "netlabel" file pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)  * Connect our net4addr_seq_* operations with /smack/netlabel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083)  * file_operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) static int smk_open_net4addr(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 	return seq_open(file, &net4addr_seq_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)  * smk_net4addr_insert
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)  * @new : netlabel to insert
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)  * This helper insert netlabel in the smack_net4addrs list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)  * sorted by netmask length (longest to smallest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)  * locked by &smk_net4addr_lock in smk_write_net4addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) static void smk_net4addr_insert(struct smk_net4addr *new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 	struct smk_net4addr *m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	struct smk_net4addr *m_next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	if (list_empty(&smk_net4addr_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 		list_add_rcu(&new->list, &smk_net4addr_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 	m = list_entry_rcu(smk_net4addr_list.next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 			   struct smk_net4addr, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 	/* the comparison '>' is a bit hacky, but works */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 	if (new->smk_masks > m->smk_masks) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 		list_add_rcu(&new->list, &smk_net4addr_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	list_for_each_entry_rcu(m, &smk_net4addr_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 		if (list_is_last(&m->list, &smk_net4addr_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 			list_add_rcu(&new->list, &m->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 		m_next = list_entry_rcu(m->list.next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 					struct smk_net4addr, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 		if (new->smk_masks > m_next->smk_masks) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 			list_add_rcu(&new->list, &m->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 			return;
^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) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)  * smk_write_net4addr - write() for /smack/netlabel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)  * @file: file pointer, not actually used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)  * @buf: where to get the data from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)  * @count: bytes sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)  * @ppos: where to start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)  * Accepts only one net4addr per write call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)  * Returns number of bytes written or error code, as appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) static ssize_t smk_write_net4addr(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 				size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 	struct smk_net4addr *snp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 	struct sockaddr_in newname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 	char *smack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 	struct smack_known *skp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 	char *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 	char *host = (char *)&newname.sin_addr.s_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 	struct netlbl_audit audit_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 	struct in_addr mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 	unsigned int m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 	unsigned int masks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	int found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 	u32 mask_bits = (1<<31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 	__be32 nsa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 	u32 temp_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 	 * Must have privilege.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 	 * No partial writes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 	 * Enough data must be present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 	 * "<addr/mask, as a.b.c.d/e><space><label>"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 	 * "<addr, as a.b.c.d><space><label>"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 	if (!smack_privileged(CAP_MAC_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 	if (*ppos != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 	if (count < SMK_NETLBLADDRMIN || count > PAGE_SIZE - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 	data = memdup_user_nul(buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 	if (IS_ERR(data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 		return PTR_ERR(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 	smack = kzalloc(count + 1, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 	if (smack == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 		rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 		goto free_data_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 	rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd/%u %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 		&host[0], &host[1], &host[2], &host[3], &masks, smack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 	if (rc != 6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 		rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 			&host[0], &host[1], &host[2], &host[3], smack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 		if (rc != 5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 			rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 			goto free_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 		m = BEBITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 		masks = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 	if (masks > BEBITS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 		rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 		goto free_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 	}
^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) 	 * If smack begins with '-', it is an option, don't import it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 	if (smack[0] != '-') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 		skp = smk_import_entry(smack, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 		if (IS_ERR(skp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 			rc = PTR_ERR(skp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 			goto free_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 		 * Only the -CIPSO option is supported for IPv4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 		if (strcmp(smack, SMACK_CIPSO_OPTION) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 			rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 			goto free_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 	for (m = masks, temp_mask = 0; m > 0; m--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 		temp_mask |= mask_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 		mask_bits >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 	mask.s_addr = cpu_to_be32(temp_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 	newname.sin_addr.s_addr &= mask.s_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 	 * Only allow one writer at a time. Writes should be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 	 * quite rare and small in any case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 	mutex_lock(&smk_net4addr_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 	nsa = newname.sin_addr.s_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 	/* try to find if the prefix is already in the list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 	found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 	list_for_each_entry_rcu(snp, &smk_net4addr_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 		if (snp->smk_host.s_addr == nsa && snp->smk_masks == masks) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 			found = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 	smk_netlabel_audit_set(&audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 	if (found == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 		snp = kzalloc(sizeof(*snp), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 		if (snp == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 			rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 			rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 			snp->smk_host.s_addr = newname.sin_addr.s_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 			snp->smk_mask.s_addr = mask.s_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 			snp->smk_label = skp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 			snp->smk_masks = masks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 			smk_net4addr_insert(snp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 		 * Delete the unlabeled entry, only if the previous label
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 		 * wasn't the special CIPSO option
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 		if (snp->smk_label != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 			rc = netlbl_cfg_unlbl_static_del(&init_net, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 					&snp->smk_host, &snp->smk_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 					PF_INET, &audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 			rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 		snp->smk_label = skp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 	 * Now tell netlabel about the single label nature of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 	 * this host so that incoming packets get labeled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 	 * but only if we didn't get the special CIPSO option
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 	if (rc == 0 && skp != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 		rc = netlbl_cfg_unlbl_static_add(&init_net, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 			&snp->smk_host, &snp->smk_mask, PF_INET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 			snp->smk_label->smk_secid, &audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 	if (rc == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 		rc = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 	mutex_unlock(&smk_net4addr_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) free_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 	kfree(smack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) free_data_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 	kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) static const struct file_operations smk_net4addr_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 	.open           = smk_open_net4addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 	.read		= seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 	.llseek         = seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 	.write		= smk_write_net4addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 	.release        = seq_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)  * Seq_file read operations for /smack/netlabel6
^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) static void *net6addr_seq_start(struct seq_file *s, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 	return smk_seq_start(s, pos, &smk_net6addr_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) static void *net6addr_seq_next(struct seq_file *s, void *v, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 	return smk_seq_next(s, v, pos, &smk_net6addr_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319)  * Print host/label pairs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) static int net6addr_seq_show(struct seq_file *s, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 	struct list_head *list = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 	struct smk_net6addr *skp =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 			 list_entry(list, struct smk_net6addr, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 	if (skp->smk_label != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 		seq_printf(s, "%pI6/%d %s\n", &skp->smk_host, skp->smk_masks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 				skp->smk_label->smk_known);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) static const struct seq_operations net6addr_seq_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 	.start = net6addr_seq_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 	.next  = net6addr_seq_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 	.show  = net6addr_seq_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 	.stop  = smk_seq_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342)  * smk_open_net6addr - open() for /smack/netlabel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343)  * @inode: inode structure representing file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344)  * @file: "netlabel" file pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346)  * Connect our net6addr_seq_* operations with /smack/netlabel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)  * file_operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) static int smk_open_net6addr(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 	return seq_open(file, &net6addr_seq_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) }
^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)  * smk_net6addr_insert
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)  * @new : entry to insert
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)  * This inserts an entry in the smack_net6addrs list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359)  * sorted by netmask length (longest to smallest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360)  * locked by &smk_net6addr_lock in smk_write_net6addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) static void smk_net6addr_insert(struct smk_net6addr *new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 	struct smk_net6addr *m_next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 	struct smk_net6addr *m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 	if (list_empty(&smk_net6addr_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 		list_add_rcu(&new->list, &smk_net6addr_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 	m = list_entry_rcu(smk_net6addr_list.next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 			   struct smk_net6addr, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 	if (new->smk_masks > m->smk_masks) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 		list_add_rcu(&new->list, &smk_net6addr_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 	list_for_each_entry_rcu(m, &smk_net6addr_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 		if (list_is_last(&m->list, &smk_net6addr_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 			list_add_rcu(&new->list, &m->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 		m_next = list_entry_rcu(m->list.next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 					struct smk_net6addr, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 		if (new->smk_masks > m_next->smk_masks) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 			list_add_rcu(&new->list, &m->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 	}
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397)  * smk_write_net6addr - write() for /smack/netlabel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398)  * @file: file pointer, not actually used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)  * @buf: where to get the data from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400)  * @count: bytes sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401)  * @ppos: where to start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403)  * Accepts only one net6addr per write call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404)  * Returns number of bytes written or error code, as appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) static ssize_t smk_write_net6addr(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 				size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 	struct smk_net6addr *snp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 	struct in6_addr newname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 	struct in6_addr fullmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 	struct smack_known *skp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 	char *smack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 	char *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 	int found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 	unsigned int scanned[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 	unsigned int m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 	unsigned int mask = 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 	 * Must have privilege.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 	 * No partial writes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 	 * Enough data must be present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 	 * "<addr/mask, as a:b:c:d:e:f:g:h/e><space><label>"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 	 * "<addr, as a:b:c:d:e:f:g:h><space><label>"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 	if (!smack_privileged(CAP_MAC_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 	if (*ppos != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 	if (count < SMK_NETLBLADDRMIN || count > PAGE_SIZE - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 	data = memdup_user_nul(buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 	if (IS_ERR(data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 		return PTR_ERR(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 	smack = kzalloc(count + 1, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 	if (smack == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 		rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 		goto free_data_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 	i = sscanf(data, "%x:%x:%x:%x:%x:%x:%x:%x/%u %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 			&scanned[0], &scanned[1], &scanned[2], &scanned[3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 			&scanned[4], &scanned[5], &scanned[6], &scanned[7],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 			&mask, smack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 	if (i != 10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 		i = sscanf(data, "%x:%x:%x:%x:%x:%x:%x:%x %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 				&scanned[0], &scanned[1], &scanned[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 				&scanned[3], &scanned[4], &scanned[5],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 				&scanned[6], &scanned[7], smack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 		if (i != 9) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 			rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 			goto free_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 	if (mask > 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 		rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 		goto free_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 	for (i = 0; i < 8; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 		if (scanned[i] > 0xffff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 			rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 			goto free_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 		newname.s6_addr16[i] = htons(scanned[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 	 * If smack begins with '-', it is an option, don't import it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 	if (smack[0] != '-') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 		skp = smk_import_entry(smack, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 		if (IS_ERR(skp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 			rc = PTR_ERR(skp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 			goto free_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 		 * Only -DELETE is supported for IPv6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 		if (strcmp(smack, SMACK_DELETE_OPTION) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 			rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 			goto free_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 	for (i = 0, m = mask; i < 8; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 		if (m >= 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 			fullmask.s6_addr16[i] = 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 			m -= 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 		} else if (m > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 			fullmask.s6_addr16[i] = (1 << m) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 			m = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 			fullmask.s6_addr16[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 		newname.s6_addr16[i] &= fullmask.s6_addr16[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 	 * Only allow one writer at a time. Writes should be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 	 * quite rare and small in any case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 	mutex_lock(&smk_net6addr_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 	 * Try to find the prefix in the list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 	list_for_each_entry_rcu(snp, &smk_net6addr_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 		if (mask != snp->smk_masks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 		for (found = 1, i = 0; i < 8; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 			if (newname.s6_addr16[i] !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 			    snp->smk_host.s6_addr16[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 				found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 		if (found == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 	if (found == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 		snp = kzalloc(sizeof(*snp), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 		if (snp == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 			rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 			snp->smk_host = newname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 			snp->smk_mask = fullmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 			snp->smk_masks = mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 			snp->smk_label = skp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 			smk_net6addr_insert(snp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 		snp->smk_label = skp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 	if (rc == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 		rc = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 	mutex_unlock(&smk_net6addr_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) free_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 	kfree(smack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) free_data_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 	kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) static const struct file_operations smk_net6addr_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 	.open           = smk_open_net6addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 	.read		= seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 	.llseek         = seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 	.write		= smk_write_net6addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 	.release        = seq_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) #endif /* CONFIG_IPV6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562)  * smk_read_doi - read() for /smack/doi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563)  * @filp: file pointer, not actually used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)  * @buf: where to put the result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565)  * @count: maximum to send along
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566)  * @ppos: where to start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568)  * Returns number of bytes read or error code, as appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) static ssize_t smk_read_doi(struct file *filp, char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 			    size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 	char temp[80];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 	ssize_t rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 	if (*ppos != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 	sprintf(temp, "%d", smk_cipso_doi_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 	rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586)  * smk_write_doi - write() for /smack/doi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587)  * @file: file pointer, not actually used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588)  * @buf: where to get the data from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589)  * @count: bytes sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590)  * @ppos: where to start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592)  * Returns number of bytes written or error code, as appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) static ssize_t smk_write_doi(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 			     size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 	char temp[80];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 	if (!smack_privileged(CAP_MAC_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 	if (count >= sizeof(temp) || count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 	if (copy_from_user(temp, buf, count) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 	temp[count] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 	if (sscanf(temp, "%d", &i) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 	smk_cipso_doi_value = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) 	smk_cipso_doi();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) static const struct file_operations smk_doi_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 	.read		= smk_read_doi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) 	.write		= smk_write_doi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) 	.llseek		= default_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628)  * smk_read_direct - read() for /smack/direct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629)  * @filp: file pointer, not actually used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630)  * @buf: where to put the result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631)  * @count: maximum to send along
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632)  * @ppos: where to start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634)  * Returns number of bytes read or error code, as appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) static ssize_t smk_read_direct(struct file *filp, char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 			       size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 	char temp[80];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 	ssize_t rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 	if (*ppos != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 	sprintf(temp, "%d", smack_cipso_direct);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 	rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) }
^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)  * smk_write_direct - write() for /smack/direct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653)  * @file: file pointer, not actually used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654)  * @buf: where to get the data from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655)  * @count: bytes sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656)  * @ppos: where to start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658)  * Returns number of bytes written or error code, as appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) static ssize_t smk_write_direct(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 				size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 	struct smack_known *skp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) 	char temp[80];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 	if (!smack_privileged(CAP_MAC_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 	if (count >= sizeof(temp) || count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) 	if (copy_from_user(temp, buf, count) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) 	temp[count] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 	if (sscanf(temp, "%d", &i) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 	 * Don't do anything if the value hasn't actually changed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 	 * If it is changing reset the level on entries that were
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 	 * set up to be direct when they were created.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 	if (smack_cipso_direct != i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 		mutex_lock(&smack_known_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 		list_for_each_entry_rcu(skp, &smack_known_list, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) 			if (skp->smk_netlabel.attr.mls.lvl ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 			    smack_cipso_direct)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) 				skp->smk_netlabel.attr.mls.lvl = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 		smack_cipso_direct = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) 		mutex_unlock(&smack_known_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) static const struct file_operations smk_direct_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 	.read		= smk_read_direct,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) 	.write		= smk_write_direct,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 	.llseek		= default_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706)  * smk_read_mapped - read() for /smack/mapped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707)  * @filp: file pointer, not actually used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708)  * @buf: where to put the result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709)  * @count: maximum to send along
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710)  * @ppos: where to start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712)  * Returns number of bytes read or error code, as appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) static ssize_t smk_read_mapped(struct file *filp, char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 			       size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 	char temp[80];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 	ssize_t rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) 	if (*ppos != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 	sprintf(temp, "%d", smack_cipso_mapped);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 	rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730)  * smk_write_mapped - write() for /smack/mapped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731)  * @file: file pointer, not actually used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732)  * @buf: where to get the data from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733)  * @count: bytes sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734)  * @ppos: where to start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736)  * Returns number of bytes written or error code, as appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) static ssize_t smk_write_mapped(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 				size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 	struct smack_known *skp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 	char temp[80];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) 	if (!smack_privileged(CAP_MAC_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 	if (count >= sizeof(temp) || count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) 	if (copy_from_user(temp, buf, count) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 	temp[count] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) 	if (sscanf(temp, "%d", &i) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 	 * Don't do anything if the value hasn't actually changed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) 	 * If it is changing reset the level on entries that were
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) 	 * set up to be mapped when they were created.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 	if (smack_cipso_mapped != i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 		mutex_lock(&smack_known_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 		list_for_each_entry_rcu(skp, &smack_known_list, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) 			if (skp->smk_netlabel.attr.mls.lvl ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 			    smack_cipso_mapped)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 				skp->smk_netlabel.attr.mls.lvl = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) 		smack_cipso_mapped = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 		mutex_unlock(&smack_known_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) static const struct file_operations smk_mapped_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 	.read		= smk_read_mapped,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) 	.write		= smk_write_mapped,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) 	.llseek		= default_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784)  * smk_read_ambient - read() for /smack/ambient
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785)  * @filp: file pointer, not actually used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786)  * @buf: where to put the result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787)  * @cn: maximum to send along
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788)  * @ppos: where to start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790)  * Returns number of bytes read or error code, as appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) static ssize_t smk_read_ambient(struct file *filp, char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) 				size_t cn, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) 	ssize_t rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) 	int asize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) 	if (*ppos != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) 	 * Being careful to avoid a problem in the case where
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) 	 * smack_net_ambient gets changed in midstream.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) 	mutex_lock(&smack_ambient_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) 	asize = strlen(smack_net_ambient->smk_known) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) 	if (cn >= asize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) 		rc = simple_read_from_buffer(buf, cn, ppos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) 					     smack_net_ambient->smk_known,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) 					     asize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 		rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) 	mutex_unlock(&smack_ambient_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821)  * smk_write_ambient - write() for /smack/ambient
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822)  * @file: file pointer, not actually used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823)  * @buf: where to get the data from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824)  * @count: bytes sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825)  * @ppos: where to start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827)  * Returns number of bytes written or error code, as appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) static ssize_t smk_write_ambient(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) 				 size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) 	struct smack_known *skp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) 	char *oldambient;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) 	char *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) 	int rc = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) 	if (!smack_privileged(CAP_MAC_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) 	/* Enough data must be present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) 	if (count == 0 || count > PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) 	data = memdup_user_nul(buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) 	if (IS_ERR(data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) 		return PTR_ERR(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) 	skp = smk_import_entry(data, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) 	if (IS_ERR(skp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) 		rc = PTR_ERR(skp);
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) 	mutex_lock(&smack_ambient_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) 	oldambient = smack_net_ambient->smk_known;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) 	smack_net_ambient = skp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) 	smk_unlbl_ambient(oldambient);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) 	mutex_unlock(&smack_ambient_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) 	kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) 	return rc;
^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 file_operations smk_ambient_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) 	.read		= smk_read_ambient,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) 	.write		= smk_write_ambient,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) 	.llseek		= default_llseek,
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874)  * Seq_file operations for /smack/onlycap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) static void *onlycap_seq_start(struct seq_file *s, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) 	return smk_seq_start(s, pos, &smack_onlycap_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) static void *onlycap_seq_next(struct seq_file *s, void *v, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) 	return smk_seq_next(s, v, pos, &smack_onlycap_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) static int onlycap_seq_show(struct seq_file *s, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) 	struct list_head *list = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) 	struct smack_known_list_elem *sklep =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) 		list_entry_rcu(list, struct smack_known_list_elem, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) 	seq_puts(s, sklep->smk_label->smk_known);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) 	seq_putc(s, ' ');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) static const struct seq_operations onlycap_seq_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) 	.start = onlycap_seq_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) 	.next  = onlycap_seq_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) 	.show  = onlycap_seq_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) 	.stop  = smk_seq_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) static int smk_open_onlycap(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) 	return seq_open(file, &onlycap_seq_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911)  * smk_list_swap_rcu - swap public list with a private one in RCU-safe way
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912)  * The caller must hold appropriate mutex to prevent concurrent modifications
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913)  * to the public list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914)  * Private list is assumed to be not accessible to other threads yet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916)  * @public: public list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917)  * @private: private list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) static void smk_list_swap_rcu(struct list_head *public,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) 			      struct list_head *private)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) 	struct list_head *first, *last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) 	if (list_empty(public)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) 		list_splice_init_rcu(private, public, synchronize_rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) 		/* Remember public list before replacing it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) 		first = public->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) 		last = public->prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) 		/* Publish private list in place of public in RCU-safe way */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) 		private->prev->next = public;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) 		private->next->prev = public;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) 		rcu_assign_pointer(public->next, private->next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) 		public->prev = private->prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) 		synchronize_rcu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) 		/* When all readers are done with the old public list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) 		 * attach it in place of private */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) 		private->next = first;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) 		private->prev = last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) 		first->prev = private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) 		last->next = private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949)  * smk_parse_label_list - parse list of Smack labels, separated by spaces
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951)  * @data: the string to parse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952)  * @private: destination list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954)  * Returns zero on success or error code, as appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) static int smk_parse_label_list(char *data, struct list_head *list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) 	char *tok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) 	struct smack_known *skp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) 	struct smack_known_list_elem *sklep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) 	while ((tok = strsep(&data, " ")) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) 		if (!*tok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) 		skp = smk_import_entry(tok, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) 		if (IS_ERR(skp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) 			return PTR_ERR(skp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) 		sklep = kzalloc(sizeof(*sklep), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) 		if (sklep == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) 		sklep->smk_label = skp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) 		list_add(&sklep->list, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982)  * smk_destroy_label_list - destroy a list of smack_known_list_elem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983)  * @head: header pointer of the list to destroy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) void smk_destroy_label_list(struct list_head *list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) 	struct smack_known_list_elem *sklep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) 	struct smack_known_list_elem *sklep2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) 	list_for_each_entry_safe(sklep, sklep2, list, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) 		kfree(sklep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) 	INIT_LIST_HEAD(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997)  * smk_write_onlycap - write() for smackfs/onlycap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998)  * @file: file pointer, not actually used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999)  * @buf: where to get the data from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000)  * @count: bytes sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001)  * @ppos: where to start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003)  * Returns number of bytes written or error code, as appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) 				 size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) 	char *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) 	LIST_HEAD(list_tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) 	if (!smack_privileged(CAP_MAC_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) 	if (count > PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) 	data = memdup_user_nul(buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) 	if (IS_ERR(data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) 		return PTR_ERR(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) 	rc = smk_parse_label_list(data, &list_tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) 	kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) 	 * Clear the smack_onlycap on invalid label errors. This means
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) 	 * that we can pass a null string to unset the onlycap value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) 	 * Importing will also reject a label beginning with '-',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) 	 * so "-usecapabilities" will also work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) 	 * But do so only on invalid label, not on system errors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) 	 * The invalid label must be first to count as clearing attempt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) 	if (!rc || (rc == -EINVAL && list_empty(&list_tmp))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) 		mutex_lock(&smack_onlycap_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) 		smk_list_swap_rcu(&smack_onlycap_list, &list_tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) 		mutex_unlock(&smack_onlycap_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) 		rc = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) 	smk_destroy_label_list(&list_tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) static const struct file_operations smk_onlycap_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) 	.open		= smk_open_onlycap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) 	.read		= seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) 	.write		= smk_write_onlycap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) 	.llseek		= seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) 	.release	= seq_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) #ifdef CONFIG_SECURITY_SMACK_BRINGUP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057)  * smk_read_unconfined - read() for smackfs/unconfined
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058)  * @filp: file pointer, not actually used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059)  * @buf: where to put the result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060)  * @cn: maximum to send along
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061)  * @ppos: where to start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063)  * Returns number of bytes read or error code, as appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) static ssize_t smk_read_unconfined(struct file *filp, char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) 					size_t cn, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) 	char *smack = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) 	ssize_t rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) 	int asize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) 	if (*ppos != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) 	if (smack_unconfined != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) 		smack = smack_unconfined->smk_known;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) 	asize = strlen(smack) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) 	if (cn >= asize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) 		rc = simple_read_from_buffer(buf, cn, ppos, smack, asize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087)  * smk_write_unconfined - write() for smackfs/unconfined
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088)  * @file: file pointer, not actually used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089)  * @buf: where to get the data from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090)  * @count: bytes sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091)  * @ppos: where to start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093)  * Returns number of bytes written or error code, as appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) static ssize_t smk_write_unconfined(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) 					size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) 	char *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) 	struct smack_known *skp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) 	int rc = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) 	if (!smack_privileged(CAP_MAC_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) 	if (count > PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) 	data = memdup_user_nul(buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) 	if (IS_ERR(data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) 		return PTR_ERR(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) 	 * Clear the smack_unconfined on invalid label errors. This means
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) 	 * that we can pass a null string to unset the unconfined value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) 	 * Importing will also reject a label beginning with '-',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) 	 * so "-confine" will also work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) 	 * But do so only on invalid label, not on system errors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) 	skp = smk_import_entry(data, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) 	if (PTR_ERR(skp) == -EINVAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) 		skp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) 	else if (IS_ERR(skp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) 		rc = PTR_ERR(skp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) 		goto freeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) 	smack_unconfined = skp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) freeout:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) 	kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) static const struct file_operations smk_unconfined_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) 	.read		= smk_read_unconfined,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) 	.write		= smk_write_unconfined,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) 	.llseek		= default_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) #endif /* CONFIG_SECURITY_SMACK_BRINGUP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144)  * smk_read_logging - read() for /smack/logging
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145)  * @filp: file pointer, not actually used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146)  * @buf: where to put the result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147)  * @cn: maximum to send along
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148)  * @ppos: where to start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150)  * Returns number of bytes read or error code, as appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) static ssize_t smk_read_logging(struct file *filp, char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) 				size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) 	char temp[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) 	ssize_t rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) 	if (*ppos != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) 	sprintf(temp, "%d\n", log_policy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) 	rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167)  * smk_write_logging - write() for /smack/logging
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168)  * @file: file pointer, not actually used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169)  * @buf: where to get the data from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170)  * @count: bytes sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171)  * @ppos: where to start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173)  * Returns number of bytes written or error code, as appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) static ssize_t smk_write_logging(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) 				size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) 	char temp[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) 	if (!smack_privileged(CAP_MAC_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) 	if (count >= sizeof(temp) || count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) 	if (copy_from_user(temp, buf, count) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) 	temp[count] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) 	if (sscanf(temp, "%d", &i) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) 	if (i < 0 || i > 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) 	log_policy = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) static const struct file_operations smk_logging_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) 	.read		= smk_read_logging,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) 	.write		= smk_write_logging,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) 	.llseek		= default_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209)  * Seq_file read operations for /smack/load-self
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) static void *load_self_seq_start(struct seq_file *s, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) 	struct task_smack *tsp = smack_cred(current_cred());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) 	return smk_seq_start(s, pos, &tsp->smk_rules);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) static void *load_self_seq_next(struct seq_file *s, void *v, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) 	struct task_smack *tsp = smack_cred(current_cred());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) 	return smk_seq_next(s, v, pos, &tsp->smk_rules);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) static int load_self_seq_show(struct seq_file *s, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) 	struct list_head *list = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) 	struct smack_rule *srp =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) 		list_entry_rcu(list, struct smack_rule, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) 	smk_rule_show(s, srp, SMK_LABELLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) static const struct seq_operations load_self_seq_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) 	.start = load_self_seq_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) 	.next  = load_self_seq_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) 	.show  = load_self_seq_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) 	.stop  = smk_seq_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246)  * smk_open_load_self - open() for /smack/load-self2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247)  * @inode: inode structure representing file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248)  * @file: "load" file pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250)  * For reading, use load_seq_* seq_file reading operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) static int smk_open_load_self(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) 	return seq_open(file, &load_self_seq_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258)  * smk_write_load_self - write() for /smack/load-self
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259)  * @file: file pointer, not actually used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260)  * @buf: where to get the data from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261)  * @count: bytes sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262)  * @ppos: where to start - must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) static ssize_t smk_write_load_self(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) 			      size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) 	struct task_smack *tsp = smack_cred(current_cred());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) 	return smk_write_rules_list(file, buf, count, ppos, &tsp->smk_rules,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) 				    &tsp->smk_rules_lock, SMK_FIXED24_FMT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) static const struct file_operations smk_load_self_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) 	.open           = smk_open_load_self,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) 	.read		= seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) 	.llseek         = seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) 	.write		= smk_write_load_self,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) 	.release        = seq_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283)  * smk_user_access - handle access check transaction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284)  * @file: file pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285)  * @buf: data from user space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286)  * @count: bytes sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287)  * @ppos: where to start - must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) static ssize_t smk_user_access(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) 				size_t count, loff_t *ppos, int format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) 	struct smack_parsed_rule rule;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) 	char *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) 	int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) 	data = simple_transaction_get(file, buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) 	if (IS_ERR(data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) 		return PTR_ERR(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) 	if (format == SMK_FIXED24_FMT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) 		if (count < SMK_LOADLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) 		res = smk_parse_rule(data, &rule, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) 		 * simple_transaction_get() returns null-terminated data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) 		res = smk_parse_long_rule(data, &rule, 0, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) 	if (res >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) 		res = smk_access(rule.smk_subject, rule.smk_object,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) 				 rule.smk_access1, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) 	else if (res != -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) 		return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) 	 * smk_access() can return a value > 0 in the "bringup" case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) 	data[0] = res >= 0 ? '1' : '0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) 	data[1] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) 	simple_transaction_set(file, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) 	if (format == SMK_FIXED24_FMT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) 		return SMK_LOADLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) }
^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)  * smk_write_access - handle access check transaction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332)  * @file: file pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333)  * @buf: data from user space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334)  * @count: bytes sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335)  * @ppos: where to start - must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) static ssize_t smk_write_access(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) 				size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) 	return smk_user_access(file, buf, count, ppos, SMK_FIXED24_FMT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) static const struct file_operations smk_access_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) 	.write		= smk_write_access,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) 	.read		= simple_transaction_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) 	.release	= simple_transaction_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) 	.llseek		= generic_file_llseek,
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352)  * Seq_file read operations for /smack/load2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) static int load2_seq_show(struct seq_file *s, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) 	struct list_head *list = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) 	struct smack_rule *srp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) 	struct smack_known *skp =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) 		list_entry_rcu(list, struct smack_known, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) 	list_for_each_entry_rcu(srp, &skp->smk_rules, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) 		smk_rule_show(s, srp, SMK_LONGLABEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) static const struct seq_operations load2_seq_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) 	.start = load2_seq_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) 	.next  = load2_seq_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) 	.show  = load2_seq_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) 	.stop  = smk_seq_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376)  * smk_open_load2 - open() for /smack/load2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377)  * @inode: inode structure representing file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378)  * @file: "load2" file pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380)  * For reading, use load2_seq_* seq_file reading operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) static int smk_open_load2(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) 	return seq_open(file, &load2_seq_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) }
^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)  * smk_write_load2 - write() for /smack/load2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389)  * @file: file pointer, not actually used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390)  * @buf: where to get the data from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391)  * @count: bytes sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392)  * @ppos: where to start - must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) static ssize_t smk_write_load2(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) 				size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) 	 * Must have privilege.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) 	if (!smack_privileged(CAP_MAC_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) 	return smk_write_rules_list(file, buf, count, ppos, NULL, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) 				    SMK_LONG_FMT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) static const struct file_operations smk_load2_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) 	.open           = smk_open_load2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) 	.read		= seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) 	.llseek         = seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) 	.write		= smk_write_load2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) 	.release        = seq_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417)  * Seq_file read operations for /smack/load-self2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) static void *load_self2_seq_start(struct seq_file *s, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) 	struct task_smack *tsp = smack_cred(current_cred());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) 	return smk_seq_start(s, pos, &tsp->smk_rules);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) static void *load_self2_seq_next(struct seq_file *s, void *v, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) 	struct task_smack *tsp = smack_cred(current_cred());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) 	return smk_seq_next(s, v, pos, &tsp->smk_rules);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) static int load_self2_seq_show(struct seq_file *s, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) 	struct list_head *list = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) 	struct smack_rule *srp =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) 		list_entry_rcu(list, struct smack_rule, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) 	smk_rule_show(s, srp, SMK_LONGLABEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) static const struct seq_operations load_self2_seq_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) 	.start = load_self2_seq_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) 	.next  = load_self2_seq_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) 	.show  = load_self2_seq_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) 	.stop  = smk_seq_stop,
^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)  * smk_open_load_self2 - open() for /smack/load-self2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454)  * @inode: inode structure representing file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455)  * @file: "load" file pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457)  * For reading, use load_seq_* seq_file reading operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) static int smk_open_load_self2(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) 	return seq_open(file, &load_self2_seq_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) }
^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)  * smk_write_load_self2 - write() for /smack/load-self2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466)  * @file: file pointer, not actually used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467)  * @buf: where to get the data from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468)  * @count: bytes sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469)  * @ppos: where to start - must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) static ssize_t smk_write_load_self2(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) 			      size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) 	struct task_smack *tsp = smack_cred(current_cred());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) 	return smk_write_rules_list(file, buf, count, ppos, &tsp->smk_rules,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) 				    &tsp->smk_rules_lock, SMK_LONG_FMT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) static const struct file_operations smk_load_self2_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) 	.open           = smk_open_load_self2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) 	.read		= seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) 	.llseek         = seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) 	.write		= smk_write_load_self2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) 	.release        = seq_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490)  * smk_write_access2 - handle access check transaction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491)  * @file: file pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492)  * @buf: data from user space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493)  * @count: bytes sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494)  * @ppos: where to start - must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) static ssize_t smk_write_access2(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) 					size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) 	return smk_user_access(file, buf, count, ppos, SMK_LONG_FMT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) static const struct file_operations smk_access2_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) 	.write		= smk_write_access2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) 	.read		= simple_transaction_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) 	.release	= simple_transaction_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) 	.llseek		= generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510)  * smk_write_revoke_subj - write() for /smack/revoke-subject
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511)  * @file: file pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512)  * @buf: data from user space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513)  * @count: bytes sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514)  * @ppos: where to start - must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) static ssize_t smk_write_revoke_subj(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) 				size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) 	char *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) 	const char *cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) 	struct smack_known *skp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) 	struct smack_rule *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) 	struct list_head *rule_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) 	struct mutex *rule_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) 	int rc = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) 	if (*ppos != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) 	if (!smack_privileged(CAP_MAC_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) 	if (count == 0 || count > SMK_LONGLABEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) 	data = memdup_user(buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) 	if (IS_ERR(data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) 		return PTR_ERR(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) 	cp = smk_parse_smack(data, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) 	if (IS_ERR(cp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) 		rc = PTR_ERR(cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) 		goto out_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) 	skp = smk_find_entry(cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) 	if (skp == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) 		goto out_cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) 	rule_list = &skp->smk_rules;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) 	rule_lock = &skp->smk_rules_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) 	mutex_lock(rule_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) 	list_for_each_entry_rcu(sp, rule_list, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) 		sp->smk_access = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) 	mutex_unlock(rule_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) out_cp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) 	kfree(cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) out_data:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) 	kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) static const struct file_operations smk_revoke_subj_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) 	.write		= smk_write_revoke_subj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) 	.read		= simple_transaction_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) 	.release	= simple_transaction_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) 	.llseek		= generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576)  * smk_init_sysfs - initialize /sys/fs/smackfs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) static int smk_init_sysfs(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) 	return sysfs_create_mount_point(fs_kobj, "smackfs");
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585)  * smk_write_change_rule - write() for /smack/change-rule
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586)  * @file: file pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587)  * @buf: data from user space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588)  * @count: bytes sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589)  * @ppos: where to start - must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) static ssize_t smk_write_change_rule(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) 				size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) 	 * Must have privilege.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) 	if (!smack_privileged(CAP_MAC_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) 	return smk_write_rules_list(file, buf, count, ppos, NULL, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) 				    SMK_CHANGE_FMT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) static const struct file_operations smk_change_rule_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) 	.write		= smk_write_change_rule,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) 	.read		= simple_transaction_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) 	.release	= simple_transaction_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) 	.llseek		= generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612)  * smk_read_syslog - read() for smackfs/syslog
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613)  * @filp: file pointer, not actually used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614)  * @buf: where to put the result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615)  * @cn: maximum to send along
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616)  * @ppos: where to start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618)  * Returns number of bytes read or error code, as appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) static ssize_t smk_read_syslog(struct file *filp, char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) 				size_t cn, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) 	struct smack_known *skp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) 	ssize_t rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) 	int asize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) 	if (*ppos != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) 	if (smack_syslog_label == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) 		skp = &smack_known_star;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) 		skp = smack_syslog_label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) 	asize = strlen(skp->smk_known) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) 	if (cn >= asize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) 		rc = simple_read_from_buffer(buf, cn, ppos, skp->smk_known,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) 						asize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645)  * smk_write_syslog - write() for smackfs/syslog
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646)  * @file: file pointer, not actually used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647)  * @buf: where to get the data from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648)  * @count: bytes sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649)  * @ppos: where to start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651)  * Returns number of bytes written or error code, as appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) static ssize_t smk_write_syslog(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) 				size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) 	char *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) 	struct smack_known *skp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) 	int rc = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) 	if (!smack_privileged(CAP_MAC_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) 	/* Enough data must be present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) 	if (count == 0 || count > PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) 	data = memdup_user_nul(buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) 	if (IS_ERR(data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) 		return PTR_ERR(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) 	skp = smk_import_entry(data, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) 	if (IS_ERR(skp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) 		rc = PTR_ERR(skp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) 		smack_syslog_label = skp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) 	kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) static const struct file_operations smk_syslog_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) 	.read		= smk_read_syslog,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) 	.write		= smk_write_syslog,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) 	.llseek		= default_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688)  * Seq_file read operations for /smack/relabel-self
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) static void *relabel_self_seq_start(struct seq_file *s, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) 	struct task_smack *tsp = smack_cred(current_cred());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) 	return smk_seq_start(s, pos, &tsp->smk_relabel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) static void *relabel_self_seq_next(struct seq_file *s, void *v, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) 	struct task_smack *tsp = smack_cred(current_cred());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) 	return smk_seq_next(s, v, pos, &tsp->smk_relabel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) static int relabel_self_seq_show(struct seq_file *s, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) 	struct list_head *list = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) 	struct smack_known_list_elem *sklep =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) 		list_entry(list, struct smack_known_list_elem, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) 	seq_puts(s, sklep->smk_label->smk_known);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) 	seq_putc(s, ' ');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) static const struct seq_operations relabel_self_seq_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) 	.start = relabel_self_seq_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) 	.next  = relabel_self_seq_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) 	.show  = relabel_self_seq_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) 	.stop  = smk_seq_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725)  * smk_open_relabel_self - open() for /smack/relabel-self
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726)  * @inode: inode structure representing file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727)  * @file: "relabel-self" file pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729)  * Connect our relabel_self_seq_* operations with /smack/relabel-self
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730)  * file_operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) static int smk_open_relabel_self(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) 	return seq_open(file, &relabel_self_seq_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738)  * smk_write_relabel_self - write() for /smack/relabel-self
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739)  * @file: file pointer, not actually used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740)  * @buf: where to get the data from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741)  * @count: bytes sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742)  * @ppos: where to start - must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) static ssize_t smk_write_relabel_self(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) 				size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) 	char *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) 	LIST_HEAD(list_tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) 	 * Must have privilege.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) 	if (!smack_privileged(CAP_MAC_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) 	 * No partial write.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) 	 * Enough data must be present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) 	if (*ppos != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) 	if (count == 0 || count > PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) 	data = memdup_user_nul(buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) 	if (IS_ERR(data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) 		return PTR_ERR(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) 	rc = smk_parse_label_list(data, &list_tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) 	kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) 	if (!rc || (rc == -EINVAL && list_empty(&list_tmp))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) 		struct cred *new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) 		struct task_smack *tsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) 		new = prepare_creds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) 		if (!new) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) 			rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) 		tsp = smack_cred(new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) 		smk_destroy_label_list(&tsp->smk_relabel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) 		list_splice(&list_tmp, &tsp->smk_relabel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) 		commit_creds(new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) 		return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) 	smk_destroy_label_list(&list_tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) static const struct file_operations smk_relabel_self_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) 	.open		= smk_open_relabel_self,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) 	.read		= seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) 	.llseek		= seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) 	.write		= smk_write_relabel_self,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) 	.release	= seq_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803)  * smk_read_ptrace - read() for /smack/ptrace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804)  * @filp: file pointer, not actually used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805)  * @buf: where to put the result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806)  * @count: maximum to send along
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807)  * @ppos: where to start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809)  * Returns number of bytes read or error code, as appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) static ssize_t smk_read_ptrace(struct file *filp, char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) 			       size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) 	char temp[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) 	ssize_t rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) 	if (*ppos != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) 	sprintf(temp, "%d\n", smack_ptrace_rule);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) 	rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826)  * smk_write_ptrace - write() for /smack/ptrace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827)  * @file: file pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828)  * @buf: data from user space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829)  * @count: bytes sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830)  * @ppos: where to start - must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) static ssize_t smk_write_ptrace(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) 				size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) 	char temp[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) 	if (!smack_privileged(CAP_MAC_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) 	if (*ppos != 0 || count >= sizeof(temp) || count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) 	if (copy_from_user(temp, buf, count) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) 	temp[count] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) 	if (sscanf(temp, "%d", &i) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) 	if (i < SMACK_PTRACE_DEFAULT || i > SMACK_PTRACE_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) 	smack_ptrace_rule = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) static const struct file_operations smk_ptrace_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) 	.write		= smk_write_ptrace,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) 	.read		= smk_read_ptrace,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) 	.llseek		= default_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865)  * smk_fill_super - fill the smackfs superblock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866)  * @sb: the empty superblock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867)  * @fc: unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869)  * Fill in the well known entries for the smack filesystem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871)  * Returns 0 on success, an error code on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) static int smk_fill_super(struct super_block *sb, struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) 	static const struct tree_descr smack_files[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) 		[SMK_LOAD] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) 			"load", &smk_load_ops, S_IRUGO|S_IWUSR},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) 		[SMK_CIPSO] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) 			"cipso", &smk_cipso_ops, S_IRUGO|S_IWUSR},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) 		[SMK_DOI] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) 			"doi", &smk_doi_ops, S_IRUGO|S_IWUSR},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) 		[SMK_DIRECT] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) 			"direct", &smk_direct_ops, S_IRUGO|S_IWUSR},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) 		[SMK_AMBIENT] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) 			"ambient", &smk_ambient_ops, S_IRUGO|S_IWUSR},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) 		[SMK_NET4ADDR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) 			"netlabel", &smk_net4addr_ops, S_IRUGO|S_IWUSR},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) 		[SMK_ONLYCAP] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) 			"onlycap", &smk_onlycap_ops, S_IRUGO|S_IWUSR},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) 		[SMK_LOGGING] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) 			"logging", &smk_logging_ops, S_IRUGO|S_IWUSR},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) 		[SMK_LOAD_SELF] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) 			"load-self", &smk_load_self_ops, S_IRUGO|S_IWUGO},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) 		[SMK_ACCESSES] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) 			"access", &smk_access_ops, S_IRUGO|S_IWUGO},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) 		[SMK_MAPPED] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) 			"mapped", &smk_mapped_ops, S_IRUGO|S_IWUSR},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) 		[SMK_LOAD2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) 			"load2", &smk_load2_ops, S_IRUGO|S_IWUSR},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) 		[SMK_LOAD_SELF2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) 			"load-self2", &smk_load_self2_ops, S_IRUGO|S_IWUGO},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) 		[SMK_ACCESS2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) 			"access2", &smk_access2_ops, S_IRUGO|S_IWUGO},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) 		[SMK_CIPSO2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) 			"cipso2", &smk_cipso2_ops, S_IRUGO|S_IWUSR},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) 		[SMK_REVOKE_SUBJ] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) 			"revoke-subject", &smk_revoke_subj_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) 			S_IRUGO|S_IWUSR},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) 		[SMK_CHANGE_RULE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) 			"change-rule", &smk_change_rule_ops, S_IRUGO|S_IWUSR},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) 		[SMK_SYSLOG] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) 			"syslog", &smk_syslog_ops, S_IRUGO|S_IWUSR},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) 		[SMK_PTRACE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) 			"ptrace", &smk_ptrace_ops, S_IRUGO|S_IWUSR},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) #ifdef CONFIG_SECURITY_SMACK_BRINGUP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) 		[SMK_UNCONFINED] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) 			"unconfined", &smk_unconfined_ops, S_IRUGO|S_IWUSR},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) 		[SMK_NET6ADDR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) 			"ipv6host", &smk_net6addr_ops, S_IRUGO|S_IWUSR},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) #endif /* CONFIG_IPV6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) 		[SMK_RELABEL_SELF] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) 			"relabel-self", &smk_relabel_self_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) 				S_IRUGO|S_IWUGO},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) 		/* last one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) 			{""}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) 	rc = simple_fill_super(sb, SMACK_MAGIC, smack_files);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) 	if (rc != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) 		printk(KERN_ERR "%s failed %d while creating inodes\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) 			__func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943)  * smk_get_tree - get the smackfs superblock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944)  * @fc: The mount context, including any options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946)  * Just passes everything along.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948)  * Returns what the lower level code does.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) static int smk_get_tree(struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) 	return get_tree_single(fc, smk_fill_super);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) static const struct fs_context_operations smk_context_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) 	.get_tree	= smk_get_tree,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960)  * smk_init_fs_context - Initialise a filesystem context for smackfs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961)  * @fc: The blank mount context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) static int smk_init_fs_context(struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) 	fc->ops = &smk_context_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) static struct file_system_type smk_fs_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) 	.name		= "smackfs",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) 	.init_fs_context = smk_init_fs_context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) 	.kill_sb	= kill_litter_super,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) static struct vfsmount *smackfs_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978)  * init_smk_fs - get the smackfs superblock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980)  * register the smackfs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982)  * Do not register smackfs if Smack wasn't enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983)  * on boot. We can not put this method normally under the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984)  * smack_init() code path since the security subsystem get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985)  * initialized before the vfs caches.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987)  * Returns true if we were not chosen on boot or if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988)  * we were chosen and filesystem registration succeeded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) static int __init init_smk_fs(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) 	if (smack_enabled == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) 	err = smk_init_sysfs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) 		printk(KERN_ERR "smackfs: sysfs mountpoint problem.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) 	err = register_filesystem(&smk_fs_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) 	if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) 		smackfs_mount = kern_mount(&smk_fs_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) 		if (IS_ERR(smackfs_mount)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) 			printk(KERN_ERR "smackfs:  could not mount!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) 			err = PTR_ERR(smackfs_mount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) 			smackfs_mount = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) 	smk_cipso_doi();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) 	smk_unlbl_ambient(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) 	rc = smack_populate_secattr(&smack_known_floor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) 	if (err == 0 && rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) 		err = rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) 	rc = smack_populate_secattr(&smack_known_hat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) 	if (err == 0 && rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) 		err = rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) 	rc = smack_populate_secattr(&smack_known_huh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) 	if (err == 0 && rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) 		err = rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) 	rc = smack_populate_secattr(&smack_known_star);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) 	if (err == 0 && rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) 		err = rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) 	rc = smack_populate_secattr(&smack_known_web);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) 	if (err == 0 && rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) 		err = rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) __initcall(init_smk_fs);