Skip to content

Commit

Permalink
Merge tag 'selinux-pr-20200803' of git://git.kernel.org/pub/scm/linux…
Browse files Browse the repository at this point in the history
…/kernel/git/pcmoore/selinux

Pull selinux updates from Paul Moore:
 "Beyond the usual smattering of bug fixes, we've got three small
  improvements worth highlighting:

   - improved SELinux policy symbol table performance due to a reworking
     of the insert and search functions

   - allow reading of SELinux labels before the policy is loaded,
     allowing for some more "exotic" initramfs approaches

   - improved checking an error reporting about process
     class/permissions during SELinux policy load"

* tag 'selinux-pr-20200803' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux:
  selinux: complete the inlining of hashtab functions
  selinux: prepare for inlining of hashtab functions
  selinux: specialize symtab insert and search functions
  selinux: Fix spelling mistakes in the comments
  selinux: fixed a checkpatch warning with the sizeof macro
  selinux: log error messages on required process class / permissions
  scripts/selinux/mdp: fix initial SID handling
  selinux: allow reading labels before policy is loaded
  • Loading branch information
torvalds committed Aug 4, 2020
2 parents 9ecc6ea + 54b27f9 commit 49e917d
Show file tree
Hide file tree
Showing 15 changed files with 258 additions and 166 deletions.
23 changes: 18 additions & 5 deletions scripts/selinux/mdp/mdp.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,14 @@ int main(int argc, char *argv[])

initial_sid_to_string_len = sizeof(initial_sid_to_string) / sizeof (char *);
/* print out the sids */
for (i = 1; i < initial_sid_to_string_len; i++)
fprintf(fout, "sid %s\n", initial_sid_to_string[i]);
for (i = 1; i < initial_sid_to_string_len; i++) {
const char *name = initial_sid_to_string[i];

if (name)
fprintf(fout, "sid %s\n", name);
else
fprintf(fout, "sid unused%d\n", i);
}
fprintf(fout, "\n");

/* print out the class permissions */
Expand Down Expand Up @@ -126,9 +132,16 @@ int main(int argc, char *argv[])
#define OBJUSERROLETYPE "user_u:object_r:base_t"

/* default sids */
for (i = 1; i < initial_sid_to_string_len; i++)
fprintf(fout, "sid %s " SUBJUSERROLETYPE "%s\n",
initial_sid_to_string[i], mls ? ":" SYSTEMLOW : "");
for (i = 1; i < initial_sid_to_string_len; i++) {
const char *name = initial_sid_to_string[i];

if (name)
fprintf(fout, "sid %s ", name);
else
fprintf(fout, "sid unused%d\n", i);
fprintf(fout, SUBJUSERROLETYPE "%s\n",
mls ? ":" SYSTEMLOW : "");
}
fprintf(fout, "\n");

