^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);