aboutsummaryrefslogtreecommitdiff
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/dummy.c25
-rw-r--r--security/keys/key.c56
-rw-r--r--security/keys/keyctl.c13
-rw-r--r--security/keys/keyring.c21
-rw-r--r--security/keys/permission.c7
-rw-r--r--security/keys/process_keys.c9
-rw-r--r--security/keys/user_defined.c49
-rw-r--r--security/selinux/hooks.c78
-rw-r--r--security/selinux/netif.c3
-rw-r--r--security/selinux/selinuxfs.c50
-rw-r--r--security/selinux/ss/conditional.c12
-rw-r--r--security/selinux/ss/ebitmap.c9
-rw-r--r--security/selinux/ss/hashtab.c6
-rw-r--r--security/selinux/ss/policydb.c51
-rw-r--r--security/selinux/ss/services.c11
15 files changed, 212 insertions, 188 deletions
diff --git a/security/dummy.c b/security/dummy.c
index 3d34f3de7e8..3ca5f2b828a 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -377,7 +377,7 @@ static int dummy_inode_removexattr (struct dentry *dentry, char *name)
return 0;
}
-static int dummy_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size)
+static int dummy_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err)
{
return -EOPNOTSUPP;
}
@@ -803,6 +803,23 @@ static int dummy_setprocattr(struct task_struct *p, char *name, void *value, siz
return -EINVAL;
}
+#ifdef CONFIG_KEYS
+static inline int dummy_key_alloc(struct key *key)
+{
+ return 0;
+}
+
+static inline void dummy_key_free(struct key *key)
+{
+}
+
+static inline int dummy_key_permission(key_ref_t key_ref,
+ struct task_struct *context,
+ key_perm_t perm)
+{
+ return 0;
+}
+#endif /* CONFIG_KEYS */
struct security_operations dummy_security_ops;
@@ -954,5 +971,11 @@ void security_fixup_ops (struct security_operations *ops)
set_to_dummy_if_null(ops, sk_alloc_security);
set_to_dummy_if_null(ops, sk_free_security);
#endif /* CONFIG_SECURITY_NETWORK */
+#ifdef CONFIG_KEYS
+ set_to_dummy_if_null(ops, key_alloc);
+ set_to_dummy_if_null(ops, key_free);
+ set_to_dummy_if_null(ops, key_permission);
+#endif /* CONFIG_KEYS */
+
}
diff --git a/security/keys/key.c b/security/keys/key.c
index 2182be9e930..ccde17aff61 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -1,6 +1,6 @@
/* key.c: basic authentication token and access key management
*
- * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
@@ -13,6 +13,7 @@
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/slab.h>
+#include <linux/security.h>
#include <linux/workqueue.h>
#include <linux/err.h>
#include "internal.h"
@@ -253,6 +254,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
struct key_user *user = NULL;
struct key *key;
size_t desclen, quotalen;
+ int ret;
key = ERR_PTR(-EINVAL);
if (!desc || !*desc)
@@ -305,6 +307,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
key->flags = 0;
key->expiry = 0;
key->payload.data = NULL;
+ key->security = NULL;
if (!not_in_quota)
key->flags |= 1 << KEY_FLAG_IN_QUOTA;
@@ -315,16 +318,34 @@ struct key *key_alloc(struct key_type *type, const char *desc,
key->magic = KEY_DEBUG_MAGIC;
#endif
+ /* let the security module know about the key */
+ ret = security_key_alloc(key);
+ if (ret < 0)
+ goto security_error;
+
/* publish the key by giving it a serial number */
atomic_inc(&user->nkeys);
key_alloc_serial(key);
- error:
+error:
return key;
- no_memory_3:
+security_error:
+ kfree(key->description);
+ kmem_cache_free(key_jar, key);
+ if (!not_in_quota) {
+ spin_lock(&user->lock);
+ user->qnkeys--;
+ user->qnbytes -= quotalen;
+ spin_unlock(&user->lock);
+ }
+ key_user_put(user);
+ key = ERR_PTR(ret);
+ goto error;
+
+no_memory_3:
kmem_cache_free(key_jar, key);
- no_memory_2:
+no_memory_2:
if (!not_in_quota) {
spin_lock(&user->lock);
user->qnkeys--;
@@ -332,11 +353,11 @@ struct key *key_alloc(struct key_type *type, const char *desc,
spin_unlock(&user->lock);
}
key_user_put(user);
- no_memory_1:
+no_memory_1:
key = ERR_PTR(-ENOMEM);
goto error;
- no_quota:
+no_quota:
spin_unlock(&user->lock);
key_user_put(user);
key = ERR_PTR(-EDQUOT);
@@ -556,6 +577,8 @@ static void key_cleanup(void *data)
key_check(key);
+ security_key_free(key);
+
/* deal with the user's key tracking and quota */
if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) {
spin_lock(&key->user->lock);
@@ -700,8 +723,8 @@ static inline key_ref_t __key_update(key_ref_t key_ref,
int ret;
/* need write permission on the key to update it */
- ret = -EACCES;
- if (!key_permission(key_ref, KEY_WRITE))
+ ret = key_permission(key_ref, KEY_WRITE);
+ if (ret < 0)
goto error;
ret = -EEXIST;
@@ -711,7 +734,6 @@ static inline key_ref_t __key_update(key_ref_t key_ref,
down_write(&key->sem);
ret = key->type->update(key, payload, plen);
-
if (ret == 0)
/* updating a negative key instantiates it */
clear_bit(KEY_FLAG_NEGATIVE, &key->flags);
@@ -768,9 +790,11 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
/* if we're going to allocate a new key, we're going to have
* to modify the keyring */
- key_ref = ERR_PTR(-EACCES);
- if (!key_permission(keyring_ref, KEY_WRITE))
+ ret = key_permission(keyring_ref, KEY_WRITE);
+ if (ret < 0) {
+ key_ref = ERR_PTR(ret);
goto error_3;
+ }
/* search for an existing key of the same type and description in the
* destination keyring
@@ -780,8 +804,8 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
goto found_matching_key;
/* decide on the permissions we want */
- perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK;
- perm |= KEY_USR_VIEW | KEY_USR_SEARCH | KEY_USR_LINK;
+ perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR;
+ perm |= KEY_USR_VIEW | KEY_USR_SEARCH | KEY_USR_LINK | KEY_USR_SETATTR;
if (ktype->read)
perm |= KEY_POS_READ | KEY_USR_READ;
@@ -840,16 +864,16 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen)
key_check(key);
/* the key must be writable */
- ret = -EACCES;
- if (!key_permission(key_ref, KEY_WRITE))
+ ret = key_permission(key_ref, KEY_WRITE);
+ if (ret < 0)
goto error;
/* attempt to update it if supported */
ret = -EOPNOTSUPP;
if (key->type->update) {
down_write(&key->sem);
- ret = key->type->update(key, payload, plen);
+ ret = key->type->update(key, payload, plen);
if (ret == 0)
/* updating a negative key instantiates it */
clear_bit(KEY_FLAG_NEGATIVE, &key->flags);
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 4c670ee6acf..b7a468fabdf 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -624,8 +624,8 @@ long keyctl_keyring_search(key_serial_t ringid,
/* link the resulting key to the destination keyring if we can */
if (dest_ref) {
- ret = -EACCES;
- if (!key_permission(key_ref, KEY_LINK))
+ ret = key_permission(key_ref, KEY_LINK);
+ if (ret < 0)
goto error6;
ret = key_link(key_ref_to_ptr(dest_ref), key_ref_to_ptr(key_ref));
@@ -676,8 +676,11 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen)
key = key_ref_to_ptr(key_ref);
/* see if we can read it directly */
- if (key_permission(key_ref, KEY_READ))
+ ret = key_permission(key_ref, KEY_READ);
+ if (ret == 0)
goto can_read_key;
+ if (ret != -EACCES)
+ goto error;
/* we can't; see if it's searchable from this process's keyrings
* - we automatically take account of the fact that it may be
@@ -726,7 +729,7 @@ long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid)
if (uid == (uid_t) -1 && gid == (gid_t) -1)
goto error;
- key_ref = lookup_user_key(NULL, id, 1, 1, 0);
+ key_ref = lookup_user_key(NULL, id, 1, 1, KEY_SETATTR);
if (IS_ERR(key_ref)) {
ret = PTR_ERR(key_ref);
goto error;
@@ -786,7 +789,7 @@ long keyctl_setperm_key(key_serial_t id, key_perm_t perm)
if (perm & ~(KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL))
goto error;
- key_ref = lookup_user_key(NULL, id, 1, 1, 0);
+ key_ref = lookup_user_key(NULL, id, 1, 1, KEY_SETATTR);
if (IS_ERR(key_ref)) {
ret = PTR_ERR(key_ref);
goto error;
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 0639396dd44..e1cc4dd7901 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -13,6 +13,7 @@
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/slab.h>
+#include <linux/security.h>
#include <linux/seq_file.h>
#include <linux/err.h>
#include <asm/uaccess.h>
@@ -309,7 +310,9 @@ struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
int ret;
keyring = key_alloc(&key_type_keyring, description,
- uid, gid, KEY_POS_ALL | KEY_USR_ALL, not_in_quota);
+ uid, gid,
+ (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
+ not_in_quota);
if (!IS_ERR(keyring)) {
ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL);
@@ -359,9 +362,11 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
key_check(keyring);
/* top keyring must have search permission to begin the search */
- key_ref = ERR_PTR(-EACCES);
- if (!key_task_permission(keyring_ref, context, KEY_SEARCH))
+ err = key_task_permission(keyring_ref, context, KEY_SEARCH);
+ if (err < 0) {
+ key_ref = ERR_PTR(err);
goto error;
+ }
key_ref = ERR_PTR(-ENOTDIR);
if (keyring->type != &key_type_keyring)
@@ -402,8 +407,8 @@ descend:
continue;
/* key must have search permissions */
- if (!key_task_permission(make_key_ref(key, possessed),
- context, KEY_SEARCH))
+ if (key_task_permission(make_key_ref(key, possessed),
+ context, KEY_SEARCH) < 0)
continue;
/* we set a different error code if we find a negative key */
@@ -430,7 +435,7 @@ ascend:
continue;
if (!key_task_permission(make_key_ref(key, possessed),
- context, KEY_SEARCH))
+ context, KEY_SEARCH) < 0)
continue;
/* stack the current position */
@@ -521,7 +526,7 @@ key_ref_t __keyring_search_one(key_ref_t keyring_ref,
(!key->type->match ||
key->type->match(key, description)) &&
key_permission(make_key_ref(key, possessed),
- perm) &&
+ perm) < 0 &&
!test_bit(KEY_FLAG_REVOKED, &key->flags)
)
goto found;
@@ -617,7 +622,7 @@ struct key *find_keyring_by_name(const char *name, key_serial_t bound)
continue;
if (!key_permission(make_key_ref(keyring, 0),
- KEY_SEARCH))
+ KEY_SEARCH) < 0)
continue;
/* found a potential candidate, but we still need to
diff --git a/security/keys/permission.c b/security/keys/permission.c
index 03db073ba45..e7f579c0eaf 100644
--- a/security/keys/permission.c
+++ b/security/keys/permission.c
@@ -10,6 +10,7 @@
*/
#include <linux/module.h>
+#include <linux/security.h>
#include "internal.h"
/*****************************************************************************/
@@ -63,7 +64,11 @@ use_these_perms:
kperm = kperm & perm & KEY_ALL;
- return kperm == perm;
+ if (kperm != perm)
+ return -EACCES;
+
+ /* let LSM be the final arbiter */
+ return security_key_permission(key_ref, context, perm);
} /* end key_task_permission() */
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index d42d2158ce1..566b1cc0118 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -39,7 +39,7 @@ struct key root_user_keyring = {
.type = &key_type_keyring,
.user = &root_key_user,
.sem = __RWSEM_INITIALIZER(root_user_keyring.sem),
- .perm = KEY_POS_ALL | KEY_USR_ALL,
+ .perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
.flags = 1 << KEY_FLAG_INSTANTIATED,
.description = "_uid.0",
#ifdef KEY_DEBUGGING
@@ -54,7 +54,7 @@ struct key root_session_keyring = {
.type = &key_type_keyring,
.user = &root_key_user,
.sem = __RWSEM_INITIALIZER(root_session_keyring.sem),
- .perm = KEY_POS_ALL | KEY_USR_ALL,
+ .perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
.flags = 1 << KEY_FLAG_INSTANTIATED,
.description = "_uid_ses.0",
#ifdef KEY_DEBUGGING
@@ -666,9 +666,8 @@ key_ref_t lookup_user_key(struct task_struct *context, key_serial_t id,
goto invalid_key;
/* check the permissions */
- ret = -EACCES;
-
- if (!key_task_permission(key_ref, context, perm))
+ ret = key_task_permission(key_ref, context, perm);
+ if (ret < 0)
goto invalid_key;
error:
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
index e446acba73d..cbda3b2780a 100644
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -15,18 +15,10 @@
#include <linux/slab.h>
#include <linux/seq_file.h>
#include <linux/err.h>
+#include <keys/user-type.h>
#include <asm/uaccess.h>
#include "internal.h"
-static int user_instantiate(struct key *key, const void *data, size_t datalen);
-static int user_duplicate(struct key *key, const struct key *source);
-static int user_update(struct key *key, const void *data, size_t datalen);
-static int user_match(const struct key *key, const void *criterion);
-static void user_destroy(struct key *key);
-static void user_describe(const struct key *user, struct seq_file *m);
-static long user_read(const struct key *key,
- char __user *buffer, size_t buflen);
-
/*
* user defined keys take an arbitrary string as the description and an
* arbitrary blob of data as the payload
@@ -42,19 +34,13 @@ struct key_type key_type_user = {
.read = user_read,
};
-struct user_key_payload {
- struct rcu_head rcu; /* RCU destructor */
- unsigned short datalen; /* length of this data */
- char data[0]; /* actual data */
-};
-
EXPORT_SYMBOL_GPL(key_type_user);
/*****************************************************************************/
/*
* instantiate a user defined key
*/
-static int user_instantiate(struct key *key, const void *data, size_t datalen)
+int user_instantiate(struct key *key, const void *data, size_t datalen)
{
struct user_key_payload *upayload;
int ret;
@@ -78,18 +64,20 @@ static int user_instantiate(struct key *key, const void *data, size_t datalen)
rcu_assign_pointer(key->payload.data, upayload);
ret = 0;
- error:
+error:
return ret;
} /* end user_instantiate() */
+EXPORT_SYMBOL_GPL(user_instantiate);
+
/*****************************************************************************/
/*
* duplicate a user defined key
* - both keys' semaphores are locked against further modification
* - the new key cannot yet be accessed
*/
-static int user_duplicate(struct key *key, const struct key *source)
+int user_duplicate(struct key *key, const struct key *source)
{
struct user_key_payload *upayload, *spayload;
int ret;
@@ -112,6 +100,8 @@ static int user_duplicate(struct key *key, const struct key *source)
} /* end user_duplicate() */
+EXPORT_SYMBOL_GPL(user_duplicate);
+
/*****************************************************************************/
/*
* dispose of the old data from an updated user defined key
@@ -131,7 +121,7 @@ static void user_update_rcu_disposal(struct rcu_head *rcu)
* update a user defined key
* - the key's semaphore is write-locked
*/
-static int user_update(struct key *key, const void *data, size_t datalen)
+int user_update(struct key *key, const void *data, size_t datalen)
{
struct user_key_payload *upayload, *zap;
int ret;
@@ -163,26 +153,30 @@ static int user_update(struct key *key, const void *data, size_t datalen)
call_rcu(&zap->rcu, user_update_rcu_disposal);
- error:
+error:
return ret;
} /* end user_update() */
+EXPORT_SYMBOL_GPL(user_update);
+
/*****************************************************************************/
/*
* match users on their name
*/
-static int user_match(const struct key *key, const void *description)
+int user_match(const struct key *key, const void *description)
{
return strcmp(key->description, description) == 0;
} /* end user_match() */
+EXPORT_SYMBOL_GPL(user_match);
+
/*****************************************************************************/
/*
* dispose of the data dangling from the corpse of a user
*/
-static void user_destroy(struct key *key)
+void user_destroy(struct key *key)
{
struct user_key_payload *upayload = key->payload.data;
@@ -190,11 +184,13 @@ static void user_destroy(struct key *key)
} /* end user_destroy() */
+EXPORT_SYMBOL_GPL(user_destroy);
+
/*****************************************************************************/
/*
* describe the user key
*/
-static void user_describe(const struct key *key, struct seq_file *m)
+void user_describe(const struct key *key, struct seq_file *m)
{
seq_puts(m, key->description);
@@ -202,13 +198,14 @@ static void user_describe(const struct key *key, struct seq_file *m)
} /* end user_describe() */
+EXPORT_SYMBOL_GPL(user_describe);
+
/*****************************************************************************/
/*
* read the key data
* - the key's semaphore is read-locked
*/
-static long user_read(const struct key *key,
- char __user *buffer, size_t buflen)
+long user_read(const struct key *key, char __user *buffer, size_t buflen)
{
struct user_key_payload *upayload;
long ret;
@@ -228,3 +225,5 @@ static long user_read(const struct key *key,
return ret;
} /* end user_read() */
+
+EXPORT_SYMBOL_GPL(user_read);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 447a1e0f48c..45c41490d52 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -122,11 +122,10 @@ static int task_alloc_security(struct task_struct *task)
{
struct task_security_struct *tsec;
- tsec = kmalloc(sizeof(struct task_security_struct), GFP_KERNEL);
+ tsec = kzalloc(sizeof(struct task_security_struct), GFP_KERNEL);
if (!tsec)
return -ENOMEM;
- memset(tsec, 0, sizeof(struct task_security_struct));
tsec->magic = SELINUX_MAGIC;
tsec->task = task;
tsec->osid = tsec->sid = tsec->ptrace_sid = SECINITSID_UNLABELED;
@@ -151,11 +150,10 @@ static int inode_alloc_security(struct inode *inode)
struct task_security_struct *tsec = current->security;
struct inode_security_struct *isec;
- isec = kmalloc(sizeof(struct inode_security_struct), GFP_KERNEL);
+ isec = kzalloc(sizeof(struct inode_security_struct), GFP_KERNEL);
if (!isec)
return -ENOMEM;
- memset(isec, 0, sizeof(struct inode_security_struct));
init_MUTEX(&isec->sem);
INIT_LIST_HEAD(&isec->list);
isec->magic = SELINUX_MAGIC;
@@ -193,11 +191,10 @@ static int file_alloc_security(struct file *file)
struct task_security_struct *tsec = current->security;
struct file_security_struct *fsec;
- fsec = kmalloc(sizeof(struct file_security_struct), GFP_ATOMIC);
+ fsec = kzalloc(sizeof(struct file_security_struct), GFP_ATOMIC);
if (!fsec)
return -ENOMEM;
- memset(fsec, 0, sizeof(struct file_security_struct));
fsec->magic = SELINUX_MAGIC;
fsec->file = file;
if (tsec && tsec->magic == SELINUX_MAGIC) {
@@ -227,11 +224,10 @@ static int superblock_alloc_security(struct super_block *sb)
{
struct superblock_security_struct *sbsec;
- sbsec = kmalloc(sizeof(struct superblock_security_struct), GFP_KERNEL);
+ sbsec = kzalloc(sizeof(struct superblock_security_struct), GFP_KERNEL);
if (!sbsec)
return -ENOMEM;
- memset(sbsec, 0, sizeof(struct superblock_security_struct));
init_MUTEX(&sbsec->sem);
INIT_LIST_HEAD(&sbsec->list);
INIT_LIST_HEAD(&sbsec->isec_head);
@@ -269,11 +265,10 @@ static int sk_alloc_security(struct sock *sk, int family, gfp_t priority)
if (family != PF_UNIX)
return 0;
- ssec = kmalloc(sizeof(*ssec), priority);
+ ssec = kzalloc(sizeof(*ssec), priority);
if (!ssec)
return -ENOMEM;
- memset(ssec, 0, sizeof(*ssec));
ssec->magic = SELINUX_MAGIC;
ssec->sk = sk;
ssec->peer_sid = SECINITSID_UNLABELED;
@@ -1483,11 +1478,10 @@ static int selinux_bprm_alloc_security(struct linux_binprm *bprm)
{
struct bprm_security_struct *bsec;
- bsec = kmalloc(sizeof(struct bprm_security_struct), GFP_KERNEL);
+ bsec = kzalloc(sizeof(struct bprm_security_struct), GFP_KERNEL);
if (!bsec)
return -ENOMEM;
- memset(bsec, 0, sizeof *bsec);
bsec->magic = SELINUX_MAGIC;
bsec->bprm = bprm;
bsec->sid = SECINITSID_UNLABELED;
@@ -1615,7 +1609,7 @@ static inline void flush_unauthorized_files(struct files_struct * files)
if (tty) {
file_list_lock();
- file = list_entry(tty->tty_files.next, typeof(*file), f_list);
+ file = list_entry(tty->tty_files.next, typeof(*file), f_u.fu_list);
if (file) {
/* Revalidate access to controlling tty.
Use inode_has_perm on the tty inode directly rather
@@ -2211,12 +2205,6 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, char *name,
static int selinux_inode_getxattr (struct dentry *dentry, char *name)
{
- struct inode *inode = dentry->d_inode;
- struct superblock_security_struct *sbsec = inode->i_sb->s_security;
-
- if (sbsec->behavior == SECURITY_FS_USE_MNTPOINT)
- return -EOPNOTSUPP;
-
return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);
}
@@ -2247,33 +2235,54 @@ static int selinux_inode_removexattr (struct dentry *dentry, char *name)
return -EACCES;
}
-static int selinux_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size)
+/*
+ * Copy the in-core inode security context value to the user. If the
+ * getxattr() prior to this succeeded, check to see if we need to
+ * canonicalize the value to be finally returned to the user.
+ *
+ * Permission check is handled by selinux_inode_getxattr hook.
+ */
+static int selinux_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err)
{
struct inode_security_struct *isec = inode->i_security;
char *context;
unsigned len;
int rc;
- /* Permission check handled by selinux_inode_getxattr hook.*/
-
- if (strcmp(name, XATTR_SELINUX_SUFFIX))
- return -EOPNOTSUPP;
+ if (strcmp(name, XATTR_SELINUX_SUFFIX)) {
+ rc = -EOPNOTSUPP;
+ goto out;
+ }
rc = security_sid_to_context(isec->sid, &context, &len);
if (rc)
- return rc;
+ goto out;
+ /* Probe for required buffer size */
if (!buffer || !size) {
- kfree(context);
- return len;
+ rc = len;
+ goto out_free;
}
+
if (size < len) {
- kfree(context);
- return -ERANGE;
+ rc = -ERANGE;
+ goto out_free;
+ }
+
+ if (err > 0) {
+ if ((len == err) && !(memcmp(context, buffer, len))) {
+ /* Don't need to canonicalize value */
+ rc = err;
+ goto out_free;
+ }
+ memset(buffer, 0, size);
}
memcpy(buffer, context, len);
+ rc = len;
+out_free:
kfree(context);
- return len;
+out:
+ return rc;
}
static int selinux_inode_setsecurity(struct inode *inode, const char *name,
@@ -2704,8 +2713,7 @@ static int selinux_task_kill(struct task_struct *p, struct siginfo *info, int si
if (rc)
return rc;
- if (info && ((unsigned long)info == 1 ||
- (unsigned long)info == 2 || SI_FROMKERNEL(info)))
+ if (info != SEND_SIG_NOINFO && (is_si_special(info) || SI_FROMKERNEL(info)))
return 0;
if (!sig)
@@ -3599,11 +3607,10 @@ static int ipc_alloc_security(struct task_struct *task,
struct task_security_struct *tsec = task->security;
struct ipc_security_struct *isec;
- isec = kmalloc(sizeof(struct ipc_security_struct), GFP_KERNEL);
+ isec = kzalloc(sizeof(struct ipc_security_struct), GFP_KERNEL);
if (!isec)
return -ENOMEM;
- memset(isec, 0, sizeof(struct ipc_security_struct));
isec->magic = SELINUX_MAGIC;
isec->sclass = sclass;
isec->ipc_perm = perm;
@@ -3631,11 +3638,10 @@ static int msg_msg_alloc_security(struct msg_msg *msg)
{
struct msg_security_struct *msec;
- msec = kmalloc(sizeof(struct msg_security_struct), GFP_KERNEL);
+ msec = kzalloc(sizeof(struct msg_security_struct), GFP_KERNEL);
if (!msec)
return -ENOMEM;
- memset(msec, 0, sizeof(struct msg_security_struct));
msec->magic = SELINUX_MAGIC;
msec->msg = msg;
msec->sid = SECINITSID_UNLABELED;
diff --git a/security/selinux/netif.c b/security/selinux/netif.c
index 718d7be9f4d..b10c34e8a74 100644
--- a/security/selinux/netif.c
+++ b/security/selinux/netif.c
@@ -114,13 +114,12 @@ static struct sel_netif *sel_netif_lookup(struct net_device *dev)
if (likely(netif != NULL))
goto out;
- new = kmalloc(sizeof(*new), GFP_ATOMIC);
+ new = kzalloc(sizeof(*new), GFP_ATOMIC);
if (!new) {
netif = ERR_PTR(-ENOMEM);
goto out;
}
- memset(new, 0, sizeof(*new));
nsec = &new->nsec;
ret = security_netif_sid(dev->name, &nsec->if_sid, &nsec->msg_sid);
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index a45cc971e73..fdc38238972 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -105,7 +105,7 @@ static ssize_t sel_write_enforce(struct file * file, const char __user * buf,
ssize_t length;
int new_value;
- if (count < 0 || count >= PAGE_SIZE)
+ if (count >= PAGE_SIZE)
return -ENOMEM;
if (*ppos != 0) {
/* No partial writes. */
@@ -155,7 +155,7 @@ static ssize_t sel_write_disable(struct file * file, const char __user * buf,
int new_value;
extern int selinux_disable(void);
- if (count < 0 || count >= PAGE_SIZE)
+ if (count >= PAGE_SIZE)
return -ENOMEM;
if (*ppos != 0) {
/* No partial writes. */
@@ -242,7 +242,7 @@ static ssize_t sel_write_load(struct file * file, const char __user * buf,
goto out;
}
- if ((count < 0) || (count > 64 * 1024 * 1024)
+ if ((count > 64 * 1024 * 1024)
|| (data = vmalloc(count)) == NULL) {
length = -ENOMEM;
goto out;
@@ -284,7 +284,7 @@ static ssize_t sel_write_context(struct file * file, const char __user * buf,
if (length)
return length;
- if (count < 0 || count >= PAGE_SIZE)
+ if (count >= PAGE_SIZE)
return -ENOMEM;
if (*ppos != 0) {
/* No partial writes. */
@@ -332,7 +332,7 @@ static ssize_t sel_write_checkreqprot(struct file * file, const char __user * bu
if (length)
return length;
- if (count < 0 || count >= PAGE_SIZE)
+ if (count >= PAGE_SIZE)
return -ENOMEM;
if (*ppos != 0) {
/* No partial writes. */
@@ -424,15 +424,13 @@ static ssize_t sel_write_access(struct file * file, char *buf, size_t size)
return length;
length = -ENOMEM;
- scon = kmalloc(size+1, GFP_KERNEL);
+ scon = kzalloc(size+1, GFP_KERNEL);
if (!scon)
return length;
- memset(scon, 0, size+1);
- tcon = kmalloc(size+1, GFP_KERNEL);
+ tcon = kzalloc(size+1, GFP_KERNEL);
if (!tcon)
goto out;
- memset(tcon, 0, size+1);
length = -EINVAL;
if (sscanf(buf, "%s %s %hu %x", scon, tcon, &tclass, &req) != 4)
@@ -475,15 +473,13 @@ static ssize_t sel_write_create(struct file * file, char *buf, size_t size)
return length;
length = -ENOMEM;
- scon = kmalloc(size+1, GFP_KERNEL);
+ scon = kzalloc(size+1, GFP_KERNEL);
if (!scon)
return length;
- memset(scon, 0, size+1);
- tcon = kmalloc(size+1, GFP_KERNEL);
+ tcon = kzalloc(size+1, GFP_KERNEL);
if (!tcon)
goto out;
- memset(tcon, 0, size+1);
length = -EINVAL;
if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
@@ -536,15 +532,13 @@ static ssize_t sel_write_relabel(struct file * file, char *buf, size_t size)
return length;
length = -ENOMEM;
- scon = kmalloc(size+1, GFP_KERNEL);
+ scon = kzalloc(size+1, GFP_KERNEL);
if (!scon)
return length;
- memset(scon, 0, size+1);
- tcon = kmalloc(size+1, GFP_KERNEL);
+ tcon = kzalloc(size+1, GFP_KERNEL);
if (!tcon)
goto out;
- memset(tcon, 0, size+1);
length = -EINVAL;
if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
@@ -595,15 +589,13 @@ static ssize_t sel_write_user(struct file * file, char *buf, size_t size)
return length;
length = -ENOMEM;
- con = kmalloc(size+1, GFP_KERNEL);
+ con = kzalloc(size+1, GFP_KERNEL);
if (!con)
return length;
- memset(con, 0, size+1);
- user = kmalloc(size+1, GFP_KERNEL);
+ user = kzalloc(size+1, GFP_KERNEL);
if (!user)
goto out;
- memset(user, 0, size+1);
length = -EINVAL;
if (sscanf(buf, "%s %s", con, user) != 2)
@@ -658,15 +650,13 @@ static ssize_t sel_write_member(struct file * file, char *buf, size_t size)
return length;
length = -ENOMEM;
- scon = kmalloc(size+1, GFP_KERNEL);
+ scon = kzalloc(size+1, GFP_KERNEL);
if (!scon)
return length;
- memset(scon, 0, size+1);
- tcon = kmalloc(size+1, GFP_KERNEL);
+ tcon = kzalloc(size+1, GFP_KERNEL);
if (!tcon)
goto out;
- memset(tcon, 0, size+1);
length = -EINVAL;
if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
@@ -739,7 +729,7 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf,
if (!filep->f_op)
goto out;
- if (count < 0 || count > PAGE_SIZE) {
+ if (count > PAGE_SIZE) {
ret = -EINVAL;
goto out;
}
@@ -800,7 +790,7 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
if (!filep->f_op)
goto out;
- if (count < 0 || count >= PAGE_SIZE) {
+ if (count >= PAGE_SIZE) {
length = -ENOMEM;
goto out;
}
@@ -858,7 +848,7 @@ static ssize_t sel_commit_bools_write(struct file *filep,
if (!filep->f_op)
goto out;
- if (count < 0 || count >= PAGE_SIZE) {
+ if (count >= PAGE_SIZE) {
length = -ENOMEM;
goto out;
}
@@ -924,7 +914,7 @@ static void sel_remove_bools(struct dentry *de)
file_list_lock();
list_for_each(p, &sb->s_files) {
- struct file * filp = list_entry(p, struct file, f_list);
+ struct file * filp = list_entry(p, struct file, f_u.fu_list);
struct dentry * dentry = filp->f_dentry;
if (dentry->d_parent != de) {
@@ -1032,7 +1022,7 @@ static ssize_t sel_write_avc_cache_threshold(struct file * file,
ssize_t ret;
int new_value;
- if (count < 0 || count >= PAGE_SIZE) {
+ if (count >= PAGE_SIZE) {
ret = -ENOMEM;
goto out;
}
diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c
index daf28800746..d2737edba54 100644
--- a/security/selinux/ss/conditional.c
+++ b/security/selinux/ss/conditional.c
@@ -220,10 +220,9 @@ int cond_read_bool(struct policydb *p, struct hashtab *h, void *fp)
u32 len;
int rc;
- booldatum = kmalloc(sizeof(struct cond_bool_datum), GFP_KERNEL);
+ booldatum = kzalloc(sizeof(struct cond_bool_datum), GFP_KERNEL);
if (!booldatum)
return -1;
- memset(booldatum, 0, sizeof(struct cond_bool_datum));
rc = next_entry(buf, fp, sizeof buf);
if (rc < 0)
@@ -321,10 +320,9 @@ static int cond_insertf(struct avtab *a, struct avtab_key *k, struct avtab_datum
goto err;
}
- list = kmalloc(sizeof(struct cond_av_list), GFP_KERNEL);
+ list = kzalloc(sizeof(struct cond_av_list), GFP_KERNEL);
if (!list)
goto err;
- memset(list, 0, sizeof(*list));
list->node = node_ptr;
if (!data->head)
@@ -414,11 +412,10 @@ static int cond_read_node(struct policydb *p, struct cond_node *node, void *fp)
if (rc < 0)
goto err;
- expr = kmalloc(sizeof(struct cond_expr), GFP_KERNEL);
+ expr = kzalloc(sizeof(struct cond_expr), GFP_KERNEL);
if (!expr) {
goto err;
}
- memset(expr, 0, sizeof(struct cond_expr));
expr->expr_type = le32_to_cpu(buf[0]);
expr->bool = le32_to_cpu(buf[1]);
@@ -460,10 +457,9 @@ int cond_read_list(struct policydb *p, void *fp)
len = le32_to_cpu(buf[0]);
for (i = 0; i < len; i++) {
- node = kmalloc(sizeof(struct cond_node), GFP_KERNEL);
+ node = kzalloc(sizeof(struct cond_node), GFP_KERNEL);
if (!node)
goto err;
- memset(node, 0, sizeof(struct cond_node));
if (cond_read_node(p, node, fp) != 0)
goto err;
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c
index d515154128c..47024a6e184 100644
--- a/security/selinux/ss/ebitmap.c
+++ b/security/selinux/ss/ebitmap.c
@@ -39,12 +39,11 @@ int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src)
n = src->node;
prev = NULL;
while (n) {
- new = kmalloc(sizeof(*new), GFP_ATOMIC);
+ new = kzalloc(sizeof(*new), GFP_ATOMIC);
if (!new) {
ebitmap_destroy(dst);
return -ENOMEM;
}
- memset(new, 0, sizeof(*new));
new->startbit = n->startbit;
new->map = n->map;
new->next = NULL;
@@ -150,10 +149,9 @@ int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value)
if (!value)
return 0;
- new = kmalloc(sizeof(*new), GFP_ATOMIC);
+ new = kzalloc(sizeof(*new), GFP_ATOMIC);
if (!new)
return -ENOMEM;
- memset(new, 0, sizeof(*new));
new->startbit = bit & ~(MAPSIZE - 1);
new->map = (MAPBIT << (bit - new->startbit));
@@ -232,13 +230,12 @@ int ebitmap_read(struct ebitmap *e, void *fp)
printk(KERN_ERR "security: ebitmap: truncated map\n");
goto bad;
}
- n = kmalloc(sizeof(*n), GFP_KERNEL);
+ n = kzalloc(sizeof(*n), GFP_KERNEL);
if (!n) {
printk(KERN_ERR "security: ebitmap: out of memory\n");
rc = -ENOMEM;
goto bad;
}
- memset(n, 0, sizeof(*n));
n->startbit = le32_to_cpu(buf[0]);
diff --git a/security/selinux/ss/hashtab.c b/security/selinux/ss/hashtab.c
index 26661fcc00c..24e5ec95763 100644
--- a/security/selinux/ss/hashtab.c
+++ b/security/selinux/ss/hashtab.c
@@ -15,11 +15,10 @@ struct hashtab *hashtab_create(u32 (*hash_value)(struct hashtab *h, void *key),
struct hashtab *p;
u32 i;
- p = kmalloc(sizeof(*p), GFP_KERNEL);
+ p = kzalloc(sizeof(*p), GFP_KERNEL);
if (p == NULL)
return p;
- memset(p, 0, sizeof(*p));
p->size = size;
p->nel = 0;
p->hash_value = hash_value;
@@ -55,10 +54,9 @@ int hashtab_insert(struct hashtab *h, void *key, void *datum)
if (cur && (h->keycmp(h, key, cur->key) == 0))
return -EEXIST;
- newnode = kmalloc(sizeof(*newnode), GFP_KERNEL);
+ newnode = kzalloc(sizeof(*newnode), GFP_KERNEL);
if (newnode == NULL)
return -ENOMEM;
- memset(newnode, 0, sizeof(*newnode));
newnode->key = key;
newnode->datum = datum;
if (prev) {
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 8e6262d12aa..2f5f539875f 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -121,12 +121,11 @@ static int roles_init(struct policydb *p)
int rc;
struct role_datum *role;
- role = kmalloc(sizeof(*role), GFP_KERNEL);
+ role = kzalloc(sizeof(*role), GFP_KERNEL);
if (!role) {
rc = -ENOMEM;
goto out;
}
- memset(role, 0, sizeof(*role));
role->value = ++p->p_roles.nprim;
if (role->value != OBJECT_R_VAL) {
rc = -EINVAL;
@@ -851,12 +850,11 @@ static int perm_read(struct policydb *p, struct hashtab *h, void *fp)
__le32 buf[2];
u32 len;
- perdatum = kmalloc(sizeof(*perdatum), GFP_KERNEL);
+ perdatum = kzalloc(sizeof(*perdatum), GFP_KERNEL);
if (!perdatum) {
rc = -ENOMEM;
goto out;
}
- memset(perdatum, 0, sizeof(*perdatum));
rc = next_entry(buf, fp, sizeof buf);
if (rc < 0)
@@ -893,12 +891,11 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp)
u32 len, nel;
int i, rc;
- comdatum = kmalloc(sizeof(*comdatum), GFP_KERNEL);
+ comdatum = kzalloc(sizeof(*comdatum), GFP_KERNEL);
if (!comdatum) {
rc = -ENOMEM;
goto out;
}
- memset(comdatum, 0, sizeof(*comdatum));
rc = next_entry(buf, fp, sizeof buf);
if (rc < 0)
@@ -950,10 +947,9 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons,
lc = NULL;
for (i = 0; i < ncons; i++) {
- c = kmalloc(sizeof(*c), GFP_KERNEL);
+ c = kzalloc(sizeof(*c), GFP_KERNEL);
if (!c)
return -ENOMEM;
- memset(c, 0, sizeof(*c));
if (lc) {
lc->next = c;
@@ -969,10 +965,9 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons,
le = NULL;
depth = -1;
for (j = 0; j < nexpr; j++) {
- e = kmalloc(sizeof(*e), GFP_KERNEL);
+ e = kzalloc(sizeof(*e), GFP_KERNEL);
if (!e)
return -ENOMEM;
- memset(e, 0, sizeof(*e));
if (le) {
le->next = e;
@@ -1033,12 +1028,11 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
u32 len, len2, ncons, nel;
int i, rc;
- cladatum = kmalloc(sizeof(*cladatum), GFP_KERNEL);
+ cladatum = kzalloc(sizeof(*cladatum), GFP_KERNEL);
if (!cladatum) {
rc = -ENOMEM;
goto out;
}
- memset(cladatum, 0, sizeof(*cladatum));
rc = next_entry(buf, fp, sizeof(u32)*6);
if (rc < 0)
@@ -1127,12 +1121,11 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
__le32 buf[2];
u32 len;
- role = kmalloc(sizeof(*role), GFP_KERNEL);
+ role = kzalloc(sizeof(*role), GFP_KERNEL);
if (!role) {
rc = -ENOMEM;
goto out;
}
- memset(role, 0, sizeof(*role));
rc = next_entry(buf, fp, sizeof buf);
if (rc < 0)
@@ -1188,12 +1181,11 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp)
__le32 buf[3];
u32 len;
- typdatum = kmalloc(sizeof(*typdatum),GFP_KERNEL);
+ typdatum = kzalloc(sizeof(*typdatum),GFP_KERNEL);
if (!typdatum) {
rc = -ENOMEM;
return rc;
}
- memset(typdatum, 0, sizeof(*typdatum));
rc = next_entry(buf, fp, sizeof buf);
if (rc < 0)
@@ -1261,12 +1253,11 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp)
__le32 buf[2];
u32 len;
- usrdatum = kmalloc(sizeof(*usrdatum), GFP_KERNEL);
+ usrdatum = kzalloc(sizeof(*usrdatum), GFP_KERNEL);
if (!usrdatum) {
rc = -ENOMEM;
goto out;
}
- memset(usrdatum, 0, sizeof(*usrdatum));
rc = next_entry(buf, fp, sizeof buf);
if (rc < 0)
@@ -1316,12 +1307,11 @@ static int sens_read(struct policydb *p, struct hashtab *h, void *fp)
__le32 buf[2];
u32 len;
- levdatum = kmalloc(sizeof(*levdatum), GFP_ATOMIC);
+ levdatum = kzalloc(sizeof(*levdatum), GFP_ATOMIC);
if (!levdatum) {
rc = -ENOMEM;
goto out;
}
- memset(levdatum, 0, sizeof(*levdatum));
rc = next_entry(buf, fp, sizeof buf);
if (rc < 0)
@@ -1368,12 +1358,11 @@ static int cat_read(struct policydb *p, struct hashtab *h, void *fp)
__le32 buf[3];
u32 len;
- catdatum = kmalloc(sizeof(*catdatum), GFP_ATOMIC);
+ catdatum = kzalloc(sizeof(*catdatum), GFP_ATOMIC);
if (!catdatum) {
rc = -ENOMEM;
goto out;
}
- memset(catdatum, 0, sizeof(*catdatum));
rc = next_entry(buf, fp, sizeof buf);
if (rc < 0)
@@ -1567,12 +1556,11 @@ int policydb_read(struct policydb *p, void *fp)
nel = le32_to_cpu(buf[0]);
ltr = NULL;
for (i = 0; i < nel; i++) {
- tr = kmalloc(sizeof(*tr), GFP_KERNEL);
+ tr = kzalloc(sizeof(*tr), GFP_KERNEL);
if (!tr) {
rc = -ENOMEM;
goto bad;
}
- memset(tr, 0, sizeof(*tr));
if (ltr) {
ltr->next = tr;
} else {
@@ -1593,12 +1581,11 @@ int policydb_read(struct policydb *p, void *fp)
nel = le32_to_cpu(buf[0]);
lra = NULL;
for (i = 0; i < nel; i++) {
- ra = kmalloc(sizeof(*ra), GFP_KERNEL);
+ ra = kzalloc(sizeof(*ra), GFP_KERNEL);
if (!ra) {
rc = -ENOMEM;
goto bad;
}
- memset(ra, 0, sizeof(*ra));
if (lra) {
lra->next = ra;
} else {
@@ -1627,12 +1614,11 @@ int policydb_read(struct policydb *p, void *fp)
nel = le32_to_cpu(buf[0]);
l = NULL;
for (j = 0; j < nel; j++) {
- c = kmalloc(sizeof(*c), GFP_KERNEL);
+ c = kzalloc(sizeof(*c), GFP_KERNEL);
if (!c) {
rc = -ENOMEM;
goto bad;
}
- memset(c, 0, sizeof(*c));
if (l) {
l->next = c;
} else {
@@ -1743,12 +1729,11 @@ int policydb_read(struct policydb *p, void *fp)
if (rc < 0)
goto bad;
len = le32_to_cpu(buf[0]);
- newgenfs = kmalloc(sizeof(*newgenfs), GFP_KERNEL);
+ newgenfs = kzalloc(sizeof(*newgenfs), GFP_KERNEL);
if (!newgenfs) {
rc = -ENOMEM;
goto bad;
}
- memset(newgenfs, 0, sizeof(*newgenfs));
newgenfs->fstype = kmalloc(len + 1,GFP_KERNEL);
if (!newgenfs->fstype) {
@@ -1790,12 +1775,11 @@ int policydb_read(struct policydb *p, void *fp)
goto bad;
len = le32_to_cpu(buf[0]);
- newc = kmalloc(sizeof(*newc), GFP_KERNEL);
+ newc = kzalloc(sizeof(*newc), GFP_KERNEL);
if (!newc) {
rc = -ENOMEM;
goto bad;
}
- memset(newc, 0, sizeof(*newc));
newc->u.name = kmalloc(len + 1,GFP_KERNEL);
if (!newc->u.name) {
@@ -1843,12 +1827,11 @@ int policydb_read(struct policydb *p, void *fp)
nel = le32_to_cpu(buf[0]);
lrt = NULL;
for (i = 0; i < nel; i++) {
- rt = kmalloc(sizeof(*rt), GFP_KERNEL);
+ rt = kzalloc(sizeof(*rt), GFP_KERNEL);
if (!rt) {
rc = -ENOMEM;
goto bad;
}
- memset(rt, 0, sizeof(*rt));
if (lrt)
lrt->next = rt;
else
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index aecdded55e7..44eb4d74908 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -1531,12 +1531,11 @@ int security_get_user_sids(u32 fromsid,
}
usercon.user = user->value;
- mysids = kmalloc(maxnel*sizeof(*mysids), GFP_ATOMIC);
+ mysids = kcalloc(maxnel, sizeof(*mysids), GFP_ATOMIC);
if (!mysids) {
rc = -ENOMEM;
goto out_unlock;
}
- memset(mysids, 0, maxnel*sizeof(*mysids));
ebitmap_for_each_bit(&user->roles, rnode, i) {
if (!ebitmap_node_get_bit(rnode, i))
@@ -1566,13 +1565,12 @@ int security_get_user_sids(u32 fromsid,
mysids[mynel++] = sid;
} else {
maxnel += SIDS_NEL;
- mysids2 = kmalloc(maxnel*sizeof(*mysids2), GFP_ATOMIC);
+ mysids2 = kcalloc(maxnel, sizeof(*mysids2), GFP_ATOMIC);
if (!mysids2) {
rc = -ENOMEM;
kfree(mysids);
goto out_unlock;
}
- memset(mysids2, 0, maxnel*sizeof(*mysids2));
memcpy(mysids2, mysids, mynel * sizeof(*mysids2));
kfree(mysids);
mysids = mysids2;
@@ -1714,12 +1712,11 @@ int security_get_bools(int *len, char ***names, int **values)
goto out;
}
- *names = (char**)kmalloc(sizeof(char*) * *len, GFP_ATOMIC);
+ *names = (char**)kcalloc(*len, sizeof(char*), GFP_ATOMIC);
if (!*names)
goto err;
- memset(*names, 0, sizeof(char*) * *len);
- *values = (int*)kmalloc(sizeof(int) * *len, GFP_ATOMIC);
+ *values = (int*)kcalloc(*len, sizeof(int), GFP_ATOMIC);
if (!*values)
goto err;