Commit ca661c5e authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull selinux updates from Paul Moore:
 "Really only a few notable changes:

   - Continue the coding style/formatting fixup work

     This is the bulk of the diffstat in this pull request, with the
     focus this time around being the security/selinux/ss directory.

     We've only got a couple of files left to cleanup and once we're
     done with that we can start enabling some automatic style
     verfication and introduce tooling to help new folks format their
     code correctly.

   - Don't restrict xattr copy-up when SELinux policy is not loaded

     This helps systems that use overlayfs, or similar filesystems,
     preserve their SELinux labels during early boot when the SELinux
     policy has yet to be loaded.

   - Reduce the work we do during inode initialization time

     This isn't likely to show up in any benchmark results, but we
     removed an unnecessary SELinux object class lookup/calculation
     during inode initialization.

   - Correct the return values in selinux_socket_getpeersec_dgram()

     We had some inconsistencies with respect to our return values
     across selinux_socket_getpeersec_dgram() and
     selinux_socket_getpeersec_stream().

     This provides a more uniform set of error codes across the two
     functions and should help make it easier for users to identify
     the source of a failure"

* tag 'selinux-pr-20240312' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux: (24 commits)
  selinux: fix style issues in security/selinux/ss/symtab.c
  selinux: fix style issues in security/selinux/ss/symtab.h
  selinux: fix style issues in security/selinux/ss/sidtab.c
  selinux: fix style issues in security/selinux/ss/sidtab.h
  selinux: fix style issues in security/selinux/ss/services.h
  selinux: fix style issues in security/selinux/ss/policydb.c
  selinux: fix style issues in security/selinux/ss/policydb.h
  selinux: fix style issues in security/selinux/ss/mls_types.h
  selinux: fix style issues in security/selinux/ss/mls.c
  selinux: fix style issues in security/selinux/ss/mls.h
  selinux: fix style issues in security/selinux/ss/hashtab.c
  selinux: fix style issues in security/selinux/ss/hashtab.h
  selinux: fix style issues in security/selinux/ss/ebitmap.c
  selinux: fix style issues in security/selinux/ss/ebitmap.h
  selinux: fix style issues in security/selinux/ss/context.h
  selinux: fix style issues in security/selinux/ss/context.h
  selinux: fix style issues in security/selinux/ss/constraint.h
  selinux: fix style issues in security/selinux/ss/conditional.c
  selinux: fix style issues in security/selinux/ss/conditional.h
  selinux: fix style issues in security/selinux/ss/avtab.c
  ...
parents 9187210e a1fc7934
Loading
Loading
Loading
Loading
+15 −13
Original line number Diff line number Diff line
@@ -2920,23 +2920,22 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
	struct superblock_security_struct *sbsec;
	struct xattr *xattr = lsm_get_xattr_slot(xattrs, xattr_count);
	u32 newsid, clen;
	u16 newsclass;
	int rc;
	char *context;

	sbsec = selinux_superblock(dir->i_sb);

	newsid = tsec->create_sid;

	rc = selinux_determine_inode_label(tsec, dir, qstr,
		inode_mode_to_security_class(inode->i_mode),
		&newsid);
	newsclass = inode_mode_to_security_class(inode->i_mode);
	rc = selinux_determine_inode_label(tsec, dir, qstr, newsclass, &newsid);
	if (rc)
		return rc;

	/* Possibly defer initialization to selinux_complete_init. */
	if (sbsec->flags & SE_SBINITIALIZED) {
		struct inode_security_struct *isec = selinux_inode(inode);
		isec->sclass = inode_mode_to_security_class(inode->i_mode);
		isec->sclass = newsclass;
		isec->sid = newsid;
		isec->initialized = LABEL_INITIALIZED;
	}
