diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-10-13 16:29:55 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-10-13 16:29:55 -0700 |
commit | 7b540812cc0635e6c7e508359115c7cb6886fd2f (patch) | |
tree | a8e753d90bd36925a88dc9b86b5b1386bec6436c /security/selinux/ss/hashtab.c | |
parent | 01fb1e2f42d607ef5eb7a7ca54a0f0901fb5856c (diff) | |
parent | 0d50f059c4cdc9e436f6f4db8779ac0795bfdadf (diff) |
Merge tag 'selinux-pr-20201012' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux
Pull selinux updates from Paul Moore:
"A decent number of SELinux patches for v5.10, twenty two in total. The
highlights are listed below, but all of the patches pass our test
suite and merge cleanly.
- A number of changes to how the SELinux policy is loaded and managed
inside the kernel with the goal of improving the atomicity of a
SELinux policy load operation.
These changes account for the bulk of the diffstat as well as the
patch count. A special thanks to everyone who contributed patches
and fixes for this work.
- Convert the SELinux policy read-write lock to RCU.
- A tracepoint was added for audited SELinux access control events;
this should help provide a more unified backtrace across kernel and
userspace.
- Allow the removal of security.selinux xattrs when a SELinux policy
is not loaded.
- Enable policy capabilities in SELinux policies created with the
scripts/selinux/mdp tool.
- Provide some "no sooner than" dates for the SELinux checkreqprot
sysfs deprecation"
* tag 'selinux-pr-20201012' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux: (22 commits)
selinux: provide a "no sooner than" date for the checkreqprot removal
selinux: Add helper functions to get and set checkreqprot
selinux: access policycaps with READ_ONCE/WRITE_ONCE
selinux: simplify away security_policydb_len()
selinux: move policy mutex to selinux_state, use in lockdep checks
selinux: fix error handling bugs in security_load_policy()
selinux: convert policy read-write lock to RCU
selinux: delete repeated words in comments
selinux: add basic filtering for audit trace events
selinux: add tracepoint on audited events
selinux: Create new booleans and class dirs out of tree
selinux: Standardize string literal usage for selinuxfs directory names
selinux: Refactor selinuxfs directory populating functions
selinux: Create function for selinuxfs directory cleanup
selinux: permit removing security.selinux xattr before policy load
selinux: fix memdup.cocci warnings
selinux: avoid dereferencing the policy prior to initialization
selinux: fix allocation failure check on newpolicy->sidtab
selinux: refactor changing booleans
selinux: move policy commit after updating selinuxfs
...
Diffstat (limited to 'security/selinux/ss/hashtab.c')
-rw-r--r-- | security/selinux/ss/hashtab.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/security/selinux/ss/hashtab.c b/security/selinux/ss/hashtab.c index d9287bb4bfeb..dab8c25c739b 100644 --- a/security/selinux/ss/hashtab.c +++ b/security/selinux/ss/hashtab.c @@ -122,6 +122,59 @@ void hashtab_stat(struct hashtab *h, struct hashtab_info *info) info->max_chain_len = max_chain_len; } +int hashtab_duplicate(struct hashtab *new, struct hashtab *orig, + int (*copy)(struct hashtab_node *new, + struct hashtab_node *orig, void *args), + int (*destroy)(void *k, void *d, void *args), + void *args) +{ + struct hashtab_node *cur, *tmp, *tail; + int i, rc; + + memset(new, 0, sizeof(*new)); + + new->htable = kcalloc(orig->size, sizeof(*new->htable), GFP_KERNEL); + if (!new->htable) + return -ENOMEM; + + new->size = orig->size; + + for (i = 0; i < orig->size; i++) { + tail = NULL; + for (cur = orig->htable[i]; cur; cur = cur->next) { + tmp = kmem_cache_zalloc(hashtab_node_cachep, + GFP_KERNEL); + if (!tmp) + goto error; + rc = copy(tmp, cur, args); + if (rc) { + kmem_cache_free(hashtab_node_cachep, tmp); + goto error; + } + tmp->next = NULL; + if (!tail) + new->htable[i] = tmp; + else + tail->next = tmp; + tail = tmp; + new->nel++; + } + } + + return 0; + + error: + for (i = 0; i < new->size; i++) { + for (cur = new->htable[i]; cur; cur = tmp) { + tmp = cur->next; + destroy(cur->key, cur->datum, args); + kmem_cache_free(hashtab_node_cachep, cur); + } + } + kmem_cache_free(hashtab_node_cachep, new); + return -ENOMEM; +} + void __init hashtab_cache_init(void) { hashtab_node_cachep = kmem_cache_create("hashtab_node", |