#define FS_USE(behavior, fstype) \
Expand Down
7 changes: 6 additions & 1 deletion security/selinux/hooks.c
Original file line number Diff line number Diff line change
Expand Up @@ -3332,7 +3332,12 @@ static int selinux_inode_getsecurity(struct inode *inode, const char *name, void
char *context = NULL;
struct inode_security_struct *isec;

if (strcmp(name, XATTR_SELINUX_SUFFIX))
/*
* If we're not initialized yet, then we can't validate contexts, so
* just let vfs_getxattr fall back to using the on-disk xattr.
*/
if (!selinux_initialized(&selinux_state) ||
strcmp(name, XATTR_SELINUX_SUFFIX))
return -EOPNOTSUPP;

/*
Expand Down
2 changes: 1 addition & 1 deletion security/selinux/netif.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ static void sel_netif_destroy(struct sel_netif *netif)
* @sid: interface SID
*
* Description:
* This function determines the SID of a network interface by quering the
* This function determines the SID of a network interface by querying the
* security policy. The result is added to the network interface table to
* speedup future queries. Returns zero on success, negative values on
* failure.
Expand Down
2 changes: 1 addition & 1 deletion security/selinux/netnode.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ static void sel_netnode_insert(struct sel_netnode *node)
* @sid: node SID
*
* Description:
* This function determines the SID of a network address by quering the
* This function determines the SID of a network address by querying the
* security policy. The result is added to the network address table to
* speedup future queries. Returns zero on success, negative values on
* failure.
Expand Down
2 changes: 1 addition & 1 deletion security/selinux/netport.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ static void sel_netport_insert(struct sel_netport *port)
* @sid: port SID
*
* Description:
* This function determines the SID of a network port by quering the security
* This function determines the SID of a network port by querying the security
* policy. The result is added to the network port table to speedup future
* queries. Returns zero on success, negative values on failure.
*
Expand Down
8 changes: 4 additions & 4 deletions security/selinux/ss/conditional.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ static int bool_isvalid(struct cond_bool_datum *b)
return 1;
}

int cond_read_bool(struct policydb *p, struct hashtab *h, void *fp)
int cond_read_bool(struct policydb *p, struct symtab *s, void *fp)
{
char *key = NULL;
struct cond_bool_datum *booldatum;
Expand All @@ -215,7 +215,7 @@ int cond_read_bool(struct policydb *p, struct hashtab *h, void *fp)
if (!booldatum)
return -ENOMEM;

rc = next_entry(buf, fp, sizeof buf);
rc = next_entry(buf, fp, sizeof(buf));
if (rc)
goto err;

Expand All @@ -238,7 +238,7 @@ int cond_read_bool(struct policydb *p, struct hashtab *h, void *fp)
if (rc)
goto err;
key[len] = '\0';
rc = hashtab_insert(h, key, booldatum);
rc = symtab_insert(s, key, booldatum);
if (rc)
goto err;

Expand Down Expand Up @@ -416,7 +416,7 @@ int cond_read_list(struct policydb *p, void *fp)
u32 i, len;
int rc;

rc = next_entry(buf, fp, sizeof buf);
rc = next_entry(buf, fp, sizeof(buf));
if (rc)
return rc;

Expand Down
2 changes: 1 addition & 1 deletion security/selinux/ss/conditional.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ int cond_destroy_bool(void *key, void *datum, void *p);

int cond_index_bool(void *key, void *datum, void *datap);

int cond_read_bool(struct policydb *p, struct hashtab *h, void *fp);
int cond_read_bool(struct policydb *p, struct symtab *s, void *fp);
int cond_read_list(struct policydb *p, void *fp);
int cond_write_bool(void *key, void *datum, void *ptr);
int cond_write_list(struct policydb *p, void *fp);
Expand Down
59 changes: 6 additions & 53 deletions security/selinux/ss/hashtab.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include "hashtab.h"

static struct kmem_cache *hashtab_node_cachep;
Expand All @@ -29,80 +28,34 @@ static u32 hashtab_compute_size(u32 nel)
return nel == 0 ? 0 : roundup_pow_of_two(nel);
}

int hashtab_init(struct hashtab *h,
u32 (*hash_value)(struct hashtab *h, const void *key),
int (*keycmp)(struct hashtab *h, const void *key1,
const void *key2),
u32 nel_hint)
int hashtab_init(struct hashtab *h, u32 nel_hint)
{
h->size = hashtab_compute_size(nel_hint);
h->nel = 0;
h->hash_value = hash_value;
h->keycmp = keycmp;
if (!h->size)
return 0;

h->htable = kcalloc(h->size, sizeof(*h->htable), GFP_KERNEL);
return h->htable ? 0 : -ENOMEM;
}

int hashtab_insert(struct hashtab *h, void *key, void *datum)
int __hashtab_insert(struct hashtab *h, struct hashtab_node **dst,
void *key, void *datum)
{
u32 hvalue;
struct hashtab_node *prev, *cur, *newnode;

cond_resched();

if (!h->size || h->nel == HASHTAB_MAX_NODES)
return -EINVAL;

hvalue = h->hash_value(h, key);
prev = NULL;
cur = h->htable[hvalue];
while (cur && h->keycmp(h, key, cur->key) > 0) {
prev = cur;
cur = cur->next;
}

if (cur && (h->keycmp(h, key, cur->key) == 0))
return -EEXIST;
struct hashtab_node *newnode;

newnode = kmem_cache_zalloc(hashtab_node_cachep, GFP_KERNEL);
if (!newnode)
return -ENOMEM;
newnode->key = key;
newnode->datum = datum;
if (prev) {
newnode->next = prev->next;
prev->next = newnode;
} else {
newnode->next = h->htable[hvalue];
h->htable[hvalue] = newnode;
}
newnode->next = *dst;
*dst = newnode;

h->nel++;
return 0;
}

void *hashtab_search(struct hashtab *h, const void *key)
{
u32 hvalue;
struct hashtab_node *cur;

if (!h->size)
return NULL;

hvalue = h->hash_value(h, key);
cur = h->htable[hvalue];
while (cur && h->keycmp(h, key, cur->key) > 0)
cur = cur->next;

if (!cur || (h->keycmp(h, key, cur->key) != 0))
return NULL;

return cur->datum;
}

void hashtab_destroy(struct hashtab *h)
{
u32 i;
Expand Down
77 changes: 65 additions & 12 deletions security/selinux/ss/hashtab.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,17 @@
#ifndef _SS_HASHTAB_H_
#define _SS_HASHTAB_H_

#define HASHTAB_MAX_NODES 0xffffffff
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/sched.h>

#define HASHTAB_MAX_NODES U32_MAX

struct hashtab_key_params {
u32 (*hash)(const void *key); /* hash function */
int (*cmp)(const void *key1, const void *key2);
/* key comparison function */
};

