summaryrefslogtreecommitdiff
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/Kconfig1
-rw-r--r--security/Kconfig.hardening10
-rw-r--r--security/apparmor/af_unix.c14
-rw-r--r--security/apparmor/apparmorfs.c8
-rw-r--r--security/apparmor/lsm.c5
-rw-r--r--security/integrity/Kconfig1
-rw-r--r--security/integrity/ima/ima_appraise.c23
-rw-r--r--security/keys/Kconfig17
-rw-r--r--security/keys/encrypted-keys/encrypted.c63
-rw-r--r--security/keys/process_keys.c2
-rw-r--r--security/keys/trusted-keys/Kconfig5
-rw-r--r--security/keys/trusted-keys/trusted_tpm1.c284
-rw-r--r--security/landlock/fs.c11
-rw-r--r--security/min_addr.c6
-rw-r--r--security/security.c116
-rw-r--r--security/selinux/avc.c13
-rw-r--r--security/selinux/hooks.c326
-rw-r--r--security/selinux/include/objsec.h42
-rw-r--r--security/selinux/include/policycap.h1
-rw-r--r--security/selinux/include/policycap_names.h1
-rw-r--r--security/selinux/include/security.h4
-rw-r--r--security/selinux/selinuxfs.c33
-rw-r--r--security/smack/smack_lsm.c7
-rw-r--r--security/tomoyo/tomoyo.c2
24 files changed, 494 insertions, 501 deletions
diff --git a/security/Kconfig b/security/Kconfig
index 4816fc74f81e..285f284dfcac 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -269,6 +269,7 @@ endchoice
config LSM
string "Ordered list of enabled LSMs"
+ depends on SECURITY
default "landlock,lockdown,yama,loadpin,safesetid,smack,selinux,tomoyo,apparmor,ipe,bpf" if DEFAULT_SECURITY_SMACK
default "landlock,lockdown,yama,loadpin,safesetid,apparmor,selinux,smack,tomoyo,ipe,bpf" if DEFAULT_SECURITY_APPARMOR
default "landlock,lockdown,yama,loadpin,safesetid,tomoyo,ipe,bpf" if DEFAULT_SECURITY_TOMOYO
diff --git a/security/Kconfig.hardening b/security/Kconfig.hardening
index b9a5bc3430aa..86f8768c63d4 100644
--- a/security/Kconfig.hardening
+++ b/security/Kconfig.hardening
@@ -255,6 +255,16 @@ config LIST_HARDENED
If unsure, say N.
+config RUST_BITMAP_HARDENED
+ bool "Check integrity of bitmap Rust API"
+ depends on RUST
+ help
+ Enables additional assertions in the Rust Bitmap API to catch
+ arguments that are not guaranteed to result in an immediate access
+ fault.
+
+ If unsure, say N.
+
config BUG_ON_DATA_CORRUPTION
bool "Trigger a BUG when data corruption is detected"
select LIST_HARDENED
diff --git a/security/apparmor/af_unix.c b/security/apparmor/af_unix.c
index 9129766d1e9c..ac0f4be791ec 100644
--- a/security/apparmor/af_unix.c
+++ b/security/apparmor/af_unix.c
@@ -31,7 +31,7 @@ static inline struct sock *aa_unix_sk(struct unix_sock *u)
}
static int unix_fs_perm(const char *op, u32 mask, const struct cred *subj_cred,
- struct aa_label *label, struct path *path)
+ struct aa_label *label, const struct path *path)
{
AA_BUG(!label);
AA_BUG(!path);
@@ -224,7 +224,7 @@ static int profile_create_perm(struct aa_profile *profile, int family,
static int profile_sk_perm(struct aa_profile *profile,
struct apparmor_audit_data *ad,
- u32 request, struct sock *sk, struct path *path)
+ u32 request, struct sock *sk, const struct path *path)
{
struct aa_ruleset *rules = profile->label.rules[0];
struct aa_perms *p = NULL;
@@ -386,9 +386,9 @@ static int profile_opt_perm(struct aa_profile *profile, u32 request,
/* null peer_label is allowed, in which case the peer_sk label is used */
static int profile_peer_perm(struct aa_profile *profile, u32 request,
- struct sock *sk, struct path *path,
+ struct sock *sk, const struct path *path,
struct sockaddr_un *peer_addr,
- int peer_addrlen, struct path *peer_path,
+ int peer_addrlen, const struct path *peer_path,
struct aa_label *peer_label,
struct apparmor_audit_data *ad)
{
@@ -445,7 +445,7 @@ int aa_unix_create_perm(struct aa_label *label, int family, int type,
static int aa_unix_label_sk_perm(const struct cred *subj_cred,
struct aa_label *label,
const char *op, u32 request, struct sock *sk,
- struct path *path)
+ const struct path *path)
{
if (!unconfined(label)) {
struct aa_profile *profile;
@@ -599,9 +599,9 @@ int aa_unix_opt_perm(const char *op, u32 request, struct socket *sock,
static int unix_peer_perm(const struct cred *subj_cred,
struct aa_label *label, const char *op, u32 request,
- struct sock *sk, struct path *path,
+ struct sock *sk, const struct path *path,
struct sockaddr_un *peer_addr, int peer_addrlen,
- struct path *peer_path, struct aa_label *peer_label)
+ const struct path *peer_path, struct aa_label *peer_label)
{
struct aa_profile *profile;
DEFINE_AUDIT_SK(ad, op, subj_cred, sk);
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index 391a586d0557..9d08d103f142 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -355,17 +355,17 @@ static void aafs_remove(struct dentry *dentry)
if (!dentry || IS_ERR(dentry))
return;
+ /* ->d_parent is stable as rename is not supported */
dir = d_inode(dentry->d_parent);
- inode_lock(dir);
- if (simple_positive(dentry)) {
+ dentry = start_removing_dentry(dentry->d_parent, dentry);
+ if (!IS_ERR(dentry) && simple_positive(dentry)) {
if (d_is_dir(dentry))
simple_rmdir(dir, dentry);
else
simple_unlink(dir, dentry);
d_delete(dentry);
- dput(dentry);
}
- inode_unlock(dir);
+ end_removing(dentry);
simple_release_fs(&aafs_mnt, &aafs_count);
}
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 8e1cc229b41b..b3f7a3258a2c 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -112,7 +112,7 @@ static void apparmor_task_free(struct task_struct *task)
}
static int apparmor_task_alloc(struct task_struct *task,
- unsigned long clone_flags)
+ u64 clone_flags)
{
struct aa_task_ctx *new = task_ctx(task);
@@ -2530,6 +2530,9 @@ static int __init apparmor_init(void)
security_add_hooks(apparmor_hooks, ARRAY_SIZE(apparmor_hooks),
&apparmor_lsmid);
+ /* Inform the audit system that secctx is used */
+ audit_cfg_lsm(&apparmor_lsmid, AUDIT_CFG_LSM_SECCTX_SUBJECT);
+
/* Report that AppArmor successfully initialized */
apparmor_initialized = 1;
if (aa_g_profile_mode == APPARMOR_COMPLAIN)
diff --git a/security/integrity/Kconfig b/security/integrity/Kconfig
index 3c45f4f3455f..916d4f2bfc44 100644
--- a/security/integrity/Kconfig
+++ b/security/integrity/Kconfig
@@ -36,6 +36,7 @@ config INTEGRITY_ASYMMETRIC_KEYS
default n
select ASYMMETRIC_KEY_TYPE
select ASYMMETRIC_PUBLIC_KEY_SUBTYPE
+ select CRYPTO
select CRYPTO_RSA
select X509_CERTIFICATE_PARSER
help
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index f435eff4667f..5149ff4fd50d 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -694,6 +694,15 @@ static int ima_protect_xattr(struct dentry *dentry, const char *xattr_name,
return 0;
}
+/*
+ * ima_reset_appraise_flags - reset ima_iint_cache flags
+ *
+ * @digsig: whether to clear/set IMA_DIGSIG flag, tristate values
+ * 0: clear IMA_DIGSIG
+ * 1: set IMA_DIGSIG
+ * -1: don't change IMA_DIGSIG
+ *
+ */
static void ima_reset_appraise_flags(struct inode *inode, int digsig)
{
struct ima_iint_cache *iint;
@@ -706,9 +715,9 @@ static void ima_reset_appraise_flags(struct inode *inode, int digsig)
return;
iint->measured_pcrs = 0;
set_bit(IMA_CHANGE_XATTR, &iint->atomic_flags);
- if (digsig)
+ if (digsig == 1)
set_bit(IMA_DIGSIG, &iint->atomic_flags);
- else
+ else if (digsig == 0)
clear_bit(IMA_DIGSIG, &iint->atomic_flags);
}
@@ -794,6 +803,8 @@ static int ima_inode_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
digsig = (xvalue->type == EVM_IMA_XATTR_DIGSIG);
} else if (!strcmp(xattr_name, XATTR_NAME_EVM) && xattr_value_len > 0) {
digsig = (xvalue->type == EVM_XATTR_PORTABLE_DIGSIG);
+ } else {
+ digsig = -1;
}
if (result == 1 || evm_revalidate_status(xattr_name)) {
ima_reset_appraise_flags(d_backing_inode(dentry), digsig);
@@ -807,7 +818,7 @@ static int ima_inode_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
const char *acl_name, struct posix_acl *kacl)
{
if (evm_revalidate_status(acl_name))
- ima_reset_appraise_flags(d_backing_inode(dentry), 0);
+ ima_reset_appraise_flags(d_backing_inode(dentry), -1);
return 0;
}
@@ -815,11 +826,13 @@ static int ima_inode_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
static int ima_inode_removexattr(struct mnt_idmap *idmap, struct dentry *dentry,
const char *xattr_name)
{
- int result;
+ int result, digsig = -1;
result = ima_protect_xattr(dentry, xattr_name, NULL, 0);
if (result == 1 || evm_revalidate_status(xattr_name)) {
- ima_reset_appraise_flags(d_backing_inode(dentry), 0);
+ if (!strcmp(xattr_name, XATTR_NAME_IMA))
+ digsig = 0;
+ ima_reset_appraise_flags(d_backing_inode(dentry), digsig);
if (result == 1)
result = 0;
}
diff --git a/security/keys/Kconfig b/security/keys/Kconfig
index d4f5fc1e7263..84f39e50ca36 100644
--- a/security/keys/Kconfig
+++ b/security/keys/Kconfig
@@ -3,7 +3,7 @@
# Key management configuration
#
-config KEYS
+menuconfig KEYS
bool "Enable access key retention support"
select ASSOCIATIVE_ARRAY
help
@@ -21,9 +21,10 @@ config KEYS
If you are unsure as to whether this is required, answer N.
+if KEYS
+
config KEYS_REQUEST_CACHE
bool "Enable temporary caching of the last request_key() result"
- depends on KEYS
help
This option causes the result of the last successful request_key()
call that didn't upcall to the kernel to be cached temporarily in the
@@ -41,7 +42,6 @@ config KEYS_REQUEST_CACHE
config PERSISTENT_KEYRINGS
bool "Enable register of persistent per-UID keyrings"
- depends on KEYS
help
This option provides a register of persistent per-UID keyrings,
primarily aimed at Kerberos key storage. The keyrings are persistent
@@ -58,7 +58,6 @@ config PERSISTENT_KEYRINGS
config BIG_KEYS
bool "Large payload keys"
- depends on KEYS
depends on TMPFS
select CRYPTO_LIB_CHACHA20POLY1305
help
@@ -70,7 +69,6 @@ config BIG_KEYS
config TRUSTED_KEYS
tristate "TRUSTED KEYS"
- depends on KEYS
help
This option provides support for creating, sealing, and unsealing
keys in the kernel. Trusted keys are random number symmetric keys,
@@ -85,12 +83,10 @@ endif
config ENCRYPTED_KEYS
tristate "ENCRYPTED KEYS"
- depends on KEYS
select CRYPTO
- select CRYPTO_HMAC
select CRYPTO_AES
select CRYPTO_CBC
- select CRYPTO_SHA256
+ select CRYPTO_LIB_SHA256
select CRYPTO_RNG
help
This option provides support for create/encrypting/decrypting keys
@@ -114,7 +110,6 @@ config USER_DECRYPTED_DATA
config KEY_DH_OPERATIONS
bool "Diffie-Hellman operations on retained keys"
- depends on KEYS
select CRYPTO
select CRYPTO_KDF800108_CTR
select CRYPTO_DH
@@ -127,9 +122,11 @@ config KEY_DH_OPERATIONS
config KEY_NOTIFICATIONS
bool "Provide key/keyring change notifications"
- depends on KEYS && WATCH_QUEUE
+ depends on WATCH_QUEUE
help
This option provides support for getting change notifications
on keys and keyrings on which the caller has View permission.
This makes use of pipes to handle the notification buffer and
provides KEYCTL_WATCH_KEY to enable/disable watches.
+
+endif # KEYS
diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c
index 831cb84fd75a..513c09e2b01c 100644
--- a/security/keys/encrypted-keys/encrypted.c
+++ b/security/keys/encrypted-keys/encrypted.c
@@ -27,7 +27,6 @@
#include <linux/scatterlist.h>
#include <linux/ctype.h>
#include <crypto/aes.h>
-#include <crypto/hash.h>
#include <crypto/sha2.h>
#include <crypto/skcipher.h>
#include <crypto/utils.h>
@@ -37,8 +36,6 @@
static const char KEY_TRUSTED_PREFIX[] = "trusted:";
static const char KEY_USER_PREFIX[] = "user:";
-static const char hash_alg[] = "sha256";
-static const char hmac_alg[] = "hmac(sha256)";
static const char blkcipher_alg[] = "cbc(aes)";
static const char key_format_default[] = "default";
static const char key_format_ecryptfs[] = "ecryptfs";
@@ -54,8 +51,6 @@ static int blksize;
#define MIN_DATA_SIZE 20
#define KEY_ENC32_PAYLOAD_LEN 32
-static struct crypto_shash *hash_tfm;
-
enum {
Opt_new, Opt_load, Opt_update, Opt_err
};
@@ -329,26 +324,6 @@ error:
return ukey;
}
-static int calc_hmac(u8 *digest, const u8 *key, unsigned int keylen,
- const u8 *buf, unsigned int buflen)
-{
- struct crypto_shash *tfm;
- int err;
-
- tfm = crypto_alloc_shash(hmac_alg, 0, 0);
- if (IS_ERR(tfm)) {
- pr_err("encrypted_key: can't alloc %s transform: %ld\n",
- hmac_alg, PTR_ERR(tfm));
- return PTR_ERR(tfm);
- }
-
- err = crypto_shash_setkey(tfm, key, keylen);
- if (!err)
- err = crypto_shash_tfm_digest(tfm, buf, buflen, digest);
- crypto_free_shash(tfm);
- return err;
-}
-
enum derived_key_type { ENC_KEY, AUTH_KEY };
/* Derive authentication/encryption key from trusted key */
@@ -357,7 +332,6 @@ static int get_derived_key(u8 *derived_key, enum derived_key_type key_type,
{
u8 *derived_buf;
unsigned int derived_buf_len;
- int ret;
derived_buf_len = strlen("AUTH_KEY") + 1 + master_keylen;
if (derived_buf_len < HASH_SIZE)
@@ -374,10 +348,9 @@ static int get_derived_key(u8 *derived_key, enum derived_key_type key_type,
memcpy(derived_buf + strlen(derived_buf) + 1, master_key,
master_keylen);
- ret = crypto_shash_tfm_digest(hash_tfm, derived_buf, derived_buf_len,
- derived_key);
+ sha256(derived_buf, derived_buf_len, derived_key);
kfree_sensitive(derived_buf);
- return ret;
+ return 0;
}
static struct skcipher_request *init_skcipher_req(const u8 *key,
@@ -503,10 +476,10 @@ static int datablob_hmac_append(struct encrypted_key_payload *epayload,
goto out;
digest = epayload->format + epayload->datablob_len;
- ret = calc_hmac(digest, derived_key, sizeof derived_key,
- epayload->format, epayload->datablob_len);
- if (!ret)
- dump_hmac(NULL, digest, HASH_SIZE);
+ hmac_sha256_usingrawkey(derived_key, sizeof(derived_key),
+ epayload->format, epayload->datablob_len,
+ digest);
+ dump_hmac(NULL, digest, HASH_SIZE);
out:
memzero_explicit(derived_key, sizeof(derived_key));
return ret;
@@ -534,9 +507,8 @@ static int datablob_hmac_verify(struct encrypted_key_payload *epayload,
} else
p = epayload->format;
- ret = calc_hmac(digest, derived_key, sizeof derived_key, p, len);
- if (ret < 0)
- goto out;
+ hmac_sha256_usingrawkey(derived_key, sizeof(derived_key), p, len,
+ digest);
ret = crypto_memneq(digest, epayload->format + epayload->datablob_len,
sizeof(digest));
if (ret) {
@@ -1011,29 +983,14 @@ static int __init init_encrypted(void)
{
int ret;
- hash_tfm = crypto_alloc_shash(hash_alg, 0, 0);
- if (IS_ERR(hash_tfm)) {
- pr_err("encrypted_key: can't allocate %s transform: %ld\n",
- hash_alg, PTR_ERR(hash_tfm));
- return PTR_ERR(hash_tfm);
- }
-
ret = aes_get_sizes();
if (ret < 0)
- goto out;
- ret = register_key_type(&key_type_encrypted);
- if (ret < 0)
- goto out;
- return 0;
-out:
- crypto_free_shash(hash_tfm);
- return ret;
-
+ return ret;
+ return register_key_type(&key_type_encrypted);
}
static void __exit cleanup_encrypted(void)
{
- crypto_free_shash(hash_tfm);
unregister_key_type(&key_type_encrypted);
}
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index b5d5333ab330..a63c46bb2d14 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -51,7 +51,7 @@ static struct key *get_user_register(struct user_namespace *user_ns)
if (!reg_keyring) {
reg_keyring = keyring_alloc(".user_reg",
user_ns->owner, INVALID_GID,
- &init_cred,
+ kernel_cred(),
KEY_POS_WRITE | KEY_POS_SEARCH |
KEY_USR_VIEW | KEY_USR_READ,
0,
diff --git a/security/keys/trusted-keys/Kconfig b/security/keys/trusted-keys/Kconfig
index 1fb8aa001995..204a68c1429d 100644
--- a/security/keys/trusted-keys/Kconfig
+++ b/security/keys/trusted-keys/Kconfig
@@ -5,10 +5,9 @@ config TRUSTED_KEYS_TPM
bool "TPM-based trusted keys"
depends on TCG_TPM >= TRUSTED_KEYS
default y
- select CRYPTO
- select CRYPTO_HMAC
- select CRYPTO_SHA1
select CRYPTO_HASH_INFO
+ select CRYPTO_LIB_SHA1
+ select CRYPTO_LIB_UTILS
select ASN1_ENCODER
select OID_REGISTRY
select ASN1
diff --git a/security/keys/trusted-keys/trusted_tpm1.c b/security/keys/trusted-keys/trusted_tpm1.c
index 89c9798d1800..636acb66a4f6 100644
--- a/security/keys/trusted-keys/trusted_tpm1.c
+++ b/security/keys/trusted-keys/trusted_tpm1.c
@@ -7,6 +7,8 @@
*/
#include <crypto/hash_info.h>
+#include <crypto/sha1.h>
+#include <crypto/utils.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/parser.h>
@@ -14,78 +16,92 @@
#include <linux/err.h>
#include <keys/trusted-type.h>
#include <linux/key-type.h>
-#include <linux/crypto.h>
-#include <crypto/hash.h>
-#include <crypto/sha1.h>
#include <linux/tpm.h>
#include <linux/tpm_command.h>
#include <keys/trusted_tpm.h>
-static const char hmac_alg[] = "hmac(sha1)";
-static const char hash_alg[] = "sha1";
static struct tpm_chip *chip;
static struct tpm_digest *digests;
-struct sdesc {
- struct shash_desc shash;
- char ctx[];
+/* implementation specific TPM constants */
+#define TPM_SIZE_OFFSET 2
+#define TPM_RETURN_OFFSET 6
+#define TPM_DATA_OFFSET 10
+
+#define LOAD32(buffer, offset) (ntohl(*(uint32_t *)&buffer[offset]))
+#define LOAD32N(buffer, offset) (*(uint32_t *)&buffer[offset])
+#define LOAD16(buffer, offset) (ntohs(*(uint16_t *)&buffer[offset]))
+
+struct osapsess {
+ uint32_t handle;
+ unsigned char secret[SHA1_DIGEST_SIZE];
+ unsigned char enonce[TPM_NONCE_SIZE];
};
-static struct crypto_shash *hashalg;
-static struct crypto_shash *hmacalg;
+/* discrete values, but have to store in uint16_t for TPM use */
+enum {
+ SEAL_keytype = 1,
+ SRK_keytype = 4
+};
-static struct sdesc *init_sdesc(struct crypto_shash *alg)
+#define TPM_DEBUG 0
+
+#if TPM_DEBUG
+static inline void dump_options(struct trusted_key_options *o)
{
- struct sdesc *sdesc;
- int size;
-
- size = sizeof(struct shash_desc) + crypto_shash_descsize(alg);
- sdesc = kmalloc(size, GFP_KERNEL);
- if (!sdesc)
- return ERR_PTR(-ENOMEM);
- sdesc->shash.tfm = alg;
- return sdesc;
+ pr_info("sealing key type %d\n", o->keytype);
+ pr_info("sealing key handle %0X\n", o->keyhandle);
+ pr_info("pcrlock %d\n", o->pcrlock);
+ pr_info("pcrinfo %d\n", o->pcrinfo_len);
+ print_hex_dump(KERN_INFO, "pcrinfo ", DUMP_PREFIX_NONE,
+ 16, 1, o->pcrinfo, o->pcrinfo_len, 0);
}
-static int TSS_sha1(const unsigned char *data, unsigned int datalen,
- unsigned char *digest)
+static inline void dump_sess(struct osapsess *s)
{
- struct sdesc *sdesc;
- int ret;
+ print_hex_dump(KERN_INFO, "trusted-key: handle ", DUMP_PREFIX_NONE,
+ 16, 1, &s->handle, 4, 0);
+ pr_info("secret:\n");
+ print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE,
+ 16, 1, &s->secret, SHA1_DIGEST_SIZE, 0);
+ pr_info("trusted-key: enonce:\n");
+ print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE,
+ 16, 1, &s->enonce, SHA1_DIGEST_SIZE, 0);
+}
- sdesc = init_sdesc(hashalg);
- if (IS_ERR(sdesc)) {
- pr_info("can't alloc %s\n", hash_alg);
- return PTR_ERR(sdesc);
- }
+static inline void dump_tpm_buf(unsigned char *buf)
+{
+ int len;
- ret = crypto_shash_digest(&sdesc->shash, data, datalen, digest);
- kfree_sensitive(sdesc);
- return ret;
+ pr_info("\ntpm buffer\n");
+ len = LOAD32(buf, TPM_SIZE_OFFSET);
+ print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1, buf, len, 0);
+}
+#else
+static inline void dump_options(struct trusted_key_options *o)
+{
}
+static inline void dump_sess(struct osapsess *s)
+{
+}
+
+static inline void dump_tpm_buf(unsigned char *buf)
+{
+}
+#endif
+
static int TSS_rawhmac(unsigned char *digest, const unsigned char *key,
unsigned int keylen, ...)
{
- struct sdesc *sdesc;
+ struct hmac_sha1_ctx hmac_ctx;
va_list argp;
unsigned int dlen;
unsigned char *data;
- int ret;
+ int ret = 0;
- sdesc = init_sdesc(hmacalg);
- if (IS_ERR(sdesc)) {
- pr_info("can't alloc %s\n", hmac_alg);
- return PTR_ERR(sdesc);
- }
-
- ret = crypto_shash_setkey(hmacalg, key, keylen);
- if (ret < 0)
- goto out;
- ret = crypto_shash_init(&sdesc->shash);
- if (ret < 0)
- goto out;
+ hmac_sha1_init_usingrawkey(&hmac_ctx, key, keylen);
va_start(argp, keylen);
for (;;) {
@@ -97,46 +113,34 @@ static int TSS_rawhmac(unsigned char *digest, const unsigned char *key,
ret = -EINVAL;
break;
}
- ret = crypto_shash_update(&sdesc->shash, data, dlen);
- if (ret < 0)
- break;
+ hmac_sha1_update(&hmac_ctx, data, dlen);
}
va_end(argp);
if (!ret)
- ret = crypto_shash_final(&sdesc->shash, digest);
-out:
- kfree_sensitive(sdesc);
+ hmac_sha1_final(&hmac_ctx, digest);
return ret;
}
/*
* calculate authorization info fields to send to TPM
*/
-int TSS_authhmac(unsigned char *digest, const unsigned char *key,
+static int TSS_authhmac(unsigned char *digest, const unsigned char *key,
unsigned int keylen, unsigned char *h1,
unsigned char *h2, unsigned int h3, ...)
{
unsigned char paramdigest[SHA1_DIGEST_SIZE];
- struct sdesc *sdesc;
+ struct sha1_ctx sha_ctx;
unsigned int dlen;
unsigned char *data;
unsigned char c;
- int ret;
+ int ret = 0;
va_list argp;
if (!chip)
return -ENODEV;
- sdesc = init_sdesc(hashalg);
- if (IS_ERR(sdesc)) {
- pr_info("can't alloc %s\n", hash_alg);
- return PTR_ERR(sdesc);
- }
-
c = !!h3;
- ret = crypto_shash_init(&sdesc->shash);
- if (ret < 0)
- goto out;
+ sha1_init(&sha_ctx);
va_start(argp, h3);
for (;;) {
dlen = va_arg(argp, unsigned int);
@@ -147,27 +151,22 @@ int TSS_authhmac(unsigned char *digest, const unsigned char *key,
ret = -EINVAL;
break;
}
- ret = crypto_shash_update(&sdesc->shash, data, dlen);
- if (ret < 0)
- break;
+ sha1_update(&sha_ctx, data, dlen);
}
va_end(argp);
if (!ret)
- ret = crypto_shash_final(&sdesc->shash, paramdigest);
+ sha1_final(&sha_ctx, paramdigest);
if (!ret)
ret = TSS_rawhmac(digest, key, keylen, SHA1_DIGEST_SIZE,
paramdigest, TPM_NONCE_SIZE, h1,
TPM_NONCE_SIZE, h2, 1, &c, 0, 0);
-out:
- kfree_sensitive(sdesc);
return ret;
}
-EXPORT_SYMBOL_GPL(TSS_authhmac);
/*
* verify the AUTH1_COMMAND (Seal) result from TPM
*/
-int TSS_checkhmac1(unsigned char *buffer,
+static int TSS_checkhmac1(unsigned char *buffer,
const uint32_t command,
const unsigned char *ononce,
const unsigned char *key,
@@ -182,7 +181,7 @@ int TSS_checkhmac1(unsigned char *buffer,
unsigned char *authdata;
unsigned char testhmac[SHA1_DIGEST_SIZE];
unsigned char paramdigest[SHA1_DIGEST_SIZE];
- struct sdesc *sdesc;
+ struct sha1_ctx sha_ctx;
unsigned int dlen;
unsigned int dpos;
va_list argp;
@@ -203,51 +202,30 @@ int TSS_checkhmac1(unsigned char *buffer,
continueflag = authdata - 1;
enonce = continueflag - TPM_NONCE_SIZE;
- sdesc = init_sdesc(hashalg);
- if (IS_ERR(sdesc)) {
- pr_info("can't alloc %s\n", hash_alg);
- return PTR_ERR(sdesc);
- }
- ret = crypto_shash_init(&sdesc->shash);
- if (ret < 0)
- goto out;
- ret = crypto_shash_update(&sdesc->shash, (const u8 *)&result,
- sizeof result);
- if (ret < 0)
- goto out;
- ret = crypto_shash_update(&sdesc->shash, (const u8 *)&ordinal,
- sizeof ordinal);
- if (ret < 0)
- goto out;
+ sha1_init(&sha_ctx);
+ sha1_update(&sha_ctx, (const u8 *)&result, sizeof(result));
+ sha1_update(&sha_ctx, (const u8 *)&ordinal, sizeof(ordinal));
va_start(argp, keylen);
for (;;) {
dlen = va_arg(argp, unsigned int);
if (dlen == 0)
break;
dpos = va_arg(argp, unsigned int);
- ret = crypto_shash_update(&sdesc->shash, buffer + dpos, dlen);
- if (ret < 0)
- break;
+ sha1_update(&sha_ctx, buffer + dpos, dlen);
}
va_end(argp);
- if (!ret)
- ret = crypto_shash_final(&sdesc->shash, paramdigest);
- if (ret < 0)
- goto out;
+ sha1_final(&sha_ctx, paramdigest);
ret = TSS_rawhmac(testhmac, key, keylen, SHA1_DIGEST_SIZE, paramdigest,
TPM_NONCE_SIZE, enonce, TPM_NONCE_SIZE, ononce,
1, continueflag, 0, 0);
if (ret < 0)
- goto out;
+ return ret;
- if (memcmp(testhmac, authdata, SHA1_DIGEST_SIZE))
- ret = -EINVAL;
-out:
- kfree_sensitive(sdesc);
- return ret;
+ if (crypto_memneq(testhmac, authdata, SHA1_DIGEST_SIZE))
+ return -EINVAL;
+ return 0;
}
-EXPORT_SYMBOL_GPL(TSS_checkhmac1);
/*
* verify the AUTH2_COMMAND (unseal) result from TPM
@@ -273,7 +251,7 @@ static int TSS_checkhmac2(unsigned char *buffer,
unsigned char testhmac1[SHA1_DIGEST_SIZE];
unsigned char testhmac2[SHA1_DIGEST_SIZE];
unsigned char paramdigest[SHA1_DIGEST_SIZE];
- struct sdesc *sdesc;
+ struct sha1_ctx sha_ctx;
unsigned int dlen;
unsigned int dpos;
va_list argp;
@@ -296,22 +274,9 @@ static int TSS_checkhmac2(unsigned char *buffer,
enonce1 = continueflag1 - TPM_NONCE_SIZE;
enonce2 = continueflag2 - TPM_NONCE_SIZE;
- sdesc = init_sdesc(hashalg);
- if (IS_ERR(sdesc)) {
- pr_info("can't alloc %s\n", hash_alg);
- return PTR_ERR(sdesc);
- }
- ret = crypto_shash_init(&sdesc->shash);
- if (ret < 0)
- goto out;
- ret = crypto_shash_update(&sdesc->shash, (const u8 *)&result,
- sizeof result);
- if (ret < 0)
- goto out;
- ret = crypto_shash_update(&sdesc->shash, (const u8 *)&ordinal,
- sizeof ordinal);
- if (ret < 0)
- goto out;
+ sha1_init(&sha_ctx);
+ sha1_update(&sha_ctx, (const u8 *)&result, sizeof(result));
+ sha1_update(&sha_ctx, (const u8 *)&ordinal, sizeof(ordinal));
va_start(argp, keylen2);
for (;;) {
@@ -319,42 +284,33 @@ static int TSS_checkhmac2(unsigned char *buffer,
if (dlen == 0)
break;
dpos = va_arg(argp, unsigned int);
- ret = crypto_shash_update(&sdesc->shash, buffer + dpos, dlen);
- if (ret < 0)
- break;
+ sha1_update(&sha_ctx, buffer + dpos, dlen);
}
va_end(argp);
- if (!ret)
- ret = crypto_shash_final(&sdesc->shash, paramdigest);
- if (ret < 0)
- goto out;
+ sha1_final(&sha_ctx, paramdigest);
ret = TSS_rawhmac(testhmac1, key1, keylen1, SHA1_DIGEST_SIZE,
paramdigest, TPM_NONCE_SIZE, enonce1,
TPM_NONCE_SIZE, ononce, 1, continueflag1, 0, 0);
if (ret < 0)
- goto out;
- if (memcmp(testhmac1, authdata1, SHA1_DIGEST_SIZE)) {
- ret = -EINVAL;
- goto out;
- }
+ return ret;
+ if (crypto_memneq(testhmac1, authdata1, SHA1_DIGEST_SIZE))
+ return -EINVAL;
ret = TSS_rawhmac(testhmac2, key2, keylen2, SHA1_DIGEST_SIZE,
paramdigest, TPM_NONCE_SIZE, enonce2,
TPM_NONCE_SIZE, ononce, 1, continueflag2, 0, 0);
if (ret < 0)
- goto out;
- if (memcmp(testhmac2, authdata2, SHA1_DIGEST_SIZE))
- ret = -EINVAL;
-out:
- kfree_sensitive(sdesc);
- return ret;
+ return ret;
+ if (crypto_memneq(testhmac2, authdata2, SHA1_DIGEST_SIZE))
+ return -EINVAL;
+ return 0;
}
/*
* For key specific tpm requests, we will generate and send our
* own TPM command packets using the drivers send function.
*/
-int trusted_tpm_send(unsigned char *cmd, size_t buflen)
+static int trusted_tpm_send(unsigned char *cmd, size_t buflen)
{
struct tpm_buf buf;
int rc;
@@ -380,7 +336,6 @@ int trusted_tpm_send(unsigned char *cmd, size_t buflen)
tpm_put_ops(chip);
return rc;
}
-EXPORT_SYMBOL_GPL(trusted_tpm_send);
/*
* Lock a trusted key, by extending a selected PCR.
@@ -434,7 +389,7 @@ static int osap(struct tpm_buf *tb, struct osapsess *s,
/*
* Create an object independent authorisation protocol (oiap) session
*/
-int oiap(struct tpm_buf *tb, uint32_t *handle, unsigned char *nonce)
+static int oiap(struct tpm_buf *tb, uint32_t *handle, unsigned char *nonce)
{
int ret;
@@ -451,7 +406,6 @@ int oiap(struct tpm_buf *tb, uint32_t *handle, unsigned char *nonce)
TPM_NONCE_SIZE);
return 0;
}
-EXPORT_SYMBOL_GPL(oiap);
struct tpm_digests {
unsigned char encauth[SHA1_DIGEST_SIZE];
@@ -498,9 +452,7 @@ static int tpm_seal(struct tpm_buf *tb, uint16_t keytype,
/* calculate encrypted authorization value */
memcpy(td->xorwork, sess.secret, SHA1_DIGEST_SIZE);
memcpy(td->xorwork + SHA1_DIGEST_SIZE, sess.enonce, SHA1_DIGEST_SIZE);
- ret = TSS_sha1(td->xorwork, SHA1_DIGEST_SIZE * 2, td->xorhash);
- if (ret < 0)
- goto out;
+ sha1(td->xorwork, SHA1_DIGEST_SIZE * 2, td->xorhash);
ret = tpm_get_random(chip, td->nonceodd, TPM_NONCE_SIZE);
if (ret < 0)
@@ -989,40 +941,6 @@ static int trusted_tpm_get_random(unsigned char *key, size_t key_len)
return tpm_get_random(chip, key, key_len);
}
-static void trusted_shash_release(void)
-{
- if (hashalg)
- crypto_free_shash(hashalg);
- if (hmacalg)
- crypto_free_shash(hmacalg);
-}
-
-static int __init trusted_shash_alloc(void)
-{
- int ret;
-
- hmacalg = crypto_alloc_shash(hmac_alg, 0, 0);
- if (IS_ERR(hmacalg)) {
- pr_info("could not allocate crypto %s\n",
- hmac_alg);
- return PTR_ERR(hmacalg);
- }
-
- hashalg = crypto_alloc_shash(hash_alg, 0, 0);
- if (IS_ERR(hashalg)) {
- pr_info("could not allocate crypto %s\n",
- hash_alg);
- ret = PTR_ERR(hashalg);
- goto hashalg_fail;
- }
-
- return 0;
-
-hashalg_fail:
- crypto_free_shash(hmacalg);
- return ret;
-}
-
static int __init init_digests(void)
{
int i;
@@ -1049,15 +967,10 @@ static int __init trusted_tpm_init(void)
ret = init_digests();
if (ret < 0)
goto err_put;
- ret = trusted_shash_alloc();
- if (ret < 0)
- goto err_free;
ret = register_key_type(&key_type_trusted);
if (ret < 0)
- goto err_release;
+ goto err_free;
return 0;
-err_release:
- trusted_shash_release();
err_free:
kfree(digests);
err_put:
@@ -1070,7 +983,6 @@ static void trusted_tpm_exit(void)
if (chip) {
put_device(&chip->dev);
kfree(digests);
- trusted_shash_release();
unregister_key_type(&key_type_trusted);
}
}
diff --git a/security/landlock/fs.c b/security/landlock/fs.c
index c04f8879ad03..cee2b6f22c83 100644
--- a/security/landlock/fs.c
+++ b/security/landlock/fs.c
@@ -1281,7 +1281,7 @@ static void hook_sb_delete(struct super_block *const sb)
struct landlock_object *object;
/* Only handles referenced inodes. */
- if (!atomic_read(&inode->i_count))
+ if (!icount_read(inode))
continue;
/*
@@ -1296,7 +1296,7 @@ static void hook_sb_delete(struct super_block *const sb)
* second call to iput() for the same Landlock object. Also
* checks I_NEW because such inode cannot be tied to an object.
*/
- if (inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW)) {
+ if (inode_state_read(inode) & (I_FREEING | I_WILL_FREE | I_NEW)) {
spin_unlock(&inode->i_lock);
continue;
}
@@ -1335,11 +1335,10 @@ static void hook_sb_delete(struct super_block *const sb)
* At this point, we own the ihold() reference that was
* originally set up by get_inode_object() and the
* __iget() reference that we just set in this loop
- * walk. Therefore the following call to iput() will
- * not sleep nor drop the inode because there is now at
- * least two references to it.
+ * walk. Therefore there are at least two references
+ * on the inode.
*/
- iput(inode);
+ iput_not_last(inode);
} else {
spin_unlock(&object->lock);
rcu_read_unlock();
diff --git a/security/min_addr.c b/security/min_addr.c
index df1bc643d886..c55bb84b8632 100644
--- a/security/min_addr.c
+++ b/security/min_addr.c
@@ -3,6 +3,7 @@
#include <linux/mm.h>
#include <linux/security.h>
#include <linux/sysctl.h>
+#include <linux/minmax.h>
/* amount of vm to protect from userspace access by both DAC and the LSM*/
unsigned long mmap_min_addr;
@@ -16,10 +17,7 @@ unsigned long dac_mmap_min_addr = CONFIG_DEFAULT_MMAP_MIN_ADDR;
static void update_mmap_min_addr(void)
{
#ifdef CONFIG_LSM_MMAP_MIN_ADDR
- if (dac_mmap_min_addr > CONFIG_LSM_MMAP_MIN_ADDR)
- mmap_min_addr = dac_mmap_min_addr;
- else
- mmap_min_addr = CONFIG_LSM_MMAP_MIN_ADDR;
+ mmap_min_addr = umax(dac_mmap_min_addr, CONFIG_LSM_MMAP_MIN_ADDR);
#else
mmap_min_addr = dac_mmap_min_addr;
#endif
diff --git a/security/security.c b/security/security.c
index ad163f06bf7a..4d3c03a4524c 100644
--- a/security/security.c
+++ b/security/security.c
@@ -283,6 +283,9 @@ static void __init lsm_set_blob_sizes(struct lsm_blob_sizes *needed)
lsm_set_blob_size(&needed->lbs_xattr_count,
&blob_sizes.lbs_xattr_count);
lsm_set_blob_size(&needed->lbs_bdev, &blob_sizes.lbs_bdev);
+ lsm_set_blob_size(&needed->lbs_bpf_map, &blob_sizes.lbs_bpf_map);
+ lsm_set_blob_size(&needed->lbs_bpf_prog, &blob_sizes.lbs_bpf_prog);
+ lsm_set_blob_size(&needed->lbs_bpf_token, &blob_sizes.lbs_bpf_token);
}
/* Prepare LSM for initialization. */
@@ -480,6 +483,9 @@ static void __init ordered_lsm_init(void)
init_debug("tun device blob size = %d\n", blob_sizes.lbs_tun_dev);
init_debug("xattr slots = %d\n", blob_sizes.lbs_xattr_count);
init_debug("bdev blob size = %d\n", blob_sizes.lbs_bdev);
+ init_debug("bpf map blob size = %d\n", blob_sizes.lbs_bpf_map);
+ init_debug("bpf prog blob size = %d\n", blob_sizes.lbs_bpf_prog);
+ init_debug("bpf token blob size = %d\n", blob_sizes.lbs_bpf_token);
/*
* Create any kmem_caches needed for blobs
@@ -823,17 +829,50 @@ static int lsm_msg_msg_alloc(struct msg_msg *mp)
*/
static int lsm_bdev_alloc(struct block_device *bdev)
{
- if (blob_sizes.lbs_bdev == 0) {
- bdev->bd_security = NULL;
- return 0;
- }
+ return lsm_blob_alloc(&bdev->bd_security, blob_sizes.lbs_bdev,
+ GFP_KERNEL);
+}
- bdev->bd_security = kzalloc(blob_sizes.lbs_bdev, GFP_KERNEL);
- if (!bdev->bd_security)
- return -ENOMEM;
+#ifdef CONFIG_BPF_SYSCALL
+/**
+ * lsm_bpf_map_alloc - allocate a composite bpf_map blob
+ * @map: the bpf_map that needs a blob
+ *
+ * Allocate the bpf_map blob for all the modules
+ *
+ * Returns 0, or -ENOMEM if memory can't be allocated.
+ */
+static int lsm_bpf_map_alloc(struct bpf_map *map)
+{
+ return lsm_blob_alloc(&map->security, blob_sizes.lbs_bpf_map, GFP_KERNEL);
+}
- return 0;
+/**
+ * lsm_bpf_prog_alloc - allocate a composite bpf_prog blob
+ * @prog: the bpf_prog that needs a blob
+ *
+ * Allocate the bpf_prog blob for all the modules
+ *
+ * Returns 0, or -ENOMEM if memory can't be allocated.
+ */
+static int lsm_bpf_prog_alloc(struct bpf_prog *prog)
+{
+ return lsm_blob_alloc(&prog->aux->security, blob_sizes.lbs_bpf_prog, GFP_KERNEL);
+}
+
+/**
+ * lsm_bpf_token_alloc - allocate a composite bpf_token blob
+ * @token: the bpf_token that needs a blob
+ *
+ * Allocate the bpf_token blob for all the modules
+ *
+ * Returns 0, or -ENOMEM if memory can't be allocated.
+ */
+static int lsm_bpf_token_alloc(struct bpf_token *token)
+{
+ return lsm_blob_alloc(&token->security, blob_sizes.lbs_bpf_token, GFP_KERNEL);
}
+#endif /* CONFIG_BPF_SYSCALL */
/**
* lsm_early_task - during initialization allocate a composite task blob
@@ -1775,7 +1814,7 @@ EXPORT_SYMBOL(security_dentry_init_security);
* Return: Returns 0 on success, error on failure.
*/
int security_dentry_create_files_as(struct dentry *dentry, int mode,
- struct qstr *name,
+ const struct qstr *name,
const struct cred *old, struct cred *new)
{
return call_int_hook(dentry_create_files_as, dentry, mode,
@@ -3185,7 +3224,7 @@ int security_file_truncate(struct file *file)
*
* Return: Returns a zero on success, negative values on failure.
*/
-int security_task_alloc(struct task_struct *task, unsigned long clone_flags)
+int security_task_alloc(struct task_struct *task, u64 clone_flags)
{
int rc = lsm_task_alloc(task);
@@ -4342,17 +4381,31 @@ EXPORT_SYMBOL(security_secid_to_secctx);
* security_lsmprop_to_secctx() - Convert a lsm_prop to a secctx
* @prop: lsm specific information
* @cp: the LSM context
+ * @lsmid: which security module to report
*
* Convert a @prop entry to security context. If @cp is NULL the
* length of the result will be returned. This does mean that the
* length could change between calls to check the length and the
* next call which actually allocates and returns the @cp.
*
+ * @lsmid identifies which LSM should supply the context.
+ * A value of LSM_ID_UNDEF indicates that the first LSM suppling
+ * the hook should be used. This is used in cases where the
+ * ID of the supplying LSM is unambiguous.
+ *
* Return: Return length of data on success, error on failure.
*/
-int security_lsmprop_to_secctx(struct lsm_prop *prop, struct lsm_context *cp)
+int security_lsmprop_to_secctx(struct lsm_prop *prop, struct lsm_context *cp,
+ int lsmid)
{
- return call_int_hook(lsmprop_to_secctx, prop, cp);
+ struct lsm_static_call *scall;
+
+ lsm_for_each_hook(scall, lsmprop_to_secctx) {
+ if (lsmid != LSM_ID_UNDEF && lsmid != scall->hl->lsmid->id)
+ continue;
+ return scall->hl->hook.lsmprop_to_secctx(prop, cp);
+ }
+ return LSM_RET_DEFAULT(lsmprop_to_secctx);
}
EXPORT_SYMBOL(security_lsmprop_to_secctx);
@@ -5714,7 +5767,16 @@ int security_bpf_prog(struct bpf_prog *prog)
int security_bpf_map_create(struct bpf_map *map, union bpf_attr *attr,
struct bpf_token *token, bool kernel)
{
- return call_int_hook(bpf_map_create, map, attr, token, kernel);
+ int rc;
+
+ rc = lsm_bpf_map_alloc(map);
+ if (unlikely(rc))
+ return rc;
+
+ rc = call_int_hook(bpf_map_create, map, attr, token, kernel);
+ if (unlikely(rc))
+ security_bpf_map_free(map);
+ return rc;
}
/**
@@ -5733,7 +5795,16 @@ int security_bpf_map_create(struct bpf_map *map, union bpf_attr *attr,
int security_bpf_prog_load(struct bpf_prog *prog, union bpf_attr *attr,
struct bpf_token *token, bool kernel)
{
- return call_int_hook(bpf_prog_load, prog, attr, token, kernel);
+ int rc;
+
+ rc = lsm_bpf_prog_alloc(prog);
+ if (unlikely(rc))
+ return rc;
+
+ rc = call_int_hook(bpf_prog_load, prog, attr, token, kernel);
+ if (unlikely(rc))
+ security_bpf_prog_free(prog);
+ return rc;
}
/**
@@ -5750,7 +5821,16 @@ int security_bpf_prog_load(struct bpf_prog *prog, union bpf_attr *attr,
int security_bpf_token_create(struct bpf_token *token, union bpf_attr *attr,
const struct path *path)
{
- return call_int_hook(bpf_token_create, token, attr, path);
+ int rc;
+
+ rc = lsm_bpf_token_alloc(token);
+ if (unlikely(rc))
+ return rc;
+
+ rc = call_int_hook(bpf_token_create, token, attr, path);
+ if (unlikely(rc))
+ security_bpf_token_free(token);
+ return rc;
}
/**
@@ -5794,6 +5874,8 @@ int security_bpf_token_capable(const struct bpf_token *token, int cap)
void security_bpf_map_free(struct bpf_map *map)
{
call_void_hook(bpf_map_free, map);
+ kfree(map->security);
+ map->security = NULL;
}
/**
@@ -5805,6 +5887,8 @@ void security_bpf_map_free(struct bpf_map *map)
void security_bpf_prog_free(struct bpf_prog *prog)
{
call_void_hook(bpf_prog_free, prog);
+ kfree(prog->aux->security);
+ prog->aux->security = NULL;
}
/**
@@ -5816,6 +5900,8 @@ void security_bpf_prog_free(struct bpf_prog *prog)
void security_bpf_token_free(struct bpf_token *token)
{
call_void_hook(bpf_token_free, token);
+ kfree(token->security);
+ token->security = NULL;
}
#endif /* CONFIG_BPF_SYSCALL */
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index 4b4837a20225..430b0e23ee00 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -292,27 +292,26 @@ static struct avc_xperms_decision_node
struct avc_xperms_decision_node *xpd_node;
struct extended_perms_decision *xpd;
- xpd_node = kmem_cache_zalloc(avc_xperms_decision_cachep,
- GFP_NOWAIT | __GFP_NOWARN);
+ xpd_node = kmem_cache_zalloc(avc_xperms_decision_cachep, GFP_NOWAIT);
if (!xpd_node)
return NULL;
xpd = &xpd_node->xpd;
if (which & XPERMS_ALLOWED) {
xpd->allowed = kmem_cache_zalloc(avc_xperms_data_cachep,
- GFP_NOWAIT | __GFP_NOWARN);
+ GFP_NOWAIT);
if (!xpd->allowed)
goto error;
}
if (which & XPERMS_AUDITALLOW) {
xpd->auditallow = kmem_cache_zalloc(avc_xperms_data_cachep,
- GFP_NOWAIT | __GFP_NOWARN);
+ GFP_NOWAIT);
if (!xpd->auditallow)
goto error;
}
if (which & XPERMS_DONTAUDIT) {
xpd->dontaudit = kmem_cache_zalloc(avc_xperms_data_cachep,
- GFP_NOWAIT | __GFP_NOWARN);
+ GFP_NOWAIT);
if (!xpd->dontaudit)
goto error;
}
@@ -340,7 +339,7 @@ static struct avc_xperms_node *avc_xperms_alloc(void)
{
struct avc_xperms_node *xp_node;
- xp_node = kmem_cache_zalloc(avc_xperms_cachep, GFP_NOWAIT | __GFP_NOWARN);
+ xp_node = kmem_cache_zalloc(avc_xperms_cachep, GFP_NOWAIT);
if (!xp_node)
return xp_node;
INIT_LIST_HEAD(&xp_node->xpd_head);
@@ -495,7 +494,7 @@ static struct avc_node *avc_alloc_node(void)
{
struct avc_node *node;
- node = kmem_cache_zalloc(avc_node_cachep, GFP_NOWAIT | __GFP_NOWARN);
+ node = kmem_cache_zalloc(avc_node_cachep, GFP_NOWAIT);
if (!node)
goto out;
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index c95a5874bf7d..e713291db873 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -210,12 +210,12 @@ static int selinux_lsm_notifier_avc_callback(u32 event)
*/
static void cred_init_security(void)
{
- struct task_security_struct *tsec;
+ struct cred_security_struct *crsec;
/* NOTE: the lsm framework zeros out the buffer on allocation */
- tsec = selinux_cred(unrcu_pointer(current->real_cred));
- tsec->osid = tsec->sid = tsec->avdcache.sid = SECINITSID_KERNEL;
+ crsec = selinux_cred(unrcu_pointer(current->real_cred));
+ crsec->osid = crsec->sid = SECINITSID_KERNEL;
}
/*
@@ -223,10 +223,10 @@ static void cred_init_security(void)
*/
static inline u32 cred_sid(const struct cred *cred)
{
- const struct task_security_struct *tsec;
+ const struct cred_security_struct *crsec;
- tsec = selinux_cred(cred);
- return tsec->sid;
+ crsec = selinux_cred(cred);
+ return crsec->sid;
}
static void __ad_net_init(struct common_audit_data *ad,
@@ -437,15 +437,15 @@ static int may_context_mount_sb_relabel(u32 sid,
struct superblock_security_struct *sbsec,
const struct cred *cred)
{
- const struct task_security_struct *tsec = selinux_cred(cred);
+ const struct cred_security_struct *crsec = selinux_cred(cred);
int rc;
- rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
+ rc = avc_has_perm(crsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
FILESYSTEM__RELABELFROM, NULL);
if (rc)
return rc;
- rc = avc_has_perm(tsec->sid, sid, SECCLASS_FILESYSTEM,
+ rc = avc_has_perm(crsec->sid, sid, SECCLASS_FILESYSTEM,
FILESYSTEM__RELABELTO, NULL);
return rc;
}
@@ -454,9 +454,9 @@ static int may_context_mount_inode_relabel(u32 sid,
struct superblock_security_struct *sbsec,
const struct cred *cred)
{
- const struct task_security_struct *tsec = selinux_cred(cred);
+ const struct cred_security_struct *crsec = selinux_cred(cred);
int rc;
- rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
+ rc = avc_has_perm(crsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
FILESYSTEM__RELABELFROM, NULL);
if (rc)
return rc;
@@ -476,7 +476,9 @@ static int selinux_is_genfs_special_handling(struct super_block *sb)
!strcmp(sb->s_type->name, "rootfs") ||
(selinux_policycap_cgroupseclabel() &&
(!strcmp(sb->s_type->name, "cgroup") ||
- !strcmp(sb->s_type->name, "cgroup2")));
+ !strcmp(sb->s_type->name, "cgroup2"))) ||
+ (selinux_policycap_functionfs_seclabel() &&
+ !strcmp(sb->s_type->name, "functionfs"));
}
static int selinux_is_sblabel_mnt(struct super_block *sb)
@@ -741,7 +743,9 @@ static int selinux_set_mnt_opts(struct super_block *sb,
!strcmp(sb->s_type->name, "binder") ||
!strcmp(sb->s_type->name, "bpf") ||
!strcmp(sb->s_type->name, "pstore") ||
- !strcmp(sb->s_type->name, "securityfs"))
+ !strcmp(sb->s_type->name, "securityfs") ||
+ (selinux_policycap_functionfs_seclabel() &&
+ !strcmp(sb->s_type->name, "functionfs")))
sbsec->flags |= SE_SBGENFS;
if (!strcmp(sb->s_type->name, "sysfs") ||
@@ -1784,7 +1788,7 @@ out:
* Determine the label for an inode that might be unioned.
*/
static int
-selinux_determine_inode_label(const struct task_security_struct *tsec,
+selinux_determine_inode_label(const struct cred_security_struct *crsec,
struct inode *dir,
const struct qstr *name, u16 tclass,
u32 *_new_isid)
@@ -1796,11 +1800,11 @@ selinux_determine_inode_label(const struct task_security_struct *tsec,
(sbsec->behavior == SECURITY_FS_USE_MNTPOINT)) {
*_new_isid = sbsec->mntpoint_sid;
} else if ((sbsec->flags & SBLABEL_MNT) &&
- tsec->create_sid) {
- *_new_isid = tsec->create_sid;
+ crsec->create_sid) {
+ *_new_isid = crsec->create_sid;
} else {
const struct inode_security_struct *dsec = inode_security(dir);
- return security_transition_sid(tsec->sid,
+ return security_transition_sid(crsec->sid,
dsec->sid, tclass,
name, _new_isid);
}
@@ -1813,7 +1817,7 @@ static int may_create(struct inode *dir,
struct dentry *dentry,
u16 tclass)
{
- const struct task_security_struct *tsec = selinux_cred(current_cred());
+ const struct cred_security_struct *crsec = selinux_cred(current_cred());
struct inode_security_struct *dsec;
struct superblock_security_struct *sbsec;
u32 sid, newsid;
@@ -1823,7 +1827,7 @@ static int may_create(struct inode *dir,
dsec = inode_security(dir);
sbsec = selinux_superblock(dir->i_sb);
- sid = tsec->sid;
+ sid = crsec->sid;
ad.type = LSM_AUDIT_DATA_DENTRY;
ad.u.dentry = dentry;
@@ -1834,7 +1838,7 @@ static int may_create(struct inode *dir,
if (rc)
return rc;
- rc = selinux_determine_inode_label(tsec, dir, &dentry->d_name, tclass,
+ rc = selinux_determine_inode_label(crsec, dir, &dentry->d_name, tclass,
&newsid);
if (rc)
return rc;
@@ -2247,8 +2251,8 @@ static u32 ptrace_parent_sid(void)
}
static int check_nnp_nosuid(const struct linux_binprm *bprm,
- const struct task_security_struct *old_tsec,
- const struct task_security_struct *new_tsec)
+ const struct cred_security_struct *old_crsec,
+ const struct cred_security_struct *new_crsec)
{
int nnp = (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS);
int nosuid = !mnt_may_suid(bprm->file->f_path.mnt);
@@ -2258,7 +2262,7 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm,
if (!nnp && !nosuid)
return 0; /* neither NNP nor nosuid */
- if (new_tsec->sid == old_tsec->sid)
+ if (new_crsec->sid == old_crsec->sid)
return 0; /* No change in credentials */
/*
@@ -2273,7 +2277,7 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm,
av |= PROCESS2__NNP_TRANSITION;
if (nosuid)
av |= PROCESS2__NOSUID_TRANSITION;
- rc = avc_has_perm(old_tsec->sid, new_tsec->sid,
+ rc = avc_has_perm(old_crsec->sid, new_crsec->sid,
SECCLASS_PROCESS2, av, NULL);
if (!rc)
return 0;
@@ -2284,8 +2288,8 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm,
* i.e. SIDs that are guaranteed to only be allowed a subset
* of the permissions of the current SID.
*/
- rc = security_bounded_transition(old_tsec->sid,
- new_tsec->sid);
+ rc = security_bounded_transition(old_crsec->sid,
+ new_crsec->sid);
if (!rc)
return 0;
@@ -2301,8 +2305,8 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm,
static int selinux_bprm_creds_for_exec(struct linux_binprm *bprm)
{
- const struct task_security_struct *old_tsec;
- struct task_security_struct *new_tsec;
+ const struct cred_security_struct *old_crsec;
+ struct cred_security_struct *new_crsec;
struct inode_security_struct *isec;
struct common_audit_data ad;
struct inode *inode = file_inode(bprm->file);
@@ -2311,18 +2315,18 @@ static int selinux_bprm_creds_for_exec(struct linux_binprm *bprm)
/* SELinux context only depends on initial program or script and not
* the script interpreter */
- old_tsec = selinux_cred(current_cred());
- new_tsec = selinux_cred(bprm->cred);
+ old_crsec = selinux_cred(current_cred());
+ new_crsec = selinux_cred(bprm->cred);
isec = inode_security(inode);
/* Default to the current task SID. */
- new_tsec->sid = old_tsec->sid;
- new_tsec->osid = old_tsec->sid;
+ new_crsec->sid = old_crsec->sid;
+ new_crsec->osid = old_crsec->sid;
/* Reset fs, key, and sock SIDs on execve. */
- new_tsec->create_sid = 0;
- new_tsec->keycreate_sid = 0;
- new_tsec->sockcreate_sid = 0;
+ new_crsec->create_sid = 0;
+ new_crsec->keycreate_sid = 0;
+ new_crsec->sockcreate_sid = 0;
/*
* Before policy is loaded, label any task outside kernel space
@@ -2331,26 +2335,26 @@ static int selinux_bprm_creds_for_exec(struct linux_binprm *bprm)
* (if the policy chooses to set SECINITSID_INIT != SECINITSID_KERNEL).
*/
if (!selinux_initialized()) {
- new_tsec->sid = SECINITSID_INIT;
+ new_crsec->sid = SECINITSID_INIT;
/* also clear the exec_sid just in case */
- new_tsec->exec_sid = 0;
+ new_crsec->exec_sid = 0;
return 0;
}
- if (old_tsec->exec_sid) {
- new_tsec->sid = old_tsec->exec_sid;
+ if (old_crsec->exec_sid) {
+ new_crsec->sid = old_crsec->exec_sid;
/* Reset exec SID on execve. */
- new_tsec->exec_sid = 0;
+ new_crsec->exec_sid = 0;
/* Fail on NNP or nosuid if not an allowed transition. */
- rc = check_nnp_nosuid(bprm, old_tsec, new_tsec);
+ rc = check_nnp_nosuid(bprm, old_crsec, new_crsec);
if (rc)
return rc;
} else {
/* Check for a default transition on this program. */
- rc = security_transition_sid(old_tsec->sid,
+ rc = security_transition_sid(old_crsec->sid,
isec->sid, SECCLASS_PROCESS, NULL,
- &new_tsec->sid);
+ &new_crsec->sid);
if (rc)
return rc;
@@ -2358,34 +2362,34 @@ static int selinux_bprm_creds_for_exec(struct linux_binprm *bprm)
* Fallback to old SID on NNP or nosuid if not an allowed
* transition.
*/
- rc = check_nnp_nosuid(bprm, old_tsec, new_tsec);
+ rc = check_nnp_nosuid(bprm, old_crsec, new_crsec);
if (rc)
- new_tsec->sid = old_tsec->sid;
+ new_crsec->sid = old_crsec->sid;
}
ad.type = LSM_AUDIT_DATA_FILE;
ad.u.file = bprm->file;
- if (new_tsec->sid == old_tsec->sid) {
- rc = avc_has_perm(old_tsec->sid, isec->sid,
+ if (new_crsec->sid == old_crsec->sid) {
+ rc = avc_has_perm(old_crsec->sid, isec->sid,
SECCLASS_FILE, FILE__EXECUTE_NO_TRANS, &ad);
if (rc)
return rc;
} else {
/* Check permissions for the transition. */
- rc = avc_has_perm(old_tsec->sid, new_tsec->sid,
+ rc = avc_has_perm(old_crsec->sid, new_crsec->sid,
SECCLASS_PROCESS, PROCESS__TRANSITION, &ad);
if (rc)
return rc;
- rc = avc_has_perm(new_tsec->sid, isec->sid,
+ rc = avc_has_perm(new_crsec->sid, isec->sid,
SECCLASS_FILE, FILE__ENTRYPOINT, &ad);
if (rc)
return rc;
/* Check for shared state */
if (bprm->unsafe & LSM_UNSAFE_SHARE) {
- rc = avc_has_perm(old_tsec->sid, new_tsec->sid,
+ rc = avc_has_perm(old_crsec->sid, new_crsec->sid,
SECCLASS_PROCESS, PROCESS__SHARE,
NULL);
if (rc)
@@ -2397,7 +2401,7 @@ static int selinux_bprm_creds_for_exec(struct linux_binprm *bprm)
if (bprm->unsafe & LSM_UNSAFE_PTRACE) {
u32 ptsid = ptrace_parent_sid();
if (ptsid != 0) {
- rc = avc_has_perm(ptsid, new_tsec->sid,
+ rc = avc_has_perm(ptsid, new_crsec->sid,
SECCLASS_PROCESS,
PROCESS__PTRACE, NULL);
if (rc)
@@ -2411,7 +2415,7 @@ static int selinux_bprm_creds_for_exec(struct linux_binprm *bprm)
/* Enable secure mode for SIDs transitions unless
the noatsecure permission is granted between
the two SIDs, i.e. ahp returns 0. */
- rc = avc_has_perm(old_tsec->sid, new_tsec->sid,
+ rc = avc_has_perm(old_crsec->sid, new_crsec->sid,
SECCLASS_PROCESS, PROCESS__NOATSECURE,
NULL);
bprm->secureexec |= !!rc;
@@ -2479,12 +2483,12 @@ static inline void flush_unauthorized_files(const struct cred *cred,
*/
static void selinux_bprm_committing_creds(const struct linux_binprm *bprm)
{
- struct task_security_struct *new_tsec;
+ struct cred_security_struct *new_crsec;
struct rlimit *rlim, *initrlim;
int rc, i;
- new_tsec = selinux_cred(bprm->cred);
- if (new_tsec->sid == new_tsec->osid)
+ new_crsec = selinux_cred(bprm->cred);
+ if (new_crsec->sid == new_crsec->osid)
return;
/* Close files for which the new task SID is not authorized. */
@@ -2503,7 +2507,7 @@ static void selinux_bprm_committing_creds(const struct linux_binprm *bprm)
* higher than the default soft limit for cases where the default is
* lower than the hard limit, e.g. RLIMIT_CORE or RLIMIT_STACK.
*/
- rc = avc_has_perm(new_tsec->osid, new_tsec->sid, SECCLASS_PROCESS,
+ rc = avc_has_perm(new_crsec->osid, new_crsec->sid, SECCLASS_PROCESS,
PROCESS__RLIMITINH, NULL);
if (rc) {
/* protect against do_prlimit() */
@@ -2525,12 +2529,12 @@ static void selinux_bprm_committing_creds(const struct linux_binprm *bprm)
*/
static void selinux_bprm_committed_creds(const struct linux_binprm *bprm)
{
- const struct task_security_struct *tsec = selinux_cred(current_cred());
+ const struct cred_security_struct *crsec = selinux_cred(current_cred());
u32 osid, sid;
int rc;
- osid = tsec->osid;
- sid = tsec->sid;
+ osid = crsec->osid;
+ sid = crsec->sid;
if (sid == osid)
return;
@@ -2901,13 +2905,13 @@ static int selinux_dentry_init_security(struct dentry *dentry, int mode,
}
static int selinux_dentry_create_files_as(struct dentry *dentry, int mode,
- struct qstr *name,
+ const struct qstr *name,
const struct cred *old,
struct cred *new)
{
u32 newsid;
int rc;
- struct task_security_struct *tsec;
+ struct cred_security_struct *crsec;
rc = selinux_determine_inode_label(selinux_cred(old),
d_inode(dentry->d_parent), name,
@@ -2916,8 +2920,8 @@ static int selinux_dentry_create_files_as(struct dentry *dentry, int mode,
if (rc)
return rc;
- tsec = selinux_cred(new);
- tsec->create_sid = newsid;
+ crsec = selinux_cred(new);
+ crsec->create_sid = newsid;
return 0;
}
@@ -2925,7 +2929,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
const struct qstr *qstr,
struct xattr *xattrs, int *xattr_count)
{
- const struct task_security_struct *tsec = selinux_cred(current_cred());
+ const struct cred_security_struct *crsec = selinux_cred(current_cred());
struct superblock_security_struct *sbsec;
struct xattr *xattr = lsm_get_xattr_slot(xattrs, xattr_count);
u32 newsid, clen;
@@ -2935,9 +2939,9 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
sbsec = selinux_superblock(dir->i_sb);
- newsid = tsec->create_sid;
+ newsid = crsec->create_sid;
newsclass = inode_mode_to_security_class(inode->i_mode);
- rc = selinux_determine_inode_label(tsec, dir, qstr, newsclass, &newsid);
+ rc = selinux_determine_inode_label(crsec, dir, qstr, newsclass, &newsid);
if (rc)
return rc;
@@ -3109,7 +3113,7 @@ static noinline int audit_inode_permission(struct inode *inode,
static inline void task_avdcache_reset(struct task_security_struct *tsec)
{
memset(&tsec->avdcache.dir, 0, sizeof(tsec->avdcache.dir));
- tsec->avdcache.sid = tsec->sid;
+ tsec->avdcache.sid = current_sid();
tsec->avdcache.seqno = avc_policy_seqno();
tsec->avdcache.dir_spot = TSEC_AVDC_DIR_SIZE - 1;
}
@@ -3133,7 +3137,7 @@ static inline int task_avdcache_search(struct task_security_struct *tsec,
if (isec->sclass != SECCLASS_DIR)
return -ENOENT;
- if (unlikely(tsec->sid != tsec->avdcache.sid ||
+ if (unlikely(current_sid() != tsec->avdcache.sid ||
tsec->avdcache.seqno != avc_policy_seqno())) {
task_avdcache_reset(tsec);
return -ENOENT;
@@ -3197,6 +3201,7 @@ static int selinux_inode_permission(struct inode *inode, int requested)
{
int mask;
u32 perms;
+ u32 sid = current_sid();
struct task_security_struct *tsec;
struct inode_security_struct *isec;
struct avdc_entry *avdc;
@@ -3209,8 +3214,8 @@ static int selinux_inode_permission(struct inode *inode, int requested)
if (!mask)
return 0;
- tsec = selinux_cred(current_cred());
- if (task_avdcache_permnoaudit(tsec))
+ tsec = selinux_task(current);
+ if (task_avdcache_permnoaudit(tsec, sid))
return 0;
isec = inode_security_rcu(inode, requested & MAY_NOT_BLOCK);
@@ -3230,7 +3235,7 @@ static int selinux_inode_permission(struct inode *inode, int requested)
struct av_decision avd;
/* Cache miss. */
- rc = avc_has_perm_noaudit(tsec->sid, isec->sid, isec->sclass,
+ rc = avc_has_perm_noaudit(sid, isec->sid, isec->sclass,
perms, 0, &avd);
audited = avc_audit_required(perms, &avd, rc,
(requested & MAY_ACCESS) ? FILE__AUDIT_ACCESS : 0,
@@ -3281,9 +3286,9 @@ static int selinux_inode_getattr(const struct path *path)
{
struct task_security_struct *tsec;
- tsec = selinux_cred(current_cred());
+ tsec = selinux_task(current);
- if (task_avdcache_permnoaudit(tsec))
+ if (task_avdcache_permnoaudit(tsec, current_sid()))
return 0;
return path_has_perm(current_cred(), path, FILE__GETATTR);
@@ -3655,7 +3660,7 @@ static void selinux_inode_getlsmprop(struct inode *inode, struct lsm_prop *prop)
static int selinux_inode_copy_up(struct dentry *src, struct cred **new)
{
struct lsm_prop prop;
- struct task_security_struct *tsec;
+ struct cred_security_struct *crsec;
struct cred *new_creds = *new;
if (new_creds == NULL) {
@@ -3664,10 +3669,10 @@ static int selinux_inode_copy_up(struct dentry *src, struct cred **new)
return -ENOMEM;
}
- tsec = selinux_cred(new_creds);
+ crsec = selinux_cred(new_creds);
/* Get label from overlay inode and set it in create_sid */
selinux_inode_getlsmprop(d_inode(src), &prop);
- tsec->create_sid = prop.selinux.secid;
+ crsec->create_sid = prop.selinux.secid;
*new = new_creds;
return 0;
}
@@ -3693,7 +3698,7 @@ static int selinux_inode_copy_up_xattr(struct dentry *dentry, const char *name)
static int selinux_kernfs_init_security(struct kernfs_node *kn_dir,
struct kernfs_node *kn)
{
- const struct task_security_struct *tsec = selinux_cred(current_cred());
+ const struct cred_security_struct *crsec = selinux_cred(current_cred());
u32 parent_sid, newsid, clen;
int rc;
char *context;
@@ -3721,8 +3726,8 @@ static int selinux_kernfs_init_security(struct kernfs_node *kn_dir,
if (rc)
return rc;
- if (tsec->create_sid) {
- newsid = tsec->create_sid;
+ if (crsec->create_sid) {
+ newsid = crsec->create_sid;
} else {
u16 secclass = inode_mode_to_security_class(kn->mode);
const char *kn_name;
@@ -3733,7 +3738,7 @@ static int selinux_kernfs_init_security(struct kernfs_node *kn_dir,
q.name = kn_name;
q.hash_len = hashlen_string(kn_dir, kn_name);
- rc = security_transition_sid(tsec->sid,
+ rc = security_transition_sid(crsec->sid,
parent_sid, secclass, &q,
&newsid);
if (rc)
@@ -4144,10 +4149,13 @@ static int selinux_file_open(struct file *file)
/* task security operations */
static int selinux_task_alloc(struct task_struct *task,
- unsigned long clone_flags)
+ u64 clone_flags)
{
u32 sid = current_sid();
+ struct task_security_struct *old_tsec = selinux_task(current);
+ struct task_security_struct *new_tsec = selinux_task(task);
+ *new_tsec = *old_tsec;
return avc_has_perm(sid, sid, SECCLASS_PROCESS, PROCESS__FORK, NULL);
}
@@ -4157,10 +4165,10 @@ static int selinux_task_alloc(struct task_struct *task,
static int selinux_cred_prepare(struct cred *new, const struct cred *old,
gfp_t gfp)
{
- const struct task_security_struct *old_tsec = selinux_cred(old);
- struct task_security_struct *tsec = selinux_cred(new);
+ const struct cred_security_struct *old_crsec = selinux_cred(old);
+ struct cred_security_struct *crsec = selinux_cred(new);
- *tsec = *old_tsec;
+ *crsec = *old_crsec;
return 0;
}
@@ -4169,10 +4177,10 @@ static int selinux_cred_prepare(struct cred *new, const struct cred *old,
*/
static void selinux_cred_transfer(struct cred *new, const struct cred *old)
{
- const struct task_security_struct *old_tsec = selinux_cred(old);
- struct task_security_struct *tsec = selinux_cred(new);
+ const struct cred_security_struct *old_crsec = selinux_cred(old);
+ struct cred_security_struct *crsec = selinux_cred(new);
- *tsec = *old_tsec;
+ *crsec = *old_crsec;
}
static void selinux_cred_getsecid(const struct cred *c, u32 *secid)
@@ -4191,7 +4199,7 @@ static void selinux_cred_getlsmprop(const struct cred *c, struct lsm_prop *prop)
*/
static int selinux_kernel_act_as(struct cred *new, u32 secid)
{
- struct task_security_struct *tsec = selinux_cred(new);
+ struct cred_security_struct *crsec = selinux_cred(new);
u32 sid = current_sid();
int ret;
@@ -4200,10 +4208,10 @@ static int selinux_kernel_act_as(struct cred *new, u32 secid)
KERNEL_SERVICE__USE_AS_OVERRIDE,
NULL);
if (ret == 0) {
- tsec->sid = secid;
- tsec->create_sid = 0;
- tsec->keycreate_sid = 0;
- tsec->sockcreate_sid = 0;
+ crsec->sid = secid;
+ crsec->create_sid = 0;
+ crsec->keycreate_sid = 0;
+ crsec->sockcreate_sid = 0;
}
return ret;
}
@@ -4215,7 +4223,7 @@ static int selinux_kernel_act_as(struct cred *new, u32 secid)
static int selinux_kernel_create_files_as(struct cred *new, struct inode *inode)
{
struct inode_security_struct *isec = inode_security(inode);
- struct task_security_struct *tsec = selinux_cred(new);
+ struct cred_security_struct *crsec = selinux_cred(new);
u32 sid = current_sid();
int ret;
@@ -4225,7 +4233,7 @@ static int selinux_kernel_create_files_as(struct cred *new, struct inode *inode)
NULL);
if (ret == 0)
- tsec->create_sid = isec->sid;
+ crsec->create_sid = isec->sid;
return ret;
}
@@ -4740,15 +4748,15 @@ static int selinux_conn_sid(u32 sk_sid, u32 skb_sid, u32 *conn_sid)
/* socket security operations */
-static int socket_sockcreate_sid(const struct task_security_struct *tsec,
+static int socket_sockcreate_sid(const struct cred_security_struct *crsec,
u16 secclass, u32 *socksid)
{
- if (tsec->sockcreate_sid > SECSID_NULL) {
- *socksid = tsec->sockcreate_sid;
+ if (crsec->sockcreate_sid > SECSID_NULL) {
+ *socksid = crsec->sockcreate_sid;
return 0;
}
- return security_transition_sid(tsec->sid, tsec->sid,
+ return security_transition_sid(crsec->sid, crsec->sid,
secclass, NULL, socksid);
}
@@ -4793,7 +4801,7 @@ static int sock_has_perm(struct sock *sk, u32 perms)
static int selinux_socket_create(int family, int type,
int protocol, int kern)
{
- const struct task_security_struct *tsec = selinux_cred(current_cred());
+ const struct cred_security_struct *crsec = selinux_cred(current_cred());
u32 newsid;
u16 secclass;
int rc;
@@ -4802,17 +4810,17 @@ static int selinux_socket_create(int family, int type,
return 0;
secclass = socket_type_to_security_class(family, type, protocol);
- rc = socket_sockcreate_sid(tsec, secclass, &newsid);
+ rc = socket_sockcreate_sid(crsec, secclass, &newsid);
if (rc)
return rc;
- return avc_has_perm(tsec->sid, newsid, secclass, SOCKET__CREATE, NULL);
+ return avc_has_perm(crsec->sid, newsid, secclass, SOCKET__CREATE, NULL);
}
static int selinux_socket_post_create(struct socket *sock, int family,
int type, int protocol, int kern)
{
- const struct task_security_struct *tsec = selinux_cred(current_cred());
+ const struct cred_security_struct *crsec = selinux_cred(current_cred());
struct inode_security_struct *isec = inode_security_novalidate(SOCK_INODE(sock));
struct sk_security_struct *sksec;
u16 sclass = socket_type_to_security_class(family, type, protocol);
@@ -4820,7 +4828,7 @@ static int selinux_socket_post_create(struct socket *sock, int family,
int err = 0;
if (!kern) {
- err = socket_sockcreate_sid(tsec, sclass, &sid);
+ err = socket_sockcreate_sid(crsec, sclass, &sid);
if (err)
return err;
}
@@ -5885,7 +5893,7 @@ static unsigned int selinux_ip_output(void *priv, struct sk_buff *skb,
/* we do this in the LOCAL_OUT path and not the POST_ROUTING path
* because we want to make sure we apply the necessary labeling
* before IPsec is applied so we can leverage AH protection */
- sk = sk_to_full_sk(skb->sk);
+ sk = skb_to_full_sk(skb);
if (sk) {
struct sk_security_struct *sksec;
@@ -6522,37 +6530,37 @@ static void selinux_d_instantiate(struct dentry *dentry, struct inode *inode)
static int selinux_lsm_getattr(unsigned int attr, struct task_struct *p,
char **value)
{
- const struct task_security_struct *tsec;
+ const struct cred_security_struct *crsec;
int error;
u32 sid;
u32 len;
rcu_read_lock();
- tsec = selinux_cred(__task_cred(p));
+ crsec = selinux_cred(__task_cred(p));
if (p != current) {
- error = avc_has_perm(current_sid(), tsec->sid,
+ error = avc_has_perm(current_sid(), crsec->sid,
SECCLASS_PROCESS, PROCESS__GETATTR, NULL);
if (error)
goto err_unlock;
}
switch (attr) {
case LSM_ATTR_CURRENT:
- sid = tsec->sid;
+ sid = crsec->sid;
break;
case LSM_ATTR_PREV:
- sid = tsec->osid;
+ sid = crsec->osid;
break;
case LSM_ATTR_EXEC:
- sid = tsec->exec_sid;
+ sid = crsec->exec_sid;
break;
case LSM_ATTR_FSCREATE:
- sid = tsec->create_sid;
+ sid = crsec->create_sid;
break;
case LSM_ATTR_KEYCREATE:
- sid = tsec->keycreate_sid;
+ sid = crsec->keycreate_sid;
break;
case LSM_ATTR_SOCKCREATE:
- sid = tsec->sockcreate_sid;
+ sid = crsec->sockcreate_sid;
break;
default:
error = -EOPNOTSUPP;
@@ -6577,7 +6585,7 @@ err_unlock:
static int selinux_lsm_setattr(u64 attr, void *value, size_t size)
{
- struct task_security_struct *tsec;
+ struct cred_security_struct *crsec;
struct cred *new;
u32 mysid = current_sid(), sid = 0, ptsid;
int error;
@@ -6663,11 +6671,11 @@ static int selinux_lsm_setattr(u64 attr, void *value, size_t size)
operation. See selinux_bprm_creds_for_exec for the execve
checks and may_create for the file creation checks. The
operation will then fail if the context is not permitted. */
- tsec = selinux_cred(new);
+ crsec = selinux_cred(new);
if (attr == LSM_ATTR_EXEC) {
- tsec->exec_sid = sid;
+ crsec->exec_sid = sid;
} else if (attr == LSM_ATTR_FSCREATE) {
- tsec->create_sid = sid;
+ crsec->create_sid = sid;
} else if (attr == LSM_ATTR_KEYCREATE) {
if (sid) {
error = avc_has_perm(mysid, sid,
@@ -6675,22 +6683,22 @@ static int selinux_lsm_setattr(u64 attr, void *value, size_t size)
if (error)
goto abort_change;
}
- tsec->keycreate_sid = sid;
+ crsec->keycreate_sid = sid;
} else if (attr == LSM_ATTR_SOCKCREATE) {
- tsec->sockcreate_sid = sid;
+ crsec->sockcreate_sid = sid;
} else if (attr == LSM_ATTR_CURRENT) {
error = -EINVAL;
if (sid == 0)
goto abort_change;
if (!current_is_single_threaded()) {
- error = security_bounded_transition(tsec->sid, sid);
+ error = security_bounded_transition(crsec->sid, sid);
if (error)
goto abort_change;
}
/* Check permissions for the transition. */
- error = avc_has_perm(tsec->sid, sid, SECCLASS_PROCESS,
+ error = avc_has_perm(crsec->sid, sid, SECCLASS_PROCESS,
PROCESS__DYNTRANSITION, NULL);
if (error)
goto abort_change;
@@ -6705,7 +6713,7 @@ static int selinux_lsm_setattr(u64 attr, void *value, size_t size)
goto abort_change;
}
- tsec->sid = sid;
+ crsec->sid = sid;
} else {
error = -EINVAL;
goto abort_change;
@@ -6872,14 +6880,14 @@ static int selinux_inode_getsecctx(struct inode *inode, struct lsm_context *cp)
static int selinux_key_alloc(struct key *k, const struct cred *cred,
unsigned long flags)
{
- const struct task_security_struct *tsec;
+ const struct cred_security_struct *crsec;
struct key_security_struct *ksec = selinux_key(k);
- tsec = selinux_cred(cred);
- if (tsec->keycreate_sid)
- ksec->sid = tsec->keycreate_sid;
+ crsec = selinux_cred(cred);
+ if (crsec->keycreate_sid)
+ ksec->sid = crsec->keycreate_sid;
else
- ksec->sid = tsec->sid;
+ ksec->sid = crsec->sid;
return 0;
}
@@ -7062,14 +7070,14 @@ static int bpf_fd_pass(const struct file *file, u32 sid)
if (file->f_op == &bpf_map_fops) {
map = file->private_data;
- bpfsec = map->security;
+ bpfsec = selinux_bpf_map_security(map);
ret = avc_has_perm(sid, bpfsec->sid, SECCLASS_BPF,
bpf_map_fmode_to_av(file->f_mode), NULL);
if (ret)
return ret;
} else if (file->f_op == &bpf_prog_fops) {
prog = file->private_data;
- bpfsec = prog->aux->security;
+ bpfsec = selinux_bpf_prog_security(prog);
ret = avc_has_perm(sid, bpfsec->sid, SECCLASS_BPF,
BPF__PROG_RUN, NULL);
if (ret)
@@ -7083,7 +7091,7 @@ static int selinux_bpf_map(struct bpf_map *map, fmode_t fmode)
u32 sid = current_sid();
struct bpf_security_struct *bpfsec;
- bpfsec = map->security;
+ bpfsec = selinux_bpf_map_security(map);
return avc_has_perm(sid, bpfsec->sid, SECCLASS_BPF,
bpf_map_fmode_to_av(fmode), NULL);
}
@@ -7093,7 +7101,7 @@ static int selinux_bpf_prog(struct bpf_prog *prog)
u32 sid = current_sid();
struct bpf_security_struct *bpfsec;
- bpfsec = prog->aux->security;
+ bpfsec = selinux_bpf_prog_security(prog);
return avc_has_perm(sid, bpfsec->sid, SECCLASS_BPF,
BPF__PROG_RUN, NULL);
}
@@ -7103,73 +7111,38 @@ static int selinux_bpf_map_create(struct bpf_map *map, union bpf_attr *attr,
{
struct bpf_security_struct *bpfsec;
- bpfsec = kzalloc(sizeof(*bpfsec), GFP_KERNEL);
- if (!bpfsec)
- return -ENOMEM;
-
+ bpfsec = selinux_bpf_map_security(map);
bpfsec->sid = current_sid();
- map->security = bpfsec;
return 0;
}
-static void selinux_bpf_map_free(struct bpf_map *map)
-{
- struct bpf_security_struct *bpfsec = map->security;
-
- map->security = NULL;
- kfree(bpfsec);
-}
-
static int selinux_bpf_prog_load(struct bpf_prog *prog, union bpf_attr *attr,
struct bpf_token *token, bool kernel)
{
struct bpf_security_struct *bpfsec;
- bpfsec = kzalloc(sizeof(*bpfsec), GFP_KERNEL);
- if (!bpfsec)
- return -ENOMEM;
-
+ bpfsec = selinux_bpf_prog_security(prog);
bpfsec->sid = current_sid();
- prog->aux->security = bpfsec;
return 0;
}
-static void selinux_bpf_prog_free(struct bpf_prog *prog)
-{
- struct bpf_security_struct *bpfsec = prog->aux->security;
-
- prog->aux->security = NULL;
- kfree(bpfsec);
-}
-
static int selinux_bpf_token_create(struct bpf_token *token, union bpf_attr *attr,
const struct path *path)
{
struct bpf_security_struct *bpfsec;
- bpfsec = kzalloc(sizeof(*bpfsec), GFP_KERNEL);
- if (!bpfsec)
- return -ENOMEM;
-
+ bpfsec = selinux_bpf_token_security(token);
bpfsec->sid = current_sid();
- token->security = bpfsec;
return 0;
}
-
-static void selinux_bpf_token_free(struct bpf_token *token)
-{
- struct bpf_security_struct *bpfsec = token->security;
-
- token->security = NULL;
- kfree(bpfsec);
-}
#endif
struct lsm_blob_sizes selinux_blob_sizes __ro_after_init = {
- .lbs_cred = sizeof(struct task_security_struct),
+ .lbs_cred = sizeof(struct cred_security_struct),
+ .lbs_task = sizeof(struct task_security_struct),
.lbs_file = sizeof(struct file_security_struct),
.lbs_inode = sizeof(struct inode_security_struct),
.lbs_ipc = sizeof(struct ipc_security_struct),
@@ -7183,6 +7156,9 @@ struct lsm_blob_sizes selinux_blob_sizes __ro_after_init = {
.lbs_xattr_count = SELINUX_INODE_INIT_XATTRS,
.lbs_tun_dev = sizeof(struct tun_security_struct),
.lbs_ib = sizeof(struct ib_security_struct),
+ .lbs_bpf_map = sizeof(struct bpf_security_struct),
+ .lbs_bpf_prog = sizeof(struct bpf_security_struct),
+ .lbs_bpf_token = sizeof(struct bpf_security_struct),
};
#ifdef CONFIG_PERF_EVENTS
@@ -7536,9 +7512,6 @@ static struct security_hook_list selinux_hooks[] __ro_after_init = {
LSM_HOOK_INIT(bpf, selinux_bpf),
LSM_HOOK_INIT(bpf_map, selinux_bpf_map),
LSM_HOOK_INIT(bpf_prog, selinux_bpf_prog),
- LSM_HOOK_INIT(bpf_map_free, selinux_bpf_map_free),
- LSM_HOOK_INIT(bpf_prog_free, selinux_bpf_prog_free),
- LSM_HOOK_INIT(bpf_token_free, selinux_bpf_token_free),
#endif
#ifdef CONFIG_PERF_EVENTS
@@ -7618,6 +7591,11 @@ static __init int selinux_init(void)
/* Set the security state for the initial task. */
cred_init_security();
+ /* Inform the audit system that secctx is used */
+ audit_cfg_lsm(&selinux_lsmid,
+ AUDIT_CFG_LSM_SECCTX_SUBJECT |
+ AUDIT_CFG_LSM_SECCTX_OBJECT);
+
default_noexec = !(VM_DATA_DEFAULT_FLAGS & VM_EXEC);
if (!default_noexec)
pr_notice("SELinux: virtual memory is executable by default\n");
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index 1d7ac59015a1..8fc3de5234ac 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -26,6 +26,7 @@
#include <linux/lsm_hooks.h>
#include <linux/msg.h>
#include <net/net_namespace.h>
+#include <linux/bpf.h>
#include "flask.h"
#include "avc.h"
@@ -36,13 +37,16 @@ struct avdc_entry {
bool permissive; /* AVC permissive flag */
};
-struct task_security_struct {
+struct cred_security_struct {
u32 osid; /* SID prior to last execve */
u32 sid; /* current SID */
u32 exec_sid; /* exec SID */
u32 create_sid; /* fscreate SID */
u32 keycreate_sid; /* keycreate SID */
u32 sockcreate_sid; /* fscreate SID */
+} __randomize_layout;
+
+struct task_security_struct {
#define TSEC_AVDC_DIR_SIZE (1 << 2)
struct {
u32 sid; /* current SID for cached entries */
@@ -53,10 +57,11 @@ struct task_security_struct {
} avdcache;
} __randomize_layout;
-static inline bool task_avdcache_permnoaudit(struct task_security_struct *tsec)
+static inline bool task_avdcache_permnoaudit(struct task_security_struct *tsec,
+ u32 sid)
{
return (tsec->avdcache.permissive_neveraudit &&
- tsec->sid == tsec->avdcache.sid &&
+ sid == tsec->avdcache.sid &&
tsec->avdcache.seqno == avc_policy_seqno());
}
@@ -171,11 +176,17 @@ struct perf_event_security_struct {
};
extern struct lsm_blob_sizes selinux_blob_sizes;
-static inline struct task_security_struct *selinux_cred(const struct cred *cred)
+static inline struct cred_security_struct *selinux_cred(const struct cred *cred)
{
return cred->security + selinux_blob_sizes.lbs_cred;
}
+static inline struct task_security_struct *
+selinux_task(const struct task_struct *task)
+{
+ return task->security + selinux_blob_sizes.lbs_task;
+}
+
static inline struct file_security_struct *selinux_file(const struct file *file)
{
return file->f_security + selinux_blob_sizes.lbs_file;
@@ -206,9 +217,9 @@ selinux_ipc(const struct kern_ipc_perm *ipc)
*/
static inline u32 current_sid(void)
{
- const struct task_security_struct *tsec = selinux_cred(current_cred());
+ const struct cred_security_struct *crsec = selinux_cred(current_cred());
- return tsec->sid;
+ return crsec->sid;
}
static inline struct superblock_security_struct *
@@ -245,4 +256,23 @@ selinux_perf_event(void *perf_event)
return perf_event + selinux_blob_sizes.lbs_perf_event;
}
+#ifdef CONFIG_BPF_SYSCALL
+static inline struct bpf_security_struct *
+selinux_bpf_map_security(struct bpf_map *map)
+{
+ return map->security + selinux_blob_sizes.lbs_bpf_map;
+}
+
+static inline struct bpf_security_struct *
+selinux_bpf_prog_security(struct bpf_prog *prog)
+{
+ return prog->aux->security + selinux_blob_sizes.lbs_bpf_prog;
+}
+
+static inline struct bpf_security_struct *
+selinux_bpf_token_security(struct bpf_token *token)
+{
+ return token->security + selinux_blob_sizes.lbs_bpf_token;
+}
+#endif /* CONFIG_BPF_SYSCALL */
#endif /* _SELINUX_OBJSEC_H_ */
diff --git a/security/selinux/include/policycap.h b/security/selinux/include/policycap.h
index 7405154e6c42..135a969f873c 100644
--- a/security/selinux/include/policycap.h
+++ b/security/selinux/include/policycap.h
@@ -17,6 +17,7 @@ enum {
POLICYDB_CAP_NETLINK_XPERM,
POLICYDB_CAP_NETIF_WILDCARD,
POLICYDB_CAP_GENFS_SECLABEL_WILDCARD,
+ POLICYDB_CAP_FUNCTIONFS_SECLABEL,
__POLICYDB_CAP_MAX
};
#define POLICYDB_CAP_MAX (__POLICYDB_CAP_MAX - 1)
diff --git a/security/selinux/include/policycap_names.h b/security/selinux/include/policycap_names.h
index d8962fcf2ff9..ff8882887651 100644
--- a/security/selinux/include/policycap_names.h
+++ b/security/selinux/include/policycap_names.h
@@ -20,6 +20,7 @@ const char *const selinux_policycap_names[__POLICYDB_CAP_MAX] = {
"netlink_xperm",
"netif_wildcard",
"genfs_seclabel_wildcard",
+ "functionfs_seclabel",
};
/* clang-format on */
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 8201e6a3ac0f..0f954a40d3fc 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -203,10 +203,10 @@ static inline bool selinux_policycap_netlink_xperm(void)
selinux_state.policycap[POLICYDB_CAP_NETLINK_XPERM]);
}
-static inline bool selinux_policycap_netif_wildcard(void)
+static inline bool selinux_policycap_functionfs_seclabel(void)
{
return READ_ONCE(
- selinux_state.policycap[POLICYDB_CAP_NETIF_WILDCARD]);
+ selinux_state.policycap[POLICYDB_CAP_FUNCTIONFS_SECLABEL]);
}
struct selinux_policy_convert_data;
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 9aa1d03ab612..404e08bf60ba 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -506,6 +506,7 @@ static int sel_make_policy_nodes(struct selinux_fs_info *fsi,
{
int ret = 0;
struct dentry *tmp_parent, *tmp_bool_dir, *tmp_class_dir;
+ struct renamedata rd = {};
unsigned int bool_num = 0;
char **bool_names = NULL;
int *bool_values = NULL;
@@ -539,9 +540,14 @@ static int sel_make_policy_nodes(struct selinux_fs_info *fsi,
if (ret)
goto out;
- lock_rename(tmp_parent, fsi->sb->s_root);
+ rd.old_parent = tmp_parent;
+ rd.new_parent = fsi->sb->s_root;
/* booleans */
+ ret = start_renaming_two_dentries(&rd, tmp_bool_dir, fsi->bool_dir);
+ if (ret)
+ goto out;
+
d_exchange(tmp_bool_dir, fsi->bool_dir);
swap(fsi->bool_num, bool_num);
@@ -549,12 +555,17 @@ static int sel_make_policy_nodes(struct selinux_fs_info *fsi,
swap(fsi->bool_pending_values, bool_values);
fsi->bool_dir = tmp_bool_dir;
+ end_renaming(&rd);
/* classes */
+ ret = start_renaming_two_dentries(&rd, tmp_class_dir, fsi->class_dir);
+ if (ret)
+ goto out;
+
d_exchange(tmp_class_dir, fsi->class_dir);
fsi->class_dir = tmp_class_dir;
- unlock_rename(tmp_parent, fsi->sb->s_root);
+ end_renaming(&rd);
out:
sel_remove_old_bool_data(bool_num, bool_names, bool_values);
@@ -1203,7 +1214,7 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf,
size_t count, loff_t *ppos)
{
struct selinux_fs_info *fsi = file_inode(filep)->i_sb->s_fs_info;
- char *page = NULL;
+ char buffer[4];
ssize_t length;
ssize_t ret;
int cur_enforcing;
@@ -1217,27 +1228,19 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf,
fsi->bool_pending_names[index]))
goto out_unlock;
- ret = -ENOMEM;
- page = (char *)get_zeroed_page(GFP_KERNEL);
- if (!page)
- goto out_unlock;
-
cur_enforcing = security_get_bool_value(index);
if (cur_enforcing < 0) {
ret = cur_enforcing;
goto out_unlock;
}
- length = scnprintf(page, PAGE_SIZE, "%d %d", cur_enforcing,
- fsi->bool_pending_values[index]);
+ length = scnprintf(buffer, sizeof(buffer), "%d %d", !!cur_enforcing,
+ !!fsi->bool_pending_values[index]);
mutex_unlock(&selinux_state.policy_mutex);
- ret = simple_read_from_buffer(buf, count, ppos, page, length);
-out_free:
- free_page((unsigned long)page);
- return ret;
+ return simple_read_from_buffer(buf, count, ppos, buffer, length);
out_unlock:
mutex_unlock(&selinux_state.policy_mutex);
- goto out_free;
+ return ret;
}
static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index fc340a6f0dde..af986587841d 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -4908,7 +4908,7 @@ static int smack_inode_copy_up_xattr(struct dentry *src, const char *name)
}
static int smack_dentry_create_files_as(struct dentry *dentry, int mode,
- struct qstr *name,
+ const struct qstr *name,
const struct cred *old,
struct cred *new)
{
@@ -5267,6 +5267,11 @@ static __init int smack_init(void)
/* initialize the smack_known_list */
init_smack_known_list();
+ /* Inform the audit system that secctx is used */
+ audit_cfg_lsm(&smack_lsmid,
+ AUDIT_CFG_LSM_SECCTX_SUBJECT |
+ AUDIT_CFG_LSM_SECCTX_OBJECT);
+
return 0;
}
diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c
index d6ebcd9db80a..48fc59d38ab2 100644
--- a/security/tomoyo/tomoyo.c
+++ b/security/tomoyo/tomoyo.c
@@ -514,7 +514,7 @@ struct lsm_blob_sizes tomoyo_blob_sizes __ro_after_init = {
* Returns 0.
*/
static int tomoyo_task_alloc(struct task_struct *task,
- unsigned long clone_flags)
+ u64 clone_flags)
{
struct tomoyo_task *old = tomoyo_task(current);
struct tomoyo_task *new = tomoyo_task(task);