Orange Pi5 kernel

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

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * Implementation of the kernel access vector cache (AVC).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * Authors:  Stephen Smalley, <sds@tycho.nsa.gov>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  *	     James Morris <jmorris@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  * Update:   KaiGai, Kohei <kaigai@ak.jp.nec.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  *	Replaced the avc_lock spinlock by RCU.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include <linux/stddef.h>
^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/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <linux/dcache.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <linux/percpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <net/sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include <linux/un.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include <net/af_unix.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include <linux/ip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #include <linux/audit.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #include <linux/ipv6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #include <net/ipv6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #include "avc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #include "avc_ss.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #include "classmap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #define CREATE_TRACE_POINTS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #include <trace/events/avc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #define AVC_CACHE_SLOTS			512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) #define AVC_DEF_CACHE_THRESHOLD		512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #define AVC_CACHE_RECLAIM		16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) #ifdef CONFIG_SECURITY_SELINUX_AVC_STATS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) #define avc_cache_stats_incr(field)	this_cpu_inc(avc_cache_stats.field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) #define avc_cache_stats_incr(field)	do {} while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) #undef CREATE_TRACE_POINTS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) #include <trace/hooks/avc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) struct avc_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 	u32			ssid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 	u32			tsid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 	u16			tclass;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 	struct av_decision	avd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 	struct avc_xperms_node	*xp_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) struct avc_node {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 	struct avc_entry	ae;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 	struct hlist_node	list; /* anchored in avc_cache->slots[i] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 	struct rcu_head		rhead;
^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) struct avc_xperms_decision_node {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 	struct extended_perms_decision xpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 	struct list_head xpd_list; /* list of extended_perms_decision */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) struct avc_xperms_node {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 	struct extended_perms xp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 	struct list_head xpd_head; /* list head of extended_perms_decision */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) struct avc_cache {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 	struct hlist_head	slots[AVC_CACHE_SLOTS]; /* head for avc_node->list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 	spinlock_t		slots_lock[AVC_CACHE_SLOTS]; /* lock for writes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 	atomic_t		lru_hint;	/* LRU hint for reclaim scan */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 	atomic_t		active_nodes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 	u32			latest_notif;	/* latest revocation notification */
^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) struct avc_callback_node {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 	int (*callback) (u32 event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 	u32 events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 	struct avc_callback_node *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) #ifdef CONFIG_SECURITY_SELINUX_AVC_STATS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) DEFINE_PER_CPU(struct avc_cache_stats, avc_cache_stats) = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) struct selinux_avc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 	unsigned int avc_cache_threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 	struct avc_cache avc_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) static struct selinux_avc selinux_avc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) void selinux_avc_init(struct selinux_avc **avc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 	selinux_avc.avc_cache_threshold = AVC_DEF_CACHE_THRESHOLD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 	for (i = 0; i < AVC_CACHE_SLOTS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 		INIT_HLIST_HEAD(&selinux_avc.avc_cache.slots[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 		spin_lock_init(&selinux_avc.avc_cache.slots_lock[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	atomic_set(&selinux_avc.avc_cache.active_nodes, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 	atomic_set(&selinux_avc.avc_cache.lru_hint, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 	*avc = &selinux_avc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) unsigned int avc_get_cache_threshold(struct selinux_avc *avc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	return avc->avc_cache_threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) void avc_set_cache_threshold(struct selinux_avc *avc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 			     unsigned int cache_threshold)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 	avc->avc_cache_threshold = cache_threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) static struct avc_callback_node *avc_callbacks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) static struct kmem_cache *avc_node_cachep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) static struct kmem_cache *avc_xperms_data_cachep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) static struct kmem_cache *avc_xperms_decision_cachep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) static struct kmem_cache *avc_xperms_cachep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) static inline int avc_hash(u32 ssid, u32 tsid, u16 tclass)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	return (ssid ^ (tsid<<2) ^ (tclass<<4)) & (AVC_CACHE_SLOTS - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136)  * avc_init - Initialize the AVC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138)  * Initialize the access vector cache.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) void __init avc_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 	avc_node_cachep = kmem_cache_create("avc_node", sizeof(struct avc_node),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 					0, SLAB_PANIC, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	avc_xperms_cachep = kmem_cache_create("avc_xperms_node",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 					sizeof(struct avc_xperms_node),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 					0, SLAB_PANIC, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 	avc_xperms_decision_cachep = kmem_cache_create(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 					"avc_xperms_decision_node",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 					sizeof(struct avc_xperms_decision_node),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 					0, SLAB_PANIC, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 	avc_xperms_data_cachep = kmem_cache_create("avc_xperms_data",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 					sizeof(struct extended_perms_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 					0, SLAB_PANIC, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) int avc_get_hash_stats(struct selinux_avc *avc, char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 	int i, chain_len, max_chain_len, slots_used;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	struct avc_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	slots_used = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 	max_chain_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 	for (i = 0; i < AVC_CACHE_SLOTS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 		head = &avc->avc_cache.slots[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 		if (!hlist_empty(head)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 			slots_used++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 			chain_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 			hlist_for_each_entry_rcu(node, head, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 				chain_len++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 			if (chain_len > max_chain_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 				max_chain_len = chain_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 		}
^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) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	return scnprintf(page, PAGE_SIZE, "entries: %d\nbuckets used: %d/%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 			 "longest chain: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 			 atomic_read(&avc->avc_cache.active_nodes),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 			 slots_used, AVC_CACHE_SLOTS, max_chain_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187)  * using a linked list for extended_perms_decision lookup because the list is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188)  * always small. i.e. less than 5, typically 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) static struct extended_perms_decision *avc_xperms_decision_lookup(u8 driver,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 					struct avc_xperms_node *xp_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	struct avc_xperms_decision_node *xpd_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	list_for_each_entry(xpd_node, &xp_node->xpd_head, xpd_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 		if (xpd_node->xpd.driver == driver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 			return &xpd_node->xpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) static inline unsigned int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) avc_xperms_has_perm(struct extended_perms_decision *xpd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 					u8 perm, u8 which)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	unsigned int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	if ((which == XPERMS_ALLOWED) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 			(xpd->used & XPERMS_ALLOWED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 		rc = security_xperm_test(xpd->allowed->p, perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	else if ((which == XPERMS_AUDITALLOW) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 			(xpd->used & XPERMS_AUDITALLOW))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 		rc = security_xperm_test(xpd->auditallow->p, perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	else if ((which == XPERMS_DONTAUDIT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 			(xpd->used & XPERMS_DONTAUDIT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 		rc = security_xperm_test(xpd->dontaudit->p, perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) static void avc_xperms_allow_perm(struct avc_xperms_node *xp_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 				u8 driver, u8 perm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	struct extended_perms_decision *xpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	security_xperm_set(xp_node->xp.drivers.p, driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	xpd = avc_xperms_decision_lookup(driver, xp_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	if (xpd && xpd->allowed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 		security_xperm_set(xpd->allowed->p, perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) static void avc_xperms_decision_free(struct avc_xperms_decision_node *xpd_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	struct extended_perms_decision *xpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 	xpd = &xpd_node->xpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	if (xpd->allowed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 		kmem_cache_free(avc_xperms_data_cachep, xpd->allowed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 	if (xpd->auditallow)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 		kmem_cache_free(avc_xperms_data_cachep, xpd->auditallow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	if (xpd->dontaudit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 		kmem_cache_free(avc_xperms_data_cachep, xpd->dontaudit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	kmem_cache_free(avc_xperms_decision_cachep, xpd_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) static void avc_xperms_free(struct avc_xperms_node *xp_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	struct avc_xperms_decision_node *xpd_node, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 	if (!xp_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	list_for_each_entry_safe(xpd_node, tmp, &xp_node->xpd_head, xpd_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 		list_del(&xpd_node->xpd_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 		avc_xperms_decision_free(xpd_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	kmem_cache_free(avc_xperms_cachep, xp_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) static void avc_copy_xperms_decision(struct extended_perms_decision *dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 					struct extended_perms_decision *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 	dest->driver = src->driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 	dest->used = src->used;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 	if (dest->used & XPERMS_ALLOWED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 		memcpy(dest->allowed->p, src->allowed->p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 				sizeof(src->allowed->p));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 	if (dest->used & XPERMS_AUDITALLOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 		memcpy(dest->auditallow->p, src->auditallow->p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 				sizeof(src->auditallow->p));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	if (dest->used & XPERMS_DONTAUDIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 		memcpy(dest->dontaudit->p, src->dontaudit->p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 				sizeof(src->dontaudit->p));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275)  * similar to avc_copy_xperms_decision, but only copy decision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276)  * information relevant to this perm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) static inline void avc_quick_copy_xperms_decision(u8 perm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 			struct extended_perms_decision *dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 			struct extended_perms_decision *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	 * compute index of the u32 of the 256 bits (8 u32s) that contain this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 	 * command permission
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	u8 i = perm >> 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 	dest->used = src->used;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 	if (dest->used & XPERMS_ALLOWED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 		dest->allowed->p[i] = src->allowed->p[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 	if (dest->used & XPERMS_AUDITALLOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 		dest->auditallow->p[i] = src->auditallow->p[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 	if (dest->used & XPERMS_DONTAUDIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 		dest->dontaudit->p[i] = src->dontaudit->p[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) static struct avc_xperms_decision_node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 		*avc_xperms_decision_alloc(u8 which)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 	struct avc_xperms_decision_node *xpd_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	struct extended_perms_decision *xpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	xpd_node = kmem_cache_zalloc(avc_xperms_decision_cachep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 				     GFP_NOWAIT | __GFP_NOWARN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	if (!xpd_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	xpd = &xpd_node->xpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	if (which & XPERMS_ALLOWED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 		xpd->allowed = kmem_cache_zalloc(avc_xperms_data_cachep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 						GFP_NOWAIT | __GFP_NOWARN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 		if (!xpd->allowed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 	if (which & XPERMS_AUDITALLOW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 		xpd->auditallow = kmem_cache_zalloc(avc_xperms_data_cachep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 						GFP_NOWAIT | __GFP_NOWARN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 		if (!xpd->auditallow)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 	if (which & XPERMS_DONTAUDIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 		xpd->dontaudit = kmem_cache_zalloc(avc_xperms_data_cachep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 						GFP_NOWAIT | __GFP_NOWARN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 		if (!xpd->dontaudit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	return xpd_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	avc_xperms_decision_free(xpd_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) static int avc_add_xperms_decision(struct avc_node *node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 			struct extended_perms_decision *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	struct avc_xperms_decision_node *dest_xpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	node->ae.xp_node->xp.len++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	dest_xpd = avc_xperms_decision_alloc(src->used);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 	if (!dest_xpd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 	avc_copy_xperms_decision(&dest_xpd->xpd, src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 	list_add(&dest_xpd->xpd_list, &node->ae.xp_node->xpd_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) static struct avc_xperms_node *avc_xperms_alloc(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 	struct avc_xperms_node *xp_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	xp_node = kmem_cache_zalloc(avc_xperms_cachep, GFP_NOWAIT | __GFP_NOWARN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 	if (!xp_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 		return xp_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	INIT_LIST_HEAD(&xp_node->xpd_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 	return xp_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) static int avc_xperms_populate(struct avc_node *node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 				struct avc_xperms_node *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 	struct avc_xperms_node *dest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	struct avc_xperms_decision_node *dest_xpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	struct avc_xperms_decision_node *src_xpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	if (src->xp.len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 	dest = avc_xperms_alloc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 	if (!dest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	memcpy(dest->xp.drivers.p, src->xp.drivers.p, sizeof(dest->xp.drivers.p));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	dest->xp.len = src->xp.len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 	/* for each source xpd allocate a destination xpd and copy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 	list_for_each_entry(src_xpd, &src->xpd_head, xpd_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 		dest_xpd = avc_xperms_decision_alloc(src_xpd->xpd.used);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 		if (!dest_xpd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 		avc_copy_xperms_decision(&dest_xpd->xpd, &src_xpd->xpd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 		list_add(&dest_xpd->xpd_list, &dest->xpd_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 	node->ae.xp_node = dest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 	avc_xperms_free(dest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 	return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) static inline u32 avc_xperms_audit_required(u32 requested,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 					struct av_decision *avd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 					struct extended_perms_decision *xpd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 					u8 perm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 					int result,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 					u32 *deniedp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	u32 denied, audited;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 	denied = requested & ~avd->allowed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	if (unlikely(denied)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 		audited = denied & avd->auditdeny;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 		if (audited && xpd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 			if (avc_xperms_has_perm(xpd, perm, XPERMS_DONTAUDIT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 				audited &= ~requested;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	} else if (result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 		audited = denied = requested;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 		audited = requested & avd->auditallow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 		if (audited && xpd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 			if (!avc_xperms_has_perm(xpd, perm, XPERMS_AUDITALLOW))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 				audited &= ~requested;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	*deniedp = denied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	return audited;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) static inline int avc_xperms_audit(struct selinux_state *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 				   u32 ssid, u32 tsid, u16 tclass,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 				   u32 requested, struct av_decision *avd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 				   struct extended_perms_decision *xpd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 				   u8 perm, int result,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 				   struct common_audit_data *ad)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 	u32 audited, denied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 	audited = avc_xperms_audit_required(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 			requested, avd, xpd, perm, result, &denied);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 	if (likely(!audited))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	return slow_avc_audit(state, ssid, tsid, tclass, requested,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 			audited, denied, result, ad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) static void avc_node_free(struct rcu_head *rhead)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 	struct avc_node *node = container_of(rhead, struct avc_node, rhead);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 	avc_xperms_free(node->ae.xp_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 	kmem_cache_free(avc_node_cachep, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 	avc_cache_stats_incr(frees);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) static void avc_node_delete(struct selinux_avc *avc, struct avc_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 	trace_android_vh_selinux_avc_node_delete(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 	hlist_del_rcu(&node->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 	call_rcu(&node->rhead, avc_node_free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 	atomic_dec(&avc->avc_cache.active_nodes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) static void avc_node_kill(struct selinux_avc *avc, struct avc_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 	avc_xperms_free(node->ae.xp_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 	kmem_cache_free(avc_node_cachep, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 	avc_cache_stats_incr(frees);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 	atomic_dec(&avc->avc_cache.active_nodes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) static void avc_node_replace(struct selinux_avc *avc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 			     struct avc_node *new, struct avc_node *old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	trace_android_vh_selinux_avc_node_replace(old, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 	hlist_replace_rcu(&old->list, &new->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 	call_rcu(&old->rhead, avc_node_free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 	atomic_dec(&avc->avc_cache.active_nodes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) static inline int avc_reclaim_node(struct selinux_avc *avc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 	struct avc_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 	int hvalue, try, ecx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 	spinlock_t *lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	for (try = 0, ecx = 0; try < AVC_CACHE_SLOTS; try++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 		hvalue = atomic_inc_return(&avc->avc_cache.lru_hint) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 			(AVC_CACHE_SLOTS - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 		head = &avc->avc_cache.slots[hvalue];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 		lock = &avc->avc_cache.slots_lock[hvalue];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 		if (!spin_trylock_irqsave(lock, flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 		rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 		hlist_for_each_entry(node, head, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 			avc_node_delete(avc, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 			avc_cache_stats_incr(reclaims);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 			ecx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 			if (ecx >= AVC_CACHE_RECLAIM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 				rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 				spin_unlock_irqrestore(lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 		rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 		spin_unlock_irqrestore(lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 	return ecx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) static struct avc_node *avc_alloc_node(struct selinux_avc *avc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	struct avc_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 	node = kmem_cache_zalloc(avc_node_cachep, GFP_NOWAIT | __GFP_NOWARN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 	if (!node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 	INIT_HLIST_NODE(&node->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 	avc_cache_stats_incr(allocations);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 	if (atomic_inc_return(&avc->avc_cache.active_nodes) >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 	    avc->avc_cache_threshold)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 		avc_reclaim_node(avc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 	return node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) static void avc_node_populate(struct avc_node *node, u32 ssid, u32 tsid, u16 tclass, struct av_decision *avd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 	node->ae.ssid = ssid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 	node->ae.tsid = tsid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 	node->ae.tclass = tclass;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 	memcpy(&node->ae.avd, avd, sizeof(node->ae.avd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) static inline struct avc_node *avc_search_node(struct selinux_avc *avc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 					       u32 ssid, u32 tsid, u16 tclass)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 	struct avc_node *node, *ret = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 	int hvalue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 	struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	hvalue = avc_hash(ssid, tsid, tclass);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 	head = &avc->avc_cache.slots[hvalue];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	hlist_for_each_entry_rcu(node, head, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 		if (ssid == node->ae.ssid &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 		    tclass == node->ae.tclass &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 		    tsid == node->ae.tsid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 			ret = node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554)  * avc_lookup - Look up an AVC entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555)  * @ssid: source security identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556)  * @tsid: target security identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557)  * @tclass: target security class
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559)  * Look up an AVC entry that is valid for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560)  * (@ssid, @tsid), interpreting the permissions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561)  * based on @tclass.  If a valid AVC entry exists,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562)  * then this function returns the avc_node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563)  * Otherwise, this function returns NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) static struct avc_node *avc_lookup(struct selinux_avc *avc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 				   u32 ssid, u32 tsid, u16 tclass)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	struct avc_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	avc_cache_stats_incr(lookups);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 	node = avc_search_node(avc, ssid, tsid, tclass);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	if (node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 		trace_android_vh_selinux_avc_lookup(node, ssid, tsid, tclass);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 		return node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	avc_cache_stats_incr(misses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) static int avc_latest_notif_update(struct selinux_avc *avc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 				   int seqno, int is_insert)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	static DEFINE_SPINLOCK(notif_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	unsigned long flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	spin_lock_irqsave(&notif_lock, flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	if (is_insert) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 		if (seqno < avc->avc_cache.latest_notif) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 			pr_warn("SELinux: avc:  seqno %d < latest_notif %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 			       seqno, avc->avc_cache.latest_notif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 			ret = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 		if (seqno > avc->avc_cache.latest_notif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 			avc->avc_cache.latest_notif = seqno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 	spin_unlock_irqrestore(&notif_lock, flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606)  * avc_insert - Insert an AVC entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607)  * @ssid: source security identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608)  * @tsid: target security identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609)  * @tclass: target security class
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610)  * @avd: resulting av decision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611)  * @xp_node: resulting extended permissions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613)  * Insert an AVC entry for the SID pair
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614)  * (@ssid, @tsid) and class @tclass.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615)  * The access vectors and the sequence number are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616)  * normally provided by the security server in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617)  * response to a security_compute_av() call.  If the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618)  * sequence number @avd->seqno is not less than the latest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619)  * revocation notification, then the function copies
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620)  * the access vectors into a cache entry, returns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621)  * avc_node inserted. Otherwise, this function returns NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) static struct avc_node *avc_insert(struct selinux_avc *avc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 				   u32 ssid, u32 tsid, u16 tclass,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 				   struct av_decision *avd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 				   struct avc_xperms_node *xp_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 	struct avc_node *pos, *node = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 	int hvalue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	unsigned long flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 	spinlock_t *lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 	struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 	if (avc_latest_notif_update(avc, avd->seqno, 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 	node = avc_alloc_node(avc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 	if (!node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 	avc_node_populate(node, ssid, tsid, tclass, avd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 	if (avc_xperms_populate(node, xp_node)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 		avc_node_kill(avc, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 	hvalue = avc_hash(ssid, tsid, tclass);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 	head = &avc->avc_cache.slots[hvalue];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 	lock = &avc->avc_cache.slots_lock[hvalue];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 	spin_lock_irqsave(lock, flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 	hlist_for_each_entry(pos, head, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 		if (pos->ae.ssid == ssid &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 			pos->ae.tsid == tsid &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 			pos->ae.tclass == tclass) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 			avc_node_replace(avc, node, pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 			goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 	hlist_add_head_rcu(&node->list, head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 	trace_android_vh_selinux_avc_insert(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 	spin_unlock_irqrestore(lock, flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 	return node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667)  * avc_audit_pre_callback - SELinux specific information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668)  * will be called by generic audit code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669)  * @ab: the audit buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670)  * @a: audit_data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) static void avc_audit_pre_callback(struct audit_buffer *ab, void *a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	struct common_audit_data *ad = a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 	struct selinux_audit_data *sad = ad->selinux_audit_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 	u32 av = sad->audited;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 	const char **perms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 	int i, perm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	audit_log_format(ab, "avc:  %s ", sad->denied ? "denied" : "granted");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	if (av == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 		audit_log_format(ab, " null");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	perms = secclass_map[sad->tclass-1].perms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	audit_log_format(ab, " {");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 	i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 	perm = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 	while (i < (sizeof(av) * 8)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 		if ((perm & av) && perms[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 			audit_log_format(ab, " %s", perms[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 			av &= ~perm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 		i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 		perm <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	if (av)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 		audit_log_format(ab, " 0x%x", av);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 	audit_log_format(ab, " } for ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708)  * avc_audit_post_callback - SELinux specific information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709)  * will be called by generic audit code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710)  * @ab: the audit buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711)  * @a: audit_data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) static void avc_audit_post_callback(struct audit_buffer *ab, void *a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 	struct common_audit_data *ad = a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 	struct selinux_audit_data *sad = ad->selinux_audit_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 	char *scontext = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 	char *tcontext = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	const char *tclass = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 	u32 scontext_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 	u32 tcontext_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 	rc = security_sid_to_context(sad->state, sad->ssid, &scontext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 				     &scontext_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 		audit_log_format(ab, " ssid=%d", sad->ssid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 		audit_log_format(ab, " scontext=%s", scontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 	rc = security_sid_to_context(sad->state, sad->tsid, &tcontext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 				     &tcontext_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 		audit_log_format(ab, " tsid=%d", sad->tsid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 		audit_log_format(ab, " tcontext=%s", tcontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 	tclass = secclass_map[sad->tclass-1].name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 	audit_log_format(ab, " tclass=%s", tclass);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 	if (sad->denied)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 		audit_log_format(ab, " permissive=%u", sad->result ? 0 : 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 	trace_selinux_audited(sad, scontext, tcontext, tclass);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 	kfree(tcontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 	kfree(scontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	/* in case of invalid context report also the actual context string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 	rc = security_sid_to_context_inval(sad->state, sad->ssid, &scontext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 					   &scontext_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 	if (!rc && scontext) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 		if (scontext_len && scontext[scontext_len - 1] == '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 			scontext_len--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 		audit_log_format(ab, " srawcon=");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 		audit_log_n_untrustedstring(ab, scontext, scontext_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 		kfree(scontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 	rc = security_sid_to_context_inval(sad->state, sad->tsid, &scontext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 					   &scontext_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 	if (!rc && scontext) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 		if (scontext_len && scontext[scontext_len - 1] == '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 			scontext_len--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 		audit_log_format(ab, " trawcon=");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 		audit_log_n_untrustedstring(ab, scontext, scontext_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 		kfree(scontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) /* This is the slow part of avc audit with big stack footprint */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) noinline int slow_avc_audit(struct selinux_state *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 			    u32 ssid, u32 tsid, u16 tclass,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 			    u32 requested, u32 audited, u32 denied, int result,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 			    struct common_audit_data *a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 	struct common_audit_data stack_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 	struct selinux_audit_data sad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 	if (WARN_ON(!tclass || tclass >= ARRAY_SIZE(secclass_map)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 	if (!a) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 		a = &stack_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 		a->type = LSM_AUDIT_DATA_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 	sad.tclass = tclass;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	sad.requested = requested;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	sad.ssid = ssid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	sad.tsid = tsid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 	sad.audited = audited;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 	sad.denied = denied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	sad.result = result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 	sad.state = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 	a->selinux_audit_data = &sad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 	common_lsm_audit(a, avc_audit_pre_callback, avc_audit_post_callback);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803)  * avc_add_callback - Register a callback for security events.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804)  * @callback: callback function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805)  * @events: security events
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807)  * Register a callback function for events in the set @events.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808)  * Returns %0 on success or -%ENOMEM if insufficient memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809)  * exists to add the callback.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) int __init avc_add_callback(int (*callback)(u32 event), u32 events)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 	struct avc_callback_node *c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 	c = kmalloc(sizeof(*c), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 	if (!c) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 		rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 	c->callback = callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 	c->events = events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	c->next = avc_callbacks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 	avc_callbacks = c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831)  * avc_update_node Update an AVC entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832)  * @event : Updating event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833)  * @perms : Permission mask bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834)  * @ssid,@tsid,@tclass : identifier of an AVC entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835)  * @seqno : sequence number when decision was made
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836)  * @xpd: extended_perms_decision to be added to the node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837)  * @flags: the AVC_* flags, e.g. AVC_NONBLOCKING, AVC_EXTENDED_PERMS, or 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839)  * if a valid AVC entry doesn't exist,this function returns -ENOENT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840)  * if kmalloc() called internal returns NULL, this function returns -ENOMEM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841)  * otherwise, this function updates the AVC entry. The original AVC-entry object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842)  * will release later by RCU.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) static int avc_update_node(struct selinux_avc *avc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 			   u32 event, u32 perms, u8 driver, u8 xperm, u32 ssid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 			   u32 tsid, u16 tclass, u32 seqno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 			   struct extended_perms_decision *xpd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 			   u32 flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	int hvalue, rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	unsigned long flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	struct avc_node *pos, *node, *orig = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 	struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	spinlock_t *lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	 * If we are in a non-blocking code path, e.g. VFS RCU walk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 	 * then we must not add permissions to a cache entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 	 * because we will not audit the denial.  Otherwise,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 	 * during the subsequent blocking retry (e.g. VFS ref walk), we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 	 * will find the permissions already granted in the cache entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 	 * and won't audit anything at all, leading to silent denials in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 	 * permissive mode that only appear when in enforcing mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 	 * See the corresponding handling of MAY_NOT_BLOCK in avc_audit()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	 * and selinux_inode_permission().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 	if (flags & AVC_NONBLOCKING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 	node = avc_alloc_node(avc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 	if (!node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 		rc = -ENOMEM;
^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) 	/* Lock the target slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 	hvalue = avc_hash(ssid, tsid, tclass);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 	head = &avc->avc_cache.slots[hvalue];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 	lock = &avc->avc_cache.slots_lock[hvalue];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	spin_lock_irqsave(lock, flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 	hlist_for_each_entry(pos, head, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 		if (ssid == pos->ae.ssid &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 		    tsid == pos->ae.tsid &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 		    tclass == pos->ae.tclass &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 		    seqno == pos->ae.avd.seqno){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 			orig = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 	if (!orig) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 		rc = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 		avc_node_kill(avc, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 		goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 	 * Copy and replace original node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	avc_node_populate(node, ssid, tsid, tclass, &orig->ae.avd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	if (orig->ae.xp_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 		rc = avc_xperms_populate(node, orig->ae.xp_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 		if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 			avc_node_kill(avc, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 			goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 	switch (event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	case AVC_CALLBACK_GRANT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 		node->ae.avd.allowed |= perms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 		if (node->ae.xp_node && (flags & AVC_EXTENDED_PERMS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 			avc_xperms_allow_perm(node->ae.xp_node, driver, xperm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	case AVC_CALLBACK_TRY_REVOKE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	case AVC_CALLBACK_REVOKE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 		node->ae.avd.allowed &= ~perms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 	case AVC_CALLBACK_AUDITALLOW_ENABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 		node->ae.avd.auditallow |= perms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 	case AVC_CALLBACK_AUDITALLOW_DISABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 		node->ae.avd.auditallow &= ~perms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	case AVC_CALLBACK_AUDITDENY_ENABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 		node->ae.avd.auditdeny |= perms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 	case AVC_CALLBACK_AUDITDENY_DISABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 		node->ae.avd.auditdeny &= ~perms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	case AVC_CALLBACK_ADD_XPERMS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 		avc_add_xperms_decision(node, xpd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 	avc_node_replace(avc, node, orig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 	spin_unlock_irqrestore(lock, flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949)  * avc_flush - Flush the cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) static void avc_flush(struct selinux_avc *avc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 	struct avc_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	spinlock_t *lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	unsigned long flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	for (i = 0; i < AVC_CACHE_SLOTS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 		head = &avc->avc_cache.slots[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 		lock = &avc->avc_cache.slots_lock[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 		spin_lock_irqsave(lock, flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 		 * With preemptable RCU, the outer spinlock does not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 		 * prevent RCU grace periods from ending.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 		rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 		hlist_for_each_entry(node, head, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 			avc_node_delete(avc, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 		rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 		spin_unlock_irqrestore(lock, flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977)  * avc_ss_reset - Flush the cache and revalidate migrated permissions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978)  * @seqno: policy sequence number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) int avc_ss_reset(struct selinux_avc *avc, u32 seqno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	struct avc_callback_node *c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	int rc = 0, tmprc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	avc_flush(avc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	for (c = avc_callbacks; c; c = c->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 		if (c->events & AVC_CALLBACK_RESET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 			tmprc = c->callback(AVC_CALLBACK_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 			/* save the first error encountered for the return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 			   value and continue processing the callbacks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 			if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 				rc = tmprc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	avc_latest_notif_update(avc, seqno, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	return rc;
^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)  * Slow-path helper function for avc_has_perm_noaudit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)  * when the avc_node lookup fails. We get called with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)  * the RCU read lock held, and need to return with it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)  * still held, but drop if for the security compute.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)  * Don't inline this, since it's the slow-path and just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)  * results in a bigger stack frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) static noinline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) struct avc_node *avc_compute_av(struct selinux_state *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 				u32 ssid, u32 tsid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 				u16 tclass, struct av_decision *avd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 				struct avc_xperms_node *xp_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 	INIT_LIST_HEAD(&xp_node->xpd_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 	security_compute_av(state, ssid, tsid, tclass, avd, &xp_node->xp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	return avc_insert(state->avc, ssid, tsid, tclass, avd, xp_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) static noinline int avc_denied(struct selinux_state *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 			       u32 ssid, u32 tsid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 			       u16 tclass, u32 requested,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 			       u8 driver, u8 xperm, unsigned int flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 			       struct av_decision *avd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 	if (flags & AVC_STRICT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 		return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 	if (enforcing_enabled(state) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	    !(avd->flags & AVD_FLAGS_PERMISSIVE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 		return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 	avc_update_node(state->avc, AVC_CALLBACK_GRANT, requested, driver,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 			xperm, ssid, tsid, tclass, avd->seqno, NULL, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) }
^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)  * The avc extended permissions logic adds an additional 256 bits of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)  * permissions to an avc node when extended permissions for that node are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)  * specified in the avtab. If the additional 256 permissions is not adequate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)  * as-is the case with ioctls, then multiple may be chained together and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)  * driver field is used to specify which set contains the permission.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) int avc_has_extended_perms(struct selinux_state *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 			   u32 ssid, u32 tsid, u16 tclass, u32 requested,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 			   u8 driver, u8 xperm, struct common_audit_data *ad)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 	struct avc_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 	struct av_decision avd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 	u32 denied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 	struct extended_perms_decision local_xpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 	struct extended_perms_decision *xpd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	struct extended_perms_data allowed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 	struct extended_perms_data auditallow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 	struct extended_perms_data dontaudit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 	struct avc_xperms_node local_xp_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 	struct avc_xperms_node *xp_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	int rc = 0, rc2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 	xp_node = &local_xp_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 	if (WARN_ON(!requested))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 		return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	node = avc_lookup(state->avc, ssid, tsid, tclass);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 	if (unlikely(!node)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 		node = avc_compute_av(state, ssid, tsid, tclass, &avd, xp_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 		memcpy(&avd, &node->ae.avd, sizeof(avd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 		xp_node = node->ae.xp_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 	/* if extended permissions are not defined, only consider av_decision */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 	if (!xp_node || !xp_node->xp.len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 		goto decision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 	local_xpd.allowed = &allowed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 	local_xpd.auditallow = &auditallow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 	local_xpd.dontaudit = &dontaudit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	xpd = avc_xperms_decision_lookup(driver, xp_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 	if (unlikely(!xpd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 		 * Compute the extended_perms_decision only if the driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 		 * is flagged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 		if (!security_xperm_test(xp_node->xp.drivers.p, driver)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 			avd.allowed &= ~requested;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 			goto decision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 		rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 		security_compute_xperms_decision(state, ssid, tsid, tclass,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 						 driver, &local_xpd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 		rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 		avc_update_node(state->avc, AVC_CALLBACK_ADD_XPERMS, requested,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 				driver, xperm, ssid, tsid, tclass, avd.seqno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 				&local_xpd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 		avc_quick_copy_xperms_decision(xperm, &local_xpd, xpd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	xpd = &local_xpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	if (!avc_xperms_has_perm(xpd, xperm, XPERMS_ALLOWED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 		avd.allowed &= ~requested;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) decision:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	denied = requested & ~(avd.allowed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 	if (unlikely(denied))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 		rc = avc_denied(state, ssid, tsid, tclass, requested,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 				driver, xperm, AVC_EXTENDED_PERMS, &avd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	rc2 = avc_xperms_audit(state, ssid, tsid, tclass, requested,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 			&avd, xpd, xperm, rc, ad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 	if (rc2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 		return rc2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126)  * avc_has_perm_noaudit - Check permissions but perform no auditing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127)  * @ssid: source security identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128)  * @tsid: target security identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)  * @tclass: target security class
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)  * @requested: requested permissions, interpreted based on @tclass
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)  * @flags:  AVC_STRICT, AVC_NONBLOCKING, or 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)  * @avd: access vector decisions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)  * Check the AVC to determine whether the @requested permissions are granted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)  * for the SID pair (@ssid, @tsid), interpreting the permissions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)  * based on @tclass, and call the security server on a cache miss to obtain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)  * a new decision and add it to the cache.  Return a copy of the decisions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)  * in @avd.  Return %0 if all @requested permissions are granted,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)  * -%EACCES if any permissions are denied, or another -errno upon
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)  * other errors.  This function is typically called by avc_has_perm(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)  * but may also be called directly to separate permission checking from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142)  * auditing, e.g. in cases where a lock must be held for the check but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)  * should be released for the auditing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) inline int avc_has_perm_noaudit(struct selinux_state *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 				u32 ssid, u32 tsid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 				u16 tclass, u32 requested,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 				unsigned int flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 				struct av_decision *avd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 	struct avc_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	struct avc_xperms_node xp_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 	u32 denied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 	if (WARN_ON(!requested))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 		return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 	node = avc_lookup(state->avc, ssid, tsid, tclass);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 	if (unlikely(!node))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 		node = avc_compute_av(state, ssid, tsid, tclass, avd, &xp_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 		memcpy(avd, &node->ae.avd, sizeof(*avd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 	denied = requested & ~(avd->allowed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 	if (unlikely(denied))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 		rc = avc_denied(state, ssid, tsid, tclass, requested, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 				flags, avd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177)  * avc_has_perm - Check permissions and perform any appropriate auditing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)  * @ssid: source security identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)  * @tsid: target security identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)  * @tclass: target security class
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)  * @requested: requested permissions, interpreted based on @tclass
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)  * @auditdata: auxiliary audit data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)  * Check the AVC to determine whether the @requested permissions are granted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)  * for the SID pair (@ssid, @tsid), interpreting the permissions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)  * based on @tclass, and call the security server on a cache miss to obtain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)  * a new decision and add it to the cache.  Audit the granting or denial of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)  * permissions in accordance with the policy.  Return %0 if all @requested
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)  * permissions are granted, -%EACCES if any permissions are denied, or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190)  * another -errno upon other errors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) int avc_has_perm(struct selinux_state *state, u32 ssid, u32 tsid, u16 tclass,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 		 u32 requested, struct common_audit_data *auditdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 	struct av_decision avd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 	int rc, rc2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 	rc = avc_has_perm_noaudit(state, ssid, tsid, tclass, requested, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 				  &avd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 	rc2 = avc_audit(state, ssid, tsid, tclass, requested, &avd, rc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 			auditdata, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 	if (rc2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 		return rc2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) int avc_has_perm_flags(struct selinux_state *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 		       u32 ssid, u32 tsid, u16 tclass, u32 requested,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 		       struct common_audit_data *auditdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 		       int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 	struct av_decision avd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 	int rc, rc2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 	rc = avc_has_perm_noaudit(state, ssid, tsid, tclass, requested,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 				  (flags & MAY_NOT_BLOCK) ? AVC_NONBLOCKING : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 				  &avd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 	rc2 = avc_audit(state, ssid, tsid, tclass, requested, &avd, rc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 			auditdata, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 	if (rc2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 		return rc2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) u32 avc_policy_seqno(struct selinux_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 	return state->avc->avc_cache.latest_notif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) void avc_disable(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 	 * If you are looking at this because you have realized that we are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 	 * not destroying the avc_node_cachep it might be easy to fix, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 	 * I don't know the memory barrier semantics well enough to know.  It's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 	 * possible that some other task dereferenced security_ops when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 	 * it still pointed to selinux operations.  If that is the case it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 	 * possible that it is about to use the avc and is about to need the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 	 * avc_node_cachep.  I know I could wrap the security.c security_ops call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 	 * in an rcu_lock, but seriously, it's not worth it.  Instead I just flush
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 	 * the cache and get that memory back.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 	if (avc_node_cachep) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 		avc_flush(selinux_state.avc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 		/* kmem_cache_destroy(avc_node_cachep); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) }