struct hashtab_node {
void *key;
Expand All @@ -23,10 +33,6 @@ struct hashtab {
struct hashtab_node **htable; /* hash table */
u32 size; /* number of slots in hash table */
u32 nel; /* number of elements in hash table */
u32 (*hash_value)(struct hashtab *h, const void *key);
/* hash function */
int (*keycmp)(struct hashtab *h, const void *key1, const void *key2);
/* key comparison function */
};

struct hashtab_info {
Expand All @@ -39,11 +45,10 @@ struct hashtab_info {
*
* Returns -ENOMEM if insufficient space is available or 0 otherwise.
*/
int hashtab_init(struct hashtab *h,
u32 (*hash_value)(struct hashtab *h, const void *key),
int (*keycmp)(struct hashtab *h, const void *key1,
const void *key2),
u32 nel_hint);
int hashtab_init(struct hashtab *h, u32 nel_hint);

int __hashtab_insert(struct hashtab *h, struct hashtab_node **dst,
void *key, void *datum);

/*
* Inserts the specified (key, datum) pair into the specified hash table.
Expand All @@ -53,15 +58,63 @@ int hashtab_init(struct hashtab *h,
* -EINVAL for general errors or
0 otherwise.
*/
int hashtab_insert(struct hashtab *h, void *k, void *d);
static inline int hashtab_insert(struct hashtab *h, void *key, void *datum,
struct hashtab_key_params key_params)
{
u32 hvalue;
struct hashtab_node *prev, *cur;

cond_resched();

if (!h->size || h->nel == HASHTAB_MAX_NODES)
return -EINVAL;

hvalue = key_params.hash(key) & (h->size - 1);
prev = NULL;
cur = h->htable[hvalue];
while (cur) {
int cmp = key_params.cmp(key, cur->key);

if (cmp == 0)
return -EEXIST;
if (cmp < 0)
break;
prev = cur;
cur = cur->next;
}

return __hashtab_insert(h, prev ? &prev->next : &h->htable[hvalue],
key, datum);
}

/*
* Searches for the entry with the specified key in the hash table.
*
* Returns NULL if no entry has the specified key or
* the datum of the entry otherwise.
*/
void *hashtab_search(struct hashtab *h, const void *k);
static inline void *hashtab_search(struct hashtab *h, const void *key,
struct hashtab_key_params key_params)
{
u32 hvalue;
struct hashtab_node *cur;

if (!h->size)
return NULL;

hvalue = key_params.hash(key) & (h->size - 1);
cur = h->htable[hvalue];
while (cur) {
int cmp = key_params.cmp(key, cur->key);

if (cmp == 0)
return cur->datum;
if (cmp < 0)
break;
cur = cur->next;
}
return NULL;
}

/*
* Destroys the specified hash table.
Expand Down
Loading

0 comments on commit 49e917d

Please sign in to comment.