@@ -3534,9 +3533,10 @@ static int selinux_inode_copy_up_xattr(const char *name)
{
	/* The copy_up hook above sets the initial context on an inode, but we
	 * don't then want to overwrite it by blindly copying all the lower
	 * xattrs up.  Instead, we have to filter out SELinux-related xattrs.
	 * xattrs up.  Instead, filter out SELinux-related xattrs following
	 * policy load.
	 */
	if (strcmp(name, XATTR_NAME_SELINUX) == 0)
	if (selinux_initialized() && strcmp(name, XATTR_NAME_SELINUX) == 0)
		return 1; /* Discard */
	/*
	 * Any other attribute apart from SELINUX is not claimed, supported
@@ -5194,11 +5194,11 @@ static int selinux_socket_getpeersec_stream(struct socket *sock,
	return err;
}

static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid)
static int selinux_socket_getpeersec_dgram(struct socket *sock,
					   struct sk_buff *skb, u32 *secid)
{
	u32 peer_secid = SECSID_NULL;
	u16 family;
	struct inode_security_struct *isec;

	if (skb && skb->protocol == htons(ETH_P_IP))
		family = PF_INET;
@@ -5206,19 +5206,21 @@ static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *
		family = PF_INET6;
	else if (sock)
		family = sock->sk->sk_family;
	else
		goto out;
	else {
		*secid = SECSID_NULL;
		return -EINVAL;
	}

	if (sock && family == PF_UNIX) {
		struct inode_security_struct *isec;
		isec = inode_security_novalidate(SOCK_INODE(sock));
		peer_secid = isec->sid;
	} else if (skb)
		selinux_skb_peerlbl_sid(skb, family, &peer_secid);

out:
	*secid = peer_secid;
	if (peer_secid == SECSID_NULL)
		return -EINVAL;
		return -ENOPROTOOPT;
	return 0;
}

+51 −54
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Implementation of the access vector table type.
 *
 * Author : Stephen Smalley, <stephen.smalley.work@gmail.com>
 */

/* Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com>
 *
/* Updated: Frank Mayer <mayerf@tresys.com> and
 *          Karl MacMillan <kmacmillan@tresys.com>
 *          Added conditional policy language extensions
 *
 *          Copyright (C) 2003 Tresys Technology, LLC
 *	This program is free software; you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License as published by
 *	the Free Software Foundation, version 2.
 *
 * Updated: Yuichi Nakamura <ynakam@hitachisoft.jp>
 *          Tuned number of hash slots for avtab to reduce memory usage
@@ -41,7 +38,8 @@ static inline u32 avtab_hash(const struct avtab_key *keyp, u32 mask)

	u32 hash = 0;

#define mix(input) do { \
#define mix(input)                                         \
	do {                                               \
		u32 v = input;                             \
		v *= c1;                                   \
		v = (v << r1) | (v >> (32 - r1));          \
@@ -66,9 +64,10 @@ static inline u32 avtab_hash(const struct avtab_key *keyp, u32 mask)
	return hash & mask;
}

static struct avtab_node*
avtab_insert_node(struct avtab *h, struct avtab_node **dst,
		  const struct avtab_key *key, const struct avtab_datum *datum)
static struct avtab_node *avtab_insert_node(struct avtab *h,
					    struct avtab_node **dst,
					    const struct avtab_key *key,
					    const struct avtab_datum *datum)
{
	struct avtab_node *newnode;
	struct avtab_extended_perms *xperms;
@@ -129,8 +128,7 @@ static int avtab_insert(struct avtab *h, const struct avtab_key *key,
		return -EINVAL;

	hvalue = avtab_hash(key, h->mask);
	for (prev = NULL, cur = h->htable[hvalue];
	     cur;
	for (prev = NULL, cur = h->htable[hvalue]; cur;
	     prev = cur, cur = cur->next) {
		cmp = avtab_node_cmp(key, &cur->key);
		/* extended perms may not be unique */
@@ -163,8 +161,7 @@ struct avtab_node *avtab_insert_nonunique(struct avtab *h,
	if (!h || !h->nslot || h->nel == U32_MAX)
		return NULL;
	hvalue = avtab_hash(key, h->mask);
	for (prev = NULL, cur = h->htable[hvalue];
	     cur;
	for (prev = NULL, cur = h->htable[hvalue]; cur;
	     prev = cur, cur = cur->next) {
		cmp = avtab_node_cmp(key, &cur->key);
		if (cmp <= 0)
@@ -188,8 +185,7 @@ struct avtab_node *avtab_search_node(struct avtab *h,
		return NULL;

	hvalue = avtab_hash(key, h->mask);
	for (cur = h->htable[hvalue]; cur;
	     cur = cur->next) {
	for (cur = h->htable[hvalue]; cur; cur = cur->next) {
		cmp = avtab_node_cmp(key, &cur->key);
		if (cmp == 0)
			return cur;
@@ -199,8 +195,8 @@ struct avtab_node *avtab_search_node(struct avtab *h,
	return NULL;
}

struct avtab_node*
avtab_search_node_next(struct avtab_node *node, u16 specified)
struct avtab_node *avtab_search_node_next(struct avtab_node *node,
					  u16 specified)
{
	struct avtab_key tmp_key;
	struct avtab_node *cur;
@@ -314,7 +310,8 @@ void avtab_hash_eval(struct avtab *h, const char *tag)

			if (chain_len > max_chain_len)
				max_chain_len = chain_len;
			chain2_len_sum += (unsigned long long)chain_len * chain_len;
			chain2_len_sum +=
				(unsigned long long)chain_len * chain_len;
		}
	}

@@ -325,6 +322,7 @@ void avtab_hash_eval(struct avtab *h, const char *tag)
}
#endif /* CONFIG_SECURITY_SELINUX_DEBUG */

/* clang-format off */
static const uint16_t spec_order[] = {
	AVTAB_ALLOWED,
	AVTAB_AUDITDENY,
@@ -336,6 +334,7 @@ static const uint16_t spec_order[] = {
	AVTAB_XPERMS_AUDITALLOW,
	AVTAB_XPERMS_DONTAUDIT
};
/* clang-format on */

int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol,
		    int (*insertf)(struct avtab *a, const struct avtab_key *k,
@@ -365,7 +364,6 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol,
		if (items2 > ARRAY_SIZE(buf32)) {
			pr_err("SELinux: avtab: entry overflow\n");
			return -EINVAL;

		}
		rc = next_entry(buf32, fp, sizeof(u32) * items2);
		if (rc) {
@@ -400,8 +398,7 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol,
			pr_err("SELinux: avtab: null entry\n");
			return -EINVAL;
		}
		if ((val & AVTAB_AV) &&
		    (val & AVTAB_TYPE)) {
		if ((val & AVTAB_AV) && (val & AVTAB_TYPE)) {
			pr_err("SELinux: avtab: entry has both access vectors and types\n");
			return -EINVAL;
		}
@@ -457,7 +454,8 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol,
	    (key.specified & AVTAB_XPERMS)) {
		pr_err("SELinux:  avtab:  policy version %u does not "
		       "support extended permissions rules and one "
				"was specified\n", vers);
		       "was specified\n",
		       vers);
		return -EINVAL;
	} else if (key.specified & AVTAB_XPERMS) {
		memset(&xperms, 0, sizeof(struct avtab_extended_perms));
@@ -471,7 +469,8 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol,
			pr_err("SELinux: avtab: truncated entry\n");
			return rc;
		}
		rc = next_entry(buf32, fp, sizeof(u32)*ARRAY_SIZE(xperms.perms.p));
		rc = next_entry(buf32, fp,
				sizeof(u32) * ARRAY_SIZE(xperms.perms.p));
		if (rc) {
			pr_err("SELinux: avtab: truncated entry\n");
			return rc;
@@ -507,7 +506,6 @@ int avtab_read(struct avtab *a, void *fp, struct policydb *pol)
	__le32 buf[1];
	u32 nel, i;


	rc = next_entry(buf, fp, sizeof(u32));
	if (rc < 0) {
		pr_err("SELinux: avtab: truncated table\n");
@@ -561,7 +559,8 @@ int avtab_write_item(struct policydb *p, const struct avtab_node *cur, void *fp)
		return rc;

	if (cur->key.specified & AVTAB_XPERMS) {
		rc = put_entry(&cur->datum.u.xperms->specified, sizeof(u8), 1, fp);
		rc = put_entry(&cur->datum.u.xperms->specified, sizeof(u8), 1,
			       fp);
		if (rc)
			return rc;
		rc = put_entry(&cur->datum.u.xperms->driver, sizeof(u8), 1, fp);
@@ -593,8 +592,7 @@ int avtab_write(struct policydb *p, struct avtab *a, void *fp)
		return rc;

	for (i = 0; i < a->nslot; i++) {
		for (cur = a->htable[i]; cur;
		     cur = cur->next) {
		for (cur = a->htable[i]; cur; cur = cur->next) {
			rc = avtab_write_item(p, cur, fp);
			if (rc)
				return rc;
@@ -606,10 +604,9 @@ int avtab_write(struct policydb *p, struct avtab *a, void *fp)

void __init avtab_cache_init(void)
{
	avtab_node_cachep = kmem_cache_create("avtab_node",
					      sizeof(struct avtab_node),
					      0, SLAB_PANIC, NULL);
	avtab_xperms_cachep = kmem_cache_create("avtab_extended_perms",
						sizeof(struct avtab_extended_perms),
						0, SLAB_PANIC, NULL);
	avtab_node_cachep = kmem_cache_create(
		"avtab_node", sizeof(struct avtab_node), 0, SLAB_PANIC, NULL);
	avtab_xperms_cachep = kmem_cache_create(
		"avtab_extended_perms", sizeof(struct avtab_extended_perms), 0,
		SLAB_PANIC, NULL);
}
+37 −37
Original line number Diff line number Diff line
@@ -9,15 +9,15 @@
 *  Author : Stephen Smalley, <stephen.smalley.work@gmail.com>
 */

/* Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com>
 *
/* Updated: Frank Mayer <mayerf@tresys.com> and
 *          Karl MacMillan <kmacmillan@tresys.com>
 *          Added conditional policy language extensions
 *
 *          Copyright (C) 2003 Tresys Technology, LLC
 *
 * Updated: Yuichi Nakamura <ynakam@hitachisoft.jp>
 *          Tuned number of hash slots for avtab to reduce memory usage
 */

#ifndef _SS_AVTAB_H_
#define _SS_AVTAB_H_

@@ -39,8 +39,8 @@ struct avtab_key {
#define AVTAB_XPERMS_ALLOWED	0x0100
#define AVTAB_XPERMS_AUDITALLOW 0x0200
#define AVTAB_XPERMS_DONTAUDIT	0x0400
#define AVTAB_XPERMS		(AVTAB_XPERMS_ALLOWED | \
				AVTAB_XPERMS_AUDITALLOW | \
#define AVTAB_XPERMS                                      \
	(AVTAB_XPERMS_ALLOWED | AVTAB_XPERMS_AUDITALLOW | \
	 AVTAB_XPERMS_DONTAUDIT)
#define AVTAB_ENABLED_OLD 0x80000000 /* reserved for used in cond_avtab */
#define AVTAB_ENABLED	  0x8000 /* reserved for used in cond_avtab */
@@ -92,6 +92,9 @@ int avtab_alloc(struct avtab *, u32);
int avtab_alloc_dup(struct avtab *new, const struct avtab *orig);
void avtab_destroy(struct avtab *h);

#define MAX_AVTAB_HASH_BITS    16
#define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS)

#ifdef CONFIG_SECURITY_SELINUX_DEBUG
void avtab_hash_eval(struct avtab *h, const char *tag);
#else
@@ -107,7 +110,8 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol,
		    void *p);

int avtab_read(struct avtab *a, void *fp, struct policydb *pol);
int avtab_write_item(struct policydb *p, const struct avtab_node *cur, void *fp);
int avtab_write_item(struct policydb *p, const struct avtab_node *cur,
		     void *fp);
int avtab_write(struct policydb *p, struct avtab *a, void *fp);

struct avtab_node *avtab_insert_nonunique(struct avtab *h,
@@ -116,11 +120,7 @@ struct avtab_node *avtab_insert_nonunique(struct avtab *h,

struct avtab_node *avtab_search_node(struct avtab *h,
				     const struct avtab_key *key);

struct avtab_node *avtab_search_node_next(struct avtab_node *node, u16 specified);

#define MAX_AVTAB_HASH_BITS 16
#define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS)
struct avtab_node *avtab_search_node_next(struct avtab_node *node,
					  u16 specified);

#endif /* _SS_AVTAB_H_ */
+33 −35
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/* SPDX-License-Identifier: GPL-2.0-only */
/* Authors: Karl MacMillan <kmacmillan@tresys.com>
 *	    Frank Mayer <mayerf@tresys.com>
 *
 *          Copyright (C) 2003 - 2004 Tresys Technology, LLC
 */

@@ -166,9 +165,8 @@ void cond_policydb_destroy(struct policydb *p)
int cond_init_bool_indexes(struct policydb *p)
{
	kfree(p->bool_val_to_struct);
	p->bool_val_to_struct = kmalloc_array(p->p_bools.nprim,
					      sizeof(*p->bool_val_to_struct),
					      GFP_KERNEL);
	p->bool_val_to_struct = kmalloc_array(
		p->p_bools.nprim, sizeof(*p->bool_val_to_struct), GFP_KERNEL);
	if (!p->bool_val_to_struct)
		return -ENOMEM;
	return 0;
@@ -287,7 +285,8 @@ static int cond_insertf(struct avtab *a, const struct avtab_key *k,
		if (other) {
			node_ptr = avtab_search_node(&p->te_cond_avtab, k);
			if (node_ptr) {
				if (avtab_search_node_next(node_ptr, k->specified)) {
				if (avtab_search_node_next(node_ptr,
							   k->specified)) {
					pr_err("SELinux: too many conflicting type rules.\n");
					return -EINVAL;
				}
@@ -478,8 +477,8 @@ int cond_write_bool(void *vkey, void *datum, void *ptr)
 * the conditional. This means that the avtab with the conditional
 * rules will not be saved but will be rebuilt on policy load.
 */
static int cond_write_av_list(struct policydb *p,
			      struct cond_av_list *list, struct policy_file *fp)
static int cond_write_av_list(struct policydb *p, struct cond_av_list *list,
			      struct policy_file *fp)
{
	__le32 buf[1];
	u32 i;
@@ -601,8 +600,7 @@ void cond_compute_av(struct avtab *ctab, struct avtab_key *key,
	}
}

static int cond_dup_av_list(struct cond_av_list *new,
			struct cond_av_list *orig,
static int cond_dup_av_list(struct cond_av_list *new, struct cond_av_list *orig,
			    struct avtab *avtab)
{
	u32 i;
@@ -614,9 +612,8 @@ static int cond_dup_av_list(struct cond_av_list *new,
		return -ENOMEM;

	for (i = 0; i < orig->len; i++) {
		new->nodes[i] = avtab_insert_nonunique(avtab,
						       &orig->nodes[i]->key,
						       &orig->nodes[i]->datum);
		new->nodes[i] = avtab_insert_nonunique(
			avtab, &orig->nodes[i]->key, &orig->nodes[i]->datum);
		if (!new->nodes[i])
			return -ENOMEM;
		new->len++;
@@ -637,8 +634,7 @@ static int duplicate_policydb_cond_list(struct policydb *newp,

	newp->cond_list_len = 0;
	newp->cond_list = kcalloc(origp->cond_list_len,
				sizeof(*newp->cond_list),
				GFP_KERNEL);
				  sizeof(*newp->cond_list), GFP_KERNEL);
	if (!newp->cond_list)
		goto error;

@@ -649,7 +645,8 @@ static int duplicate_policydb_cond_list(struct policydb *newp,
		newp->cond_list_len++;

		newn->cur_state = orign->cur_state;
		newn->expr.nodes = kmemdup(orign->expr.nodes,
		newn->expr.nodes =
			kmemdup(orign->expr.nodes,
				orign->expr.len * sizeof(*orign->expr.nodes),
				GFP_KERNEL);
		if (!newn->expr.nodes)
@@ -683,7 +680,8 @@ static int cond_bools_destroy(void *key, void *datum, void *args)
	return 0;
}

static int cond_bools_copy(struct hashtab_node *new, struct hashtab_node *orig, void *args)
static int cond_bools_copy(struct hashtab_node *new, struct hashtab_node *orig,
			   void *args)
{
	struct cond_bool_datum *datum;

+11 −12
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/* Authors: Karl MacMillan <kmacmillan@tresys.com>
 *          Frank Mayer <mayerf@tresys.com>
 *
 *          Copyright (C) 2003 - 2004 Tresys Technology, LLC
 */

Loading