18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com>
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Author:
68c2ecf20Sopenharmony_ci *      Casey Schaufler <casey@schaufler-ca.com>
78c2ecf20Sopenharmony_ci */
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci#include <linux/types.h>
108c2ecf20Sopenharmony_ci#include <linux/slab.h>
118c2ecf20Sopenharmony_ci#include <linux/fs.h>
128c2ecf20Sopenharmony_ci#include <linux/sched.h>
138c2ecf20Sopenharmony_ci#include "smack.h"
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_cistruct smack_known smack_known_huh = {
168c2ecf20Sopenharmony_ci	.smk_known	= "?",
178c2ecf20Sopenharmony_ci	.smk_secid	= 2,
188c2ecf20Sopenharmony_ci};
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_cistruct smack_known smack_known_hat = {
218c2ecf20Sopenharmony_ci	.smk_known	= "^",
228c2ecf20Sopenharmony_ci	.smk_secid	= 3,
238c2ecf20Sopenharmony_ci};
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_cistruct smack_known smack_known_star = {
268c2ecf20Sopenharmony_ci	.smk_known	= "*",
278c2ecf20Sopenharmony_ci	.smk_secid	= 4,
288c2ecf20Sopenharmony_ci};
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_cistruct smack_known smack_known_floor = {
318c2ecf20Sopenharmony_ci	.smk_known	= "_",
328c2ecf20Sopenharmony_ci	.smk_secid	= 5,
338c2ecf20Sopenharmony_ci};
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_cistruct smack_known smack_known_web = {
368c2ecf20Sopenharmony_ci	.smk_known	= "@",
378c2ecf20Sopenharmony_ci	.smk_secid	= 7,
388c2ecf20Sopenharmony_ci};
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ciLIST_HEAD(smack_known_list);
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci/*
438c2ecf20Sopenharmony_ci * The initial value needs to be bigger than any of the
448c2ecf20Sopenharmony_ci * known values above.
458c2ecf20Sopenharmony_ci */
468c2ecf20Sopenharmony_cistatic u32 smack_next_secid = 10;
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci/*
498c2ecf20Sopenharmony_ci * what events do we log
508c2ecf20Sopenharmony_ci * can be overwritten at run-time by /smack/logging
518c2ecf20Sopenharmony_ci */
528c2ecf20Sopenharmony_ciint log_policy = SMACK_AUDIT_DENIED;
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci/**
558c2ecf20Sopenharmony_ci * smk_access_entry - look up matching access rule
568c2ecf20Sopenharmony_ci * @subject_label: a pointer to the subject's Smack label
578c2ecf20Sopenharmony_ci * @object_label: a pointer to the object's Smack label
588c2ecf20Sopenharmony_ci * @rule_list: the list of rules to search
598c2ecf20Sopenharmony_ci *
608c2ecf20Sopenharmony_ci * This function looks up the subject/object pair in the
618c2ecf20Sopenharmony_ci * access rule list and returns the access mode. If no
628c2ecf20Sopenharmony_ci * entry is found returns -ENOENT.
638c2ecf20Sopenharmony_ci *
648c2ecf20Sopenharmony_ci * NOTE:
658c2ecf20Sopenharmony_ci *
668c2ecf20Sopenharmony_ci * Earlier versions of this function allowed for labels that
678c2ecf20Sopenharmony_ci * were not on the label list. This was done to allow for
688c2ecf20Sopenharmony_ci * labels to come over the network that had never been seen
698c2ecf20Sopenharmony_ci * before on this host. Unless the receiving socket has the
708c2ecf20Sopenharmony_ci * star label this will always result in a failure check. The
718c2ecf20Sopenharmony_ci * star labeled socket case is now handled in the networking
728c2ecf20Sopenharmony_ci * hooks so there is no case where the label is not on the
738c2ecf20Sopenharmony_ci * label list. Checking to see if the address of two labels
748c2ecf20Sopenharmony_ci * is the same is now a reliable test.
758c2ecf20Sopenharmony_ci *
768c2ecf20Sopenharmony_ci * Do the object check first because that is more
778c2ecf20Sopenharmony_ci * likely to differ.
788c2ecf20Sopenharmony_ci *
798c2ecf20Sopenharmony_ci * Allowing write access implies allowing locking.
808c2ecf20Sopenharmony_ci */
818c2ecf20Sopenharmony_ciint smk_access_entry(char *subject_label, char *object_label,
828c2ecf20Sopenharmony_ci			struct list_head *rule_list)
838c2ecf20Sopenharmony_ci{
848c2ecf20Sopenharmony_ci	struct smack_rule *srp;
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_ci	list_for_each_entry_rcu(srp, rule_list, list) {
878c2ecf20Sopenharmony_ci		if (srp->smk_object->smk_known == object_label &&
888c2ecf20Sopenharmony_ci		    srp->smk_subject->smk_known == subject_label) {
898c2ecf20Sopenharmony_ci			int may = srp->smk_access;
908c2ecf20Sopenharmony_ci			/*
918c2ecf20Sopenharmony_ci			 * MAY_WRITE implies MAY_LOCK.
928c2ecf20Sopenharmony_ci			 */
938c2ecf20Sopenharmony_ci			if ((may & MAY_WRITE) == MAY_WRITE)
948c2ecf20Sopenharmony_ci				may |= MAY_LOCK;
958c2ecf20Sopenharmony_ci			return may;
968c2ecf20Sopenharmony_ci		}
978c2ecf20Sopenharmony_ci	}
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ci	return -ENOENT;
1008c2ecf20Sopenharmony_ci}
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ci/**
1038c2ecf20Sopenharmony_ci * smk_access - determine if a subject has a specific access to an object
1048c2ecf20Sopenharmony_ci * @subject: a pointer to the subject's Smack label entry
1058c2ecf20Sopenharmony_ci * @object: a pointer to the object's Smack label entry
1068c2ecf20Sopenharmony_ci * @request: the access requested, in "MAY" format
1078c2ecf20Sopenharmony_ci * @a : a pointer to the audit data
1088c2ecf20Sopenharmony_ci *
1098c2ecf20Sopenharmony_ci * This function looks up the subject/object pair in the
1108c2ecf20Sopenharmony_ci * access rule list and returns 0 if the access is permitted,
1118c2ecf20Sopenharmony_ci * non zero otherwise.
1128c2ecf20Sopenharmony_ci *
1138c2ecf20Sopenharmony_ci * Smack labels are shared on smack_list
1148c2ecf20Sopenharmony_ci */
1158c2ecf20Sopenharmony_ciint smk_access(struct smack_known *subject, struct smack_known *object,
1168c2ecf20Sopenharmony_ci	       int request, struct smk_audit_info *a)
1178c2ecf20Sopenharmony_ci{
1188c2ecf20Sopenharmony_ci	int may = MAY_NOT;
1198c2ecf20Sopenharmony_ci	int rc = 0;
1208c2ecf20Sopenharmony_ci
1218c2ecf20Sopenharmony_ci	/*
1228c2ecf20Sopenharmony_ci	 * Hardcoded comparisons.
1238c2ecf20Sopenharmony_ci	 */
1248c2ecf20Sopenharmony_ci	/*
1258c2ecf20Sopenharmony_ci	 * A star subject can't access any object.
1268c2ecf20Sopenharmony_ci	 */
1278c2ecf20Sopenharmony_ci	if (subject == &smack_known_star) {
1288c2ecf20Sopenharmony_ci		rc = -EACCES;
1298c2ecf20Sopenharmony_ci		goto out_audit;
1308c2ecf20Sopenharmony_ci	}
1318c2ecf20Sopenharmony_ci	/*
1328c2ecf20Sopenharmony_ci	 * An internet object can be accessed by any subject.
1338c2ecf20Sopenharmony_ci	 * Tasks cannot be assigned the internet label.
1348c2ecf20Sopenharmony_ci	 * An internet subject can access any object.
1358c2ecf20Sopenharmony_ci	 */
1368c2ecf20Sopenharmony_ci	if (object == &smack_known_web || subject == &smack_known_web)
1378c2ecf20Sopenharmony_ci		goto out_audit;
1388c2ecf20Sopenharmony_ci	/*
1398c2ecf20Sopenharmony_ci	 * A star object can be accessed by any subject.
1408c2ecf20Sopenharmony_ci	 */
1418c2ecf20Sopenharmony_ci	if (object == &smack_known_star)
1428c2ecf20Sopenharmony_ci		goto out_audit;
1438c2ecf20Sopenharmony_ci	/*
1448c2ecf20Sopenharmony_ci	 * An object can be accessed in any way by a subject
1458c2ecf20Sopenharmony_ci	 * with the same label.
1468c2ecf20Sopenharmony_ci	 */
1478c2ecf20Sopenharmony_ci	if (subject->smk_known == object->smk_known)
1488c2ecf20Sopenharmony_ci		goto out_audit;
1498c2ecf20Sopenharmony_ci	/*
1508c2ecf20Sopenharmony_ci	 * A hat subject can read or lock any object.
1518c2ecf20Sopenharmony_ci	 * A floor object can be read or locked by any subject.
1528c2ecf20Sopenharmony_ci	 */
1538c2ecf20Sopenharmony_ci	if ((request & MAY_ANYREAD) == request ||
1548c2ecf20Sopenharmony_ci	    (request & MAY_LOCK) == request) {
1558c2ecf20Sopenharmony_ci		if (object == &smack_known_floor)
1568c2ecf20Sopenharmony_ci			goto out_audit;
1578c2ecf20Sopenharmony_ci		if (subject == &smack_known_hat)
1588c2ecf20Sopenharmony_ci			goto out_audit;
1598c2ecf20Sopenharmony_ci	}
1608c2ecf20Sopenharmony_ci	/*
1618c2ecf20Sopenharmony_ci	 * Beyond here an explicit relationship is required.
1628c2ecf20Sopenharmony_ci	 * If the requested access is contained in the available
1638c2ecf20Sopenharmony_ci	 * access (e.g. read is included in readwrite) it's
1648c2ecf20Sopenharmony_ci	 * good. A negative response from smk_access_entry()
1658c2ecf20Sopenharmony_ci	 * indicates there is no entry for this pair.
1668c2ecf20Sopenharmony_ci	 */
1678c2ecf20Sopenharmony_ci	rcu_read_lock();
1688c2ecf20Sopenharmony_ci	may = smk_access_entry(subject->smk_known, object->smk_known,
1698c2ecf20Sopenharmony_ci			       &subject->smk_rules);
1708c2ecf20Sopenharmony_ci	rcu_read_unlock();
1718c2ecf20Sopenharmony_ci
1728c2ecf20Sopenharmony_ci	if (may <= 0 || (request & may) != request) {
1738c2ecf20Sopenharmony_ci		rc = -EACCES;
1748c2ecf20Sopenharmony_ci		goto out_audit;
1758c2ecf20Sopenharmony_ci	}
1768c2ecf20Sopenharmony_ci#ifdef CONFIG_SECURITY_SMACK_BRINGUP
1778c2ecf20Sopenharmony_ci	/*
1788c2ecf20Sopenharmony_ci	 * Return a positive value if using bringup mode.
1798c2ecf20Sopenharmony_ci	 * This allows the hooks to identify checks that
1808c2ecf20Sopenharmony_ci	 * succeed because of "b" rules.
1818c2ecf20Sopenharmony_ci	 */
1828c2ecf20Sopenharmony_ci	if (may & MAY_BRINGUP)
1838c2ecf20Sopenharmony_ci		rc = SMACK_BRINGUP_ALLOW;
1848c2ecf20Sopenharmony_ci#endif
1858c2ecf20Sopenharmony_ci
1868c2ecf20Sopenharmony_ciout_audit:
1878c2ecf20Sopenharmony_ci
1888c2ecf20Sopenharmony_ci#ifdef CONFIG_SECURITY_SMACK_BRINGUP
1898c2ecf20Sopenharmony_ci	if (rc < 0) {
1908c2ecf20Sopenharmony_ci		if (object == smack_unconfined)
1918c2ecf20Sopenharmony_ci			rc = SMACK_UNCONFINED_OBJECT;
1928c2ecf20Sopenharmony_ci		if (subject == smack_unconfined)
1938c2ecf20Sopenharmony_ci			rc = SMACK_UNCONFINED_SUBJECT;
1948c2ecf20Sopenharmony_ci	}
1958c2ecf20Sopenharmony_ci#endif
1968c2ecf20Sopenharmony_ci
1978c2ecf20Sopenharmony_ci#ifdef CONFIG_AUDIT
1988c2ecf20Sopenharmony_ci	if (a)
1998c2ecf20Sopenharmony_ci		smack_log(subject->smk_known, object->smk_known,
2008c2ecf20Sopenharmony_ci			  request, rc, a);
2018c2ecf20Sopenharmony_ci#endif
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_ci	return rc;
2048c2ecf20Sopenharmony_ci}
2058c2ecf20Sopenharmony_ci
2068c2ecf20Sopenharmony_ci/**
2078c2ecf20Sopenharmony_ci * smk_tskacc - determine if a task has a specific access to an object
2088c2ecf20Sopenharmony_ci * @tsp: a pointer to the subject's task
2098c2ecf20Sopenharmony_ci * @obj_known: a pointer to the object's label entry
2108c2ecf20Sopenharmony_ci * @mode: the access requested, in "MAY" format
2118c2ecf20Sopenharmony_ci * @a : common audit data
2128c2ecf20Sopenharmony_ci *
2138c2ecf20Sopenharmony_ci * This function checks the subject task's label/object label pair
2148c2ecf20Sopenharmony_ci * in the access rule list and returns 0 if the access is permitted,
2158c2ecf20Sopenharmony_ci * non zero otherwise. It allows that the task may have the capability
2168c2ecf20Sopenharmony_ci * to override the rules.
2178c2ecf20Sopenharmony_ci */
2188c2ecf20Sopenharmony_ciint smk_tskacc(struct task_smack *tsp, struct smack_known *obj_known,
2198c2ecf20Sopenharmony_ci	       u32 mode, struct smk_audit_info *a)
2208c2ecf20Sopenharmony_ci{
2218c2ecf20Sopenharmony_ci	struct smack_known *sbj_known = smk_of_task(tsp);
2228c2ecf20Sopenharmony_ci	int may;
2238c2ecf20Sopenharmony_ci	int rc;
2248c2ecf20Sopenharmony_ci
2258c2ecf20Sopenharmony_ci	/*
2268c2ecf20Sopenharmony_ci	 * Check the global rule list
2278c2ecf20Sopenharmony_ci	 */
2288c2ecf20Sopenharmony_ci	rc = smk_access(sbj_known, obj_known, mode, NULL);
2298c2ecf20Sopenharmony_ci	if (rc >= 0) {
2308c2ecf20Sopenharmony_ci		/*
2318c2ecf20Sopenharmony_ci		 * If there is an entry in the task's rule list
2328c2ecf20Sopenharmony_ci		 * it can further restrict access.
2338c2ecf20Sopenharmony_ci		 */
2348c2ecf20Sopenharmony_ci		may = smk_access_entry(sbj_known->smk_known,
2358c2ecf20Sopenharmony_ci				       obj_known->smk_known,
2368c2ecf20Sopenharmony_ci				       &tsp->smk_rules);
2378c2ecf20Sopenharmony_ci		if (may < 0)
2388c2ecf20Sopenharmony_ci			goto out_audit;
2398c2ecf20Sopenharmony_ci		if ((mode & may) == mode)
2408c2ecf20Sopenharmony_ci			goto out_audit;
2418c2ecf20Sopenharmony_ci		rc = -EACCES;
2428c2ecf20Sopenharmony_ci	}
2438c2ecf20Sopenharmony_ci
2448c2ecf20Sopenharmony_ci	/*
2458c2ecf20Sopenharmony_ci	 * Allow for priviliged to override policy.
2468c2ecf20Sopenharmony_ci	 */
2478c2ecf20Sopenharmony_ci	if (rc != 0 && smack_privileged(CAP_MAC_OVERRIDE))
2488c2ecf20Sopenharmony_ci		rc = 0;
2498c2ecf20Sopenharmony_ci
2508c2ecf20Sopenharmony_ciout_audit:
2518c2ecf20Sopenharmony_ci#ifdef CONFIG_AUDIT
2528c2ecf20Sopenharmony_ci	if (a)
2538c2ecf20Sopenharmony_ci		smack_log(sbj_known->smk_known, obj_known->smk_known,
2548c2ecf20Sopenharmony_ci			  mode, rc, a);
2558c2ecf20Sopenharmony_ci#endif
2568c2ecf20Sopenharmony_ci	return rc;
2578c2ecf20Sopenharmony_ci}
2588c2ecf20Sopenharmony_ci
2598c2ecf20Sopenharmony_ci/**
2608c2ecf20Sopenharmony_ci * smk_curacc - determine if current has a specific access to an object
2618c2ecf20Sopenharmony_ci * @obj_known: a pointer to the object's Smack label entry
2628c2ecf20Sopenharmony_ci * @mode: the access requested, in "MAY" format
2638c2ecf20Sopenharmony_ci * @a : common audit data
2648c2ecf20Sopenharmony_ci *
2658c2ecf20Sopenharmony_ci * This function checks the current subject label/object label pair
2668c2ecf20Sopenharmony_ci * in the access rule list and returns 0 if the access is permitted,
2678c2ecf20Sopenharmony_ci * non zero otherwise. It allows that current may have the capability
2688c2ecf20Sopenharmony_ci * to override the rules.
2698c2ecf20Sopenharmony_ci */
2708c2ecf20Sopenharmony_ciint smk_curacc(struct smack_known *obj_known,
2718c2ecf20Sopenharmony_ci	       u32 mode, struct smk_audit_info *a)
2728c2ecf20Sopenharmony_ci{
2738c2ecf20Sopenharmony_ci	struct task_smack *tsp = smack_cred(current_cred());
2748c2ecf20Sopenharmony_ci
2758c2ecf20Sopenharmony_ci	return smk_tskacc(tsp, obj_known, mode, a);
2768c2ecf20Sopenharmony_ci}
2778c2ecf20Sopenharmony_ci
2788c2ecf20Sopenharmony_ci#ifdef CONFIG_AUDIT
2798c2ecf20Sopenharmony_ci/**
2808c2ecf20Sopenharmony_ci * smack_str_from_perm : helper to transalate an int to a
2818c2ecf20Sopenharmony_ci * readable string
2828c2ecf20Sopenharmony_ci * @string : the string to fill
2838c2ecf20Sopenharmony_ci * @access : the int
2848c2ecf20Sopenharmony_ci *
2858c2ecf20Sopenharmony_ci */
2868c2ecf20Sopenharmony_cistatic inline void smack_str_from_perm(char *string, int access)
2878c2ecf20Sopenharmony_ci{
2888c2ecf20Sopenharmony_ci	int i = 0;
2898c2ecf20Sopenharmony_ci
2908c2ecf20Sopenharmony_ci	if (access & MAY_READ)
2918c2ecf20Sopenharmony_ci		string[i++] = 'r';
2928c2ecf20Sopenharmony_ci	if (access & MAY_WRITE)
2938c2ecf20Sopenharmony_ci		string[i++] = 'w';
2948c2ecf20Sopenharmony_ci	if (access & MAY_EXEC)
2958c2ecf20Sopenharmony_ci		string[i++] = 'x';
2968c2ecf20Sopenharmony_ci	if (access & MAY_APPEND)
2978c2ecf20Sopenharmony_ci		string[i++] = 'a';
2988c2ecf20Sopenharmony_ci	if (access & MAY_TRANSMUTE)
2998c2ecf20Sopenharmony_ci		string[i++] = 't';
3008c2ecf20Sopenharmony_ci	if (access & MAY_LOCK)
3018c2ecf20Sopenharmony_ci		string[i++] = 'l';
3028c2ecf20Sopenharmony_ci	string[i] = '\0';
3038c2ecf20Sopenharmony_ci}
3048c2ecf20Sopenharmony_ci/**
3058c2ecf20Sopenharmony_ci * smack_log_callback - SMACK specific information
3068c2ecf20Sopenharmony_ci * will be called by generic audit code
3078c2ecf20Sopenharmony_ci * @ab : the audit_buffer
3088c2ecf20Sopenharmony_ci * @a  : audit_data
3098c2ecf20Sopenharmony_ci *
3108c2ecf20Sopenharmony_ci */
3118c2ecf20Sopenharmony_cistatic void smack_log_callback(struct audit_buffer *ab, void *a)
3128c2ecf20Sopenharmony_ci{
3138c2ecf20Sopenharmony_ci	struct common_audit_data *ad = a;
3148c2ecf20Sopenharmony_ci	struct smack_audit_data *sad = ad->smack_audit_data;
3158c2ecf20Sopenharmony_ci	audit_log_format(ab, "lsm=SMACK fn=%s action=%s",
3168c2ecf20Sopenharmony_ci			 ad->smack_audit_data->function,
3178c2ecf20Sopenharmony_ci			 sad->result ? "denied" : "granted");
3188c2ecf20Sopenharmony_ci	audit_log_format(ab, " subject=");
3198c2ecf20Sopenharmony_ci	audit_log_untrustedstring(ab, sad->subject);
3208c2ecf20Sopenharmony_ci	audit_log_format(ab, " object=");
3218c2ecf20Sopenharmony_ci	audit_log_untrustedstring(ab, sad->object);
3228c2ecf20Sopenharmony_ci	if (sad->request[0] == '\0')
3238c2ecf20Sopenharmony_ci		audit_log_format(ab, " labels_differ");
3248c2ecf20Sopenharmony_ci	else
3258c2ecf20Sopenharmony_ci		audit_log_format(ab, " requested=%s", sad->request);
3268c2ecf20Sopenharmony_ci}
3278c2ecf20Sopenharmony_ci
3288c2ecf20Sopenharmony_ci/**
3298c2ecf20Sopenharmony_ci *  smack_log - Audit the granting or denial of permissions.
3308c2ecf20Sopenharmony_ci *  @subject_label : smack label of the requester
3318c2ecf20Sopenharmony_ci *  @object_label  : smack label of the object being accessed
3328c2ecf20Sopenharmony_ci *  @request: requested permissions
3338c2ecf20Sopenharmony_ci *  @result: result from smk_access
3348c2ecf20Sopenharmony_ci *  @a:  auxiliary audit data
3358c2ecf20Sopenharmony_ci *
3368c2ecf20Sopenharmony_ci * Audit the granting or denial of permissions in accordance
3378c2ecf20Sopenharmony_ci * with the policy.
3388c2ecf20Sopenharmony_ci */
3398c2ecf20Sopenharmony_civoid smack_log(char *subject_label, char *object_label, int request,
3408c2ecf20Sopenharmony_ci	       int result, struct smk_audit_info *ad)
3418c2ecf20Sopenharmony_ci{
3428c2ecf20Sopenharmony_ci#ifdef CONFIG_SECURITY_SMACK_BRINGUP
3438c2ecf20Sopenharmony_ci	char request_buffer[SMK_NUM_ACCESS_TYPE + 5];
3448c2ecf20Sopenharmony_ci#else
3458c2ecf20Sopenharmony_ci	char request_buffer[SMK_NUM_ACCESS_TYPE + 1];
3468c2ecf20Sopenharmony_ci#endif
3478c2ecf20Sopenharmony_ci	struct smack_audit_data *sad;
3488c2ecf20Sopenharmony_ci	struct common_audit_data *a = &ad->a;
3498c2ecf20Sopenharmony_ci
3508c2ecf20Sopenharmony_ci	/* check if we have to log the current event */
3518c2ecf20Sopenharmony_ci	if (result < 0 && (log_policy & SMACK_AUDIT_DENIED) == 0)
3528c2ecf20Sopenharmony_ci		return;
3538c2ecf20Sopenharmony_ci	if (result == 0 && (log_policy & SMACK_AUDIT_ACCEPT) == 0)
3548c2ecf20Sopenharmony_ci		return;
3558c2ecf20Sopenharmony_ci
3568c2ecf20Sopenharmony_ci	sad = a->smack_audit_data;
3578c2ecf20Sopenharmony_ci
3588c2ecf20Sopenharmony_ci	if (sad->function == NULL)
3598c2ecf20Sopenharmony_ci		sad->function = "unknown";
3608c2ecf20Sopenharmony_ci
3618c2ecf20Sopenharmony_ci	/* end preparing the audit data */
3628c2ecf20Sopenharmony_ci	smack_str_from_perm(request_buffer, request);
3638c2ecf20Sopenharmony_ci	sad->subject = subject_label;
3648c2ecf20Sopenharmony_ci	sad->object  = object_label;
3658c2ecf20Sopenharmony_ci#ifdef CONFIG_SECURITY_SMACK_BRINGUP
3668c2ecf20Sopenharmony_ci	/*
3678c2ecf20Sopenharmony_ci	 * The result may be positive in bringup mode.
3688c2ecf20Sopenharmony_ci	 * A positive result is an allow, but not for normal reasons.
3698c2ecf20Sopenharmony_ci	 * Mark it as successful, but don't filter it out even if
3708c2ecf20Sopenharmony_ci	 * the logging policy says to do so.
3718c2ecf20Sopenharmony_ci	 */
3728c2ecf20Sopenharmony_ci	if (result == SMACK_UNCONFINED_SUBJECT)
3738c2ecf20Sopenharmony_ci		strcat(request_buffer, "(US)");
3748c2ecf20Sopenharmony_ci	else if (result == SMACK_UNCONFINED_OBJECT)
3758c2ecf20Sopenharmony_ci		strcat(request_buffer, "(UO)");
3768c2ecf20Sopenharmony_ci
3778c2ecf20Sopenharmony_ci	if (result > 0)
3788c2ecf20Sopenharmony_ci		result = 0;
3798c2ecf20Sopenharmony_ci#endif
3808c2ecf20Sopenharmony_ci	sad->request = request_buffer;
3818c2ecf20Sopenharmony_ci	sad->result  = result;
3828c2ecf20Sopenharmony_ci
3838c2ecf20Sopenharmony_ci	common_lsm_audit(a, smack_log_callback, NULL);
3848c2ecf20Sopenharmony_ci}
3858c2ecf20Sopenharmony_ci#else /* #ifdef CONFIG_AUDIT */
3868c2ecf20Sopenharmony_civoid smack_log(char *subject_label, char *object_label, int request,
3878c2ecf20Sopenharmony_ci               int result, struct smk_audit_info *ad)
3888c2ecf20Sopenharmony_ci{
3898c2ecf20Sopenharmony_ci}
3908c2ecf20Sopenharmony_ci#endif
3918c2ecf20Sopenharmony_ci
3928c2ecf20Sopenharmony_ciDEFINE_MUTEX(smack_known_lock);
3938c2ecf20Sopenharmony_ci
3948c2ecf20Sopenharmony_cistruct hlist_head smack_known_hash[SMACK_HASH_SLOTS];
3958c2ecf20Sopenharmony_ci
3968c2ecf20Sopenharmony_ci/**
3978c2ecf20Sopenharmony_ci * smk_insert_entry - insert a smack label into a hash map,
3988c2ecf20Sopenharmony_ci *
3998c2ecf20Sopenharmony_ci * this function must be called under smack_known_lock
4008c2ecf20Sopenharmony_ci */
4018c2ecf20Sopenharmony_civoid smk_insert_entry(struct smack_known *skp)
4028c2ecf20Sopenharmony_ci{
4038c2ecf20Sopenharmony_ci	unsigned int hash;
4048c2ecf20Sopenharmony_ci	struct hlist_head *head;
4058c2ecf20Sopenharmony_ci
4068c2ecf20Sopenharmony_ci	hash = full_name_hash(NULL, skp->smk_known, strlen(skp->smk_known));
4078c2ecf20Sopenharmony_ci	head = &smack_known_hash[hash & (SMACK_HASH_SLOTS - 1)];
4088c2ecf20Sopenharmony_ci
4098c2ecf20Sopenharmony_ci	hlist_add_head_rcu(&skp->smk_hashed, head);
4108c2ecf20Sopenharmony_ci	list_add_rcu(&skp->list, &smack_known_list);
4118c2ecf20Sopenharmony_ci}
4128c2ecf20Sopenharmony_ci
4138c2ecf20Sopenharmony_ci/**
4148c2ecf20Sopenharmony_ci * smk_find_entry - find a label on the list, return the list entry
4158c2ecf20Sopenharmony_ci * @string: a text string that might be a Smack label
4168c2ecf20Sopenharmony_ci *
4178c2ecf20Sopenharmony_ci * Returns a pointer to the entry in the label list that
4188c2ecf20Sopenharmony_ci * matches the passed string or NULL if not found.
4198c2ecf20Sopenharmony_ci */
4208c2ecf20Sopenharmony_cistruct smack_known *smk_find_entry(const char *string)
4218c2ecf20Sopenharmony_ci{
4228c2ecf20Sopenharmony_ci	unsigned int hash;
4238c2ecf20Sopenharmony_ci	struct hlist_head *head;
4248c2ecf20Sopenharmony_ci	struct smack_known *skp;
4258c2ecf20Sopenharmony_ci
4268c2ecf20Sopenharmony_ci	hash = full_name_hash(NULL, string, strlen(string));
4278c2ecf20Sopenharmony_ci	head = &smack_known_hash[hash & (SMACK_HASH_SLOTS - 1)];
4288c2ecf20Sopenharmony_ci
4298c2ecf20Sopenharmony_ci	hlist_for_each_entry_rcu(skp, head, smk_hashed)
4308c2ecf20Sopenharmony_ci		if (strcmp(skp->smk_known, string) == 0)
4318c2ecf20Sopenharmony_ci			return skp;
4328c2ecf20Sopenharmony_ci
4338c2ecf20Sopenharmony_ci	return NULL;
4348c2ecf20Sopenharmony_ci}
4358c2ecf20Sopenharmony_ci
4368c2ecf20Sopenharmony_ci/**
4378c2ecf20Sopenharmony_ci * smk_parse_smack - parse smack label from a text string
4388c2ecf20Sopenharmony_ci * @string: a text string that might contain a Smack label
4398c2ecf20Sopenharmony_ci * @len: the maximum size, or zero if it is NULL terminated.
4408c2ecf20Sopenharmony_ci *
4418c2ecf20Sopenharmony_ci * Returns a pointer to the clean label or an error code.
4428c2ecf20Sopenharmony_ci */
4438c2ecf20Sopenharmony_cichar *smk_parse_smack(const char *string, int len)
4448c2ecf20Sopenharmony_ci{
4458c2ecf20Sopenharmony_ci	char *smack;
4468c2ecf20Sopenharmony_ci	int i;
4478c2ecf20Sopenharmony_ci
4488c2ecf20Sopenharmony_ci	if (len <= 0)
4498c2ecf20Sopenharmony_ci		len = strlen(string) + 1;
4508c2ecf20Sopenharmony_ci
4518c2ecf20Sopenharmony_ci	/*
4528c2ecf20Sopenharmony_ci	 * Reserve a leading '-' as an indicator that
4538c2ecf20Sopenharmony_ci	 * this isn't a label, but an option to interfaces
4548c2ecf20Sopenharmony_ci	 * including /smack/cipso and /smack/cipso2
4558c2ecf20Sopenharmony_ci	 */
4568c2ecf20Sopenharmony_ci	if (string[0] == '-')
4578c2ecf20Sopenharmony_ci		return ERR_PTR(-EINVAL);
4588c2ecf20Sopenharmony_ci
4598c2ecf20Sopenharmony_ci	for (i = 0; i < len; i++)
4608c2ecf20Sopenharmony_ci		if (string[i] > '~' || string[i] <= ' ' || string[i] == '/' ||
4618c2ecf20Sopenharmony_ci		    string[i] == '"' || string[i] == '\\' || string[i] == '\'')
4628c2ecf20Sopenharmony_ci			break;
4638c2ecf20Sopenharmony_ci
4648c2ecf20Sopenharmony_ci	if (i == 0 || i >= SMK_LONGLABEL)
4658c2ecf20Sopenharmony_ci		return ERR_PTR(-EINVAL);
4668c2ecf20Sopenharmony_ci
4678c2ecf20Sopenharmony_ci	smack = kzalloc(i + 1, GFP_NOFS);
4688c2ecf20Sopenharmony_ci	if (smack == NULL)
4698c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
4708c2ecf20Sopenharmony_ci
4718c2ecf20Sopenharmony_ci	strncpy(smack, string, i);
4728c2ecf20Sopenharmony_ci
4738c2ecf20Sopenharmony_ci	return smack;
4748c2ecf20Sopenharmony_ci}
4758c2ecf20Sopenharmony_ci
4768c2ecf20Sopenharmony_ci/**
4778c2ecf20Sopenharmony_ci * smk_netlbl_mls - convert a catset to netlabel mls categories
4788c2ecf20Sopenharmony_ci * @catset: the Smack categories
4798c2ecf20Sopenharmony_ci * @sap: where to put the netlabel categories
4808c2ecf20Sopenharmony_ci *
4818c2ecf20Sopenharmony_ci * Allocates and fills attr.mls
4828c2ecf20Sopenharmony_ci * Returns 0 on success, error code on failure.
4838c2ecf20Sopenharmony_ci */
4848c2ecf20Sopenharmony_ciint smk_netlbl_mls(int level, char *catset, struct netlbl_lsm_secattr *sap,
4858c2ecf20Sopenharmony_ci			int len)
4868c2ecf20Sopenharmony_ci{
4878c2ecf20Sopenharmony_ci	unsigned char *cp;
4888c2ecf20Sopenharmony_ci	unsigned char m;
4898c2ecf20Sopenharmony_ci	int cat;
4908c2ecf20Sopenharmony_ci	int rc;
4918c2ecf20Sopenharmony_ci	int byte;
4928c2ecf20Sopenharmony_ci
4938c2ecf20Sopenharmony_ci	sap->flags |= NETLBL_SECATTR_MLS_CAT;
4948c2ecf20Sopenharmony_ci	sap->attr.mls.lvl = level;
4958c2ecf20Sopenharmony_ci	sap->attr.mls.cat = NULL;
4968c2ecf20Sopenharmony_ci
4978c2ecf20Sopenharmony_ci	for (cat = 1, cp = catset, byte = 0; byte < len; cp++, byte++)
4988c2ecf20Sopenharmony_ci		for (m = 0x80; m != 0; m >>= 1, cat++) {
4998c2ecf20Sopenharmony_ci			if ((m & *cp) == 0)
5008c2ecf20Sopenharmony_ci				continue;
5018c2ecf20Sopenharmony_ci			rc = netlbl_catmap_setbit(&sap->attr.mls.cat,
5028c2ecf20Sopenharmony_ci						  cat, GFP_NOFS);
5038c2ecf20Sopenharmony_ci			if (rc < 0) {
5048c2ecf20Sopenharmony_ci				netlbl_catmap_free(sap->attr.mls.cat);
5058c2ecf20Sopenharmony_ci				return rc;
5068c2ecf20Sopenharmony_ci			}
5078c2ecf20Sopenharmony_ci		}
5088c2ecf20Sopenharmony_ci
5098c2ecf20Sopenharmony_ci	return 0;
5108c2ecf20Sopenharmony_ci}
5118c2ecf20Sopenharmony_ci
5128c2ecf20Sopenharmony_ci/**
5138c2ecf20Sopenharmony_ci * smack_populate_secattr - fill in the smack_known netlabel information
5148c2ecf20Sopenharmony_ci * @skp: pointer to the structure to fill
5158c2ecf20Sopenharmony_ci *
5168c2ecf20Sopenharmony_ci * Populate the netlabel secattr structure for a Smack label.
5178c2ecf20Sopenharmony_ci *
5188c2ecf20Sopenharmony_ci * Returns 0 unless creating the category mapping fails
5198c2ecf20Sopenharmony_ci */
5208c2ecf20Sopenharmony_ciint smack_populate_secattr(struct smack_known *skp)
5218c2ecf20Sopenharmony_ci{
5228c2ecf20Sopenharmony_ci	int slen;
5238c2ecf20Sopenharmony_ci
5248c2ecf20Sopenharmony_ci	skp->smk_netlabel.attr.secid = skp->smk_secid;
5258c2ecf20Sopenharmony_ci	skp->smk_netlabel.domain = skp->smk_known;
5268c2ecf20Sopenharmony_ci	skp->smk_netlabel.cache = netlbl_secattr_cache_alloc(GFP_ATOMIC);
5278c2ecf20Sopenharmony_ci	if (skp->smk_netlabel.cache != NULL) {
5288c2ecf20Sopenharmony_ci		skp->smk_netlabel.flags |= NETLBL_SECATTR_CACHE;
5298c2ecf20Sopenharmony_ci		skp->smk_netlabel.cache->free = NULL;
5308c2ecf20Sopenharmony_ci		skp->smk_netlabel.cache->data = skp;
5318c2ecf20Sopenharmony_ci	}
5328c2ecf20Sopenharmony_ci	skp->smk_netlabel.flags |= NETLBL_SECATTR_SECID |
5338c2ecf20Sopenharmony_ci				   NETLBL_SECATTR_MLS_LVL |
5348c2ecf20Sopenharmony_ci				   NETLBL_SECATTR_DOMAIN;
5358c2ecf20Sopenharmony_ci	/*
5368c2ecf20Sopenharmony_ci	 * If direct labeling works use it.
5378c2ecf20Sopenharmony_ci	 * Otherwise use mapped labeling.
5388c2ecf20Sopenharmony_ci	 */
5398c2ecf20Sopenharmony_ci	slen = strlen(skp->smk_known);
5408c2ecf20Sopenharmony_ci	if (slen < SMK_CIPSOLEN)
5418c2ecf20Sopenharmony_ci		return smk_netlbl_mls(smack_cipso_direct, skp->smk_known,
5428c2ecf20Sopenharmony_ci				      &skp->smk_netlabel, slen);
5438c2ecf20Sopenharmony_ci
5448c2ecf20Sopenharmony_ci	return smk_netlbl_mls(smack_cipso_mapped, (char *)&skp->smk_secid,
5458c2ecf20Sopenharmony_ci			      &skp->smk_netlabel, sizeof(skp->smk_secid));
5468c2ecf20Sopenharmony_ci}
5478c2ecf20Sopenharmony_ci
5488c2ecf20Sopenharmony_ci/**
5498c2ecf20Sopenharmony_ci * smk_import_entry - import a label, return the list entry
5508c2ecf20Sopenharmony_ci * @string: a text string that might be a Smack label
5518c2ecf20Sopenharmony_ci * @len: the maximum size, or zero if it is NULL terminated.
5528c2ecf20Sopenharmony_ci *
5538c2ecf20Sopenharmony_ci * Returns a pointer to the entry in the label list that
5548c2ecf20Sopenharmony_ci * matches the passed string, adding it if necessary,
5558c2ecf20Sopenharmony_ci * or an error code.
5568c2ecf20Sopenharmony_ci */
5578c2ecf20Sopenharmony_cistruct smack_known *smk_import_entry(const char *string, int len)
5588c2ecf20Sopenharmony_ci{
5598c2ecf20Sopenharmony_ci	struct smack_known *skp;
5608c2ecf20Sopenharmony_ci	char *smack;
5618c2ecf20Sopenharmony_ci	int rc;
5628c2ecf20Sopenharmony_ci
5638c2ecf20Sopenharmony_ci	smack = smk_parse_smack(string, len);
5648c2ecf20Sopenharmony_ci	if (IS_ERR(smack))
5658c2ecf20Sopenharmony_ci		return ERR_CAST(smack);
5668c2ecf20Sopenharmony_ci
5678c2ecf20Sopenharmony_ci	mutex_lock(&smack_known_lock);
5688c2ecf20Sopenharmony_ci
5698c2ecf20Sopenharmony_ci	skp = smk_find_entry(smack);
5708c2ecf20Sopenharmony_ci	if (skp != NULL)
5718c2ecf20Sopenharmony_ci		goto freeout;
5728c2ecf20Sopenharmony_ci
5738c2ecf20Sopenharmony_ci	skp = kzalloc(sizeof(*skp), GFP_NOFS);
5748c2ecf20Sopenharmony_ci	if (skp == NULL) {
5758c2ecf20Sopenharmony_ci		skp = ERR_PTR(-ENOMEM);
5768c2ecf20Sopenharmony_ci		goto freeout;
5778c2ecf20Sopenharmony_ci	}
5788c2ecf20Sopenharmony_ci
5798c2ecf20Sopenharmony_ci	skp->smk_known = smack;
5808c2ecf20Sopenharmony_ci	skp->smk_secid = smack_next_secid++;
5818c2ecf20Sopenharmony_ci
5828c2ecf20Sopenharmony_ci	rc = smack_populate_secattr(skp);
5838c2ecf20Sopenharmony_ci	if (rc >= 0) {
5848c2ecf20Sopenharmony_ci		INIT_LIST_HEAD(&skp->smk_rules);
5858c2ecf20Sopenharmony_ci		mutex_init(&skp->smk_rules_lock);
5868c2ecf20Sopenharmony_ci		/*
5878c2ecf20Sopenharmony_ci		 * Make sure that the entry is actually
5888c2ecf20Sopenharmony_ci		 * filled before putting it on the list.
5898c2ecf20Sopenharmony_ci		 */
5908c2ecf20Sopenharmony_ci		smk_insert_entry(skp);
5918c2ecf20Sopenharmony_ci		goto unlockout;
5928c2ecf20Sopenharmony_ci	}
5938c2ecf20Sopenharmony_ci	kfree(skp);
5948c2ecf20Sopenharmony_ci	skp = ERR_PTR(rc);
5958c2ecf20Sopenharmony_cifreeout:
5968c2ecf20Sopenharmony_ci	kfree(smack);
5978c2ecf20Sopenharmony_ciunlockout:
5988c2ecf20Sopenharmony_ci	mutex_unlock(&smack_known_lock);
5998c2ecf20Sopenharmony_ci
6008c2ecf20Sopenharmony_ci	return skp;
6018c2ecf20Sopenharmony_ci}
6028c2ecf20Sopenharmony_ci
6038c2ecf20Sopenharmony_ci/**
6048c2ecf20Sopenharmony_ci * smack_from_secid - find the Smack label associated with a secid
6058c2ecf20Sopenharmony_ci * @secid: an integer that might be associated with a Smack label
6068c2ecf20Sopenharmony_ci *
6078c2ecf20Sopenharmony_ci * Returns a pointer to the appropriate Smack label entry if there is one,
6088c2ecf20Sopenharmony_ci * otherwise a pointer to the invalid Smack label.
6098c2ecf20Sopenharmony_ci */
6108c2ecf20Sopenharmony_cistruct smack_known *smack_from_secid(const u32 secid)
6118c2ecf20Sopenharmony_ci{
6128c2ecf20Sopenharmony_ci	struct smack_known *skp;
6138c2ecf20Sopenharmony_ci
6148c2ecf20Sopenharmony_ci	rcu_read_lock();
6158c2ecf20Sopenharmony_ci	list_for_each_entry_rcu(skp, &smack_known_list, list) {
6168c2ecf20Sopenharmony_ci		if (skp->smk_secid == secid) {
6178c2ecf20Sopenharmony_ci			rcu_read_unlock();
6188c2ecf20Sopenharmony_ci			return skp;
6198c2ecf20Sopenharmony_ci		}
6208c2ecf20Sopenharmony_ci	}
6218c2ecf20Sopenharmony_ci
6228c2ecf20Sopenharmony_ci	/*
6238c2ecf20Sopenharmony_ci	 * If we got this far someone asked for the translation
6248c2ecf20Sopenharmony_ci	 * of a secid that is not on the list.
6258c2ecf20Sopenharmony_ci	 */
6268c2ecf20Sopenharmony_ci	rcu_read_unlock();
6278c2ecf20Sopenharmony_ci	return &smack_known_huh;
6288c2ecf20Sopenharmony_ci}
6298c2ecf20Sopenharmony_ci
6308c2ecf20Sopenharmony_ci/*
6318c2ecf20Sopenharmony_ci * Unless a process is running with one of these labels
6328c2ecf20Sopenharmony_ci * even having CAP_MAC_OVERRIDE isn't enough to grant
6338c2ecf20Sopenharmony_ci * privilege to violate MAC policy. If no labels are
6348c2ecf20Sopenharmony_ci * designated (the empty list case) capabilities apply to
6358c2ecf20Sopenharmony_ci * everyone.
6368c2ecf20Sopenharmony_ci */
6378c2ecf20Sopenharmony_ciLIST_HEAD(smack_onlycap_list);
6388c2ecf20Sopenharmony_ciDEFINE_MUTEX(smack_onlycap_lock);
6398c2ecf20Sopenharmony_ci
6408c2ecf20Sopenharmony_ci/**
6418c2ecf20Sopenharmony_ci * smack_privileged_cred - are all privilege requirements met by cred
6428c2ecf20Sopenharmony_ci * @cap: The requested capability
6438c2ecf20Sopenharmony_ci * @cred: the credential to use
6448c2ecf20Sopenharmony_ci *
6458c2ecf20Sopenharmony_ci * Is the task privileged and allowed to be privileged
6468c2ecf20Sopenharmony_ci * by the onlycap rule.
6478c2ecf20Sopenharmony_ci *
6488c2ecf20Sopenharmony_ci * Returns true if the task is allowed to be privileged, false if it's not.
6498c2ecf20Sopenharmony_ci */
6508c2ecf20Sopenharmony_cibool smack_privileged_cred(int cap, const struct cred *cred)
6518c2ecf20Sopenharmony_ci{
6528c2ecf20Sopenharmony_ci	struct task_smack *tsp = smack_cred(cred);
6538c2ecf20Sopenharmony_ci	struct smack_known *skp = tsp->smk_task;
6548c2ecf20Sopenharmony_ci	struct smack_known_list_elem *sklep;
6558c2ecf20Sopenharmony_ci	int rc;
6568c2ecf20Sopenharmony_ci
6578c2ecf20Sopenharmony_ci	rc = cap_capable(cred, &init_user_ns, cap, CAP_OPT_NONE);
6588c2ecf20Sopenharmony_ci	if (rc)
6598c2ecf20Sopenharmony_ci		return false;
6608c2ecf20Sopenharmony_ci
6618c2ecf20Sopenharmony_ci	rcu_read_lock();
6628c2ecf20Sopenharmony_ci	if (list_empty(&smack_onlycap_list)) {
6638c2ecf20Sopenharmony_ci		rcu_read_unlock();
6648c2ecf20Sopenharmony_ci		return true;
6658c2ecf20Sopenharmony_ci	}
6668c2ecf20Sopenharmony_ci
6678c2ecf20Sopenharmony_ci	list_for_each_entry_rcu(sklep, &smack_onlycap_list, list) {
6688c2ecf20Sopenharmony_ci		if (sklep->smk_label == skp) {
6698c2ecf20Sopenharmony_ci			rcu_read_unlock();
6708c2ecf20Sopenharmony_ci			return true;
6718c2ecf20Sopenharmony_ci		}
6728c2ecf20Sopenharmony_ci	}
6738c2ecf20Sopenharmony_ci	rcu_read_unlock();
6748c2ecf20Sopenharmony_ci
6758c2ecf20Sopenharmony_ci	return false;
6768c2ecf20Sopenharmony_ci}
6778c2ecf20Sopenharmony_ci
6788c2ecf20Sopenharmony_ci/**
6798c2ecf20Sopenharmony_ci * smack_privileged - are all privilege requirements met
6808c2ecf20Sopenharmony_ci * @cap: The requested capability
6818c2ecf20Sopenharmony_ci *
6828c2ecf20Sopenharmony_ci * Is the task privileged and allowed to be privileged
6838c2ecf20Sopenharmony_ci * by the onlycap rule.
6848c2ecf20Sopenharmony_ci *
6858c2ecf20Sopenharmony_ci * Returns true if the task is allowed to be privileged, false if it's not.
6868c2ecf20Sopenharmony_ci */
6878c2ecf20Sopenharmony_cibool smack_privileged(int cap)
6888c2ecf20Sopenharmony_ci{
6898c2ecf20Sopenharmony_ci	/*
6908c2ecf20Sopenharmony_ci	 * Kernel threads may not have credentials we can use.
6918c2ecf20Sopenharmony_ci	 * The io_uring kernel threads do have reliable credentials.
6928c2ecf20Sopenharmony_ci	 */
6938c2ecf20Sopenharmony_ci	if ((current->flags & (PF_KTHREAD | PF_IO_WORKER)) == PF_KTHREAD)
6948c2ecf20Sopenharmony_ci		return true;
6958c2ecf20Sopenharmony_ci
6968c2ecf20Sopenharmony_ci	return smack_privileged_cred(cap, current_cred());
6978c2ecf20Sopenharmony_ci}
698