From patchwork Wed Nov 4 23:40:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11882671 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D55F7C55178 for ; Wed, 4 Nov 2020 23:51:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6D8FF22203 for ; Wed, 4 Nov 2020 23:51:02 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="pu6YT3gl" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730361AbgKDXvB (ORCPT ); Wed, 4 Nov 2020 18:51:01 -0500 Received: from sonic305-28.consmr.mail.ne1.yahoo.com ([66.163.185.154]:36658 "EHLO sonic305-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732828AbgKDXow (ORCPT ); Wed, 4 Nov 2020 18:44:52 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604533489; bh=Qo1Gfl7M/gEtL7nMaHAd4NMxP4V8Uuw/OZ3CtHIgtCI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=pu6YT3glSeWEuh3ZlSCbMs9jrzoUPf3DAWdO4owI28Gx4+ta5rNQVEa7QYMm+hRcNZeJBLjG7NYXvltMzKmY1mU5QGSDHZ8IbTo1akvoGv2MqfL4KQF7IZaQAC0ihZxZGDjz8sUEdMo6V1LcfGAQRK28la24leRHKWZzbddIPwWWIF5CSYx6Ys08ucNfqaXcUlCslqc4qori9zLpKfl6RbNUElD31B8E0dGIIcvJq92trJTQyF/MhGCOndXKzYP39jdGc0pPP/q53i9YZpjDkO3mNMsh/FXxNDauE0eAgsdbh367mh3ApJni1UN862ywtZzoQ73RFJTP2MNdlMLH7g== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604533489; bh=p7bFaraYo9JcuZzFbxQ6Tbwwx1wMeFwd5XLCW2UPODD=; h=From:To:Subject:Date; b=SBFCL2r3VOkatEfEmDcxR0Uf/Lb7AoWcARQD7KZWABR0IEQ/PY88pSs+7lay/+O9JxsP7A/X5/SZMIU47w1ttLbyY9M2SvQcRaLGIHDHuLjGmdb2pNqQTXqsGjp/ixdvL4WLCE3WvpIgv14iY66MS9UnZ9XY39NpNinrh2Ur0yH7Of9j/6r38wsZ3vC6o6XGJKQW+MqjuRPyQRLtHotNmyhDzP8VwKOVun0IEBHGln5pgyy/mRGibORtBpbiZ3yVlc84jSJcs8R+vynzx6pWYbqbhlhl0P9Gw2FoDNEaH/UmQdSLdzlGk2RhEJWUhgaIuBEB5G3+9WlW6QmMiNoNHA== X-YMail-OSG: WEGFifcVM1lzqnInN_yZ07flwHfIC02_zdxiEQ1NhEQogqYhv5GLQGZebb599Lg GRoQgbjrj6RWejD.VjtUE4uKfAKXAAJMfIDzHwLHMKQGuUR84ZlvjWraQXJVZ43kI0mvzwgC2nVz kS4i__vMZB1xZaXU.81qk6bcv5K8_V41sygLyxl1MjwoLly16flhyjqRkoNfQYYY5CjdcV8coN5a aUCO1vWAVHwOkxqFWkTVTR74GTKfaewlaRrHbeI73zDBVUdULvUKx9iYKqLfIjUgepQpoMNZ5x0L M1j244GGUNYU.2Px2HQU1NucMCTlyecafRkXhcQSVbWmaQpNTPtIMpGAnILlMBzWAAx__mllT5MJ 7uVuoa_Mq3nIa.NoRpfx7x.jPSKiVzTwV8QcrzCv4ohF1t6p_xJprR1K.NxkA1LK4Bs4i_gAsvUo NyXbDjRFFd41oAWvQCOd0eC1_Mo77ot1EMmo32SGdixEQ5NSd9XrZcmG8ZSs7GKLU0qSgCGSYPR8 O963GTsNBqbvHQSqNp9orKHlxQQQKttGX_KZwLPodTDwXe9OfL5Y0QQFWToZoguv_UOzZ2AK4y.b 56tM6jj7IaeXgw7.1UrtBIKWgDCvwPJNQH6eFq1eFR1d3mOqtb7ZvFZZ3l08NgWdVeaKW4wfzug4 Cv2lu.fUdokux9pWJiQbJTWEAhAtNzrI0CAynysh_Ws6QbUFHjGIxLrmh6QxEV4YWctwyMPzf40w P2EDppAfxEN5ZSYeiPIqxH9eR4Hgg3nqjFfIKpQnBIMOzPmjXQwMhTP6Wuewsd.7UrZbl3cKGbGO rMiyIvnV5krvF.ONjx2pvRhv6DwUizuVbZX7n0.QYliHnWG7Hc5ynMDkq_VD97eVeVykHuABf.2d S1R58htyQKMlQz1MZiC84OdlBItt8AbqhK3umhsXTJyc3RrlBW5AvmrLWkJYrMIt98tefRxn3tn7 QeoGKzUKkmZUvqugOA.HL1Xvg3KCtdRB4gfEwMyebuFxqI15E6TH5pcfqBzV52jpJlbvwHHpmDya RcyyrUIiUuN0t9vc7D_OKDhYF1YCpIO3ki5m06Jpb3KFk91lTqo2aWHrDs0Ybrp1qUcYqq9TzJbI kUZ5gTlP72hOOWdbT_ieJnA.J3bnv016JcS39v1WCGxn5pfuA1tdJP1BDyMaqQVxLzWz5txPOcLs jGHzp6_y6N0YzIDwZKXrqzJx515O8IA6MURvF2YsYnia.12EqzR_bmG_yadHf.7O0EARNWktAHLG 7KPBY3054SuZz0FhPPqE2K_Z8V0tW_ZnAtHljTRBkqsP_pmK5xcfO05pKTsn.H5okFwV74jupS5u YFi0vYb1YdPVSnTiWs1YqaOMdIckNaSS5nNSPBk8uYY0nhl_sV08GLRxTTLPSlz5TQbkW.L0K2LZ aqhBCkCcQBw9YkM3sYt40Y8WjuZkFaQyGw0b5xdTn4X8ca_7Dze4rdjya9WhH8B8nSp3FIypbzt6 6DluVXKA2xg4GxOFrLAyYM6Ln8qgxUsRIt0wiks.obpTPmyUHu4rnc1U22OlikdF22mNyFFzQPUY Nn2tDCeWczy89AE85vZkKTp06jZjBh7jYT3PcMFR4iGU- Received: from sonic.gate.mail.ne1.yahoo.com by sonic305.consmr.mail.ne1.yahoo.com with HTTP; Wed, 4 Nov 2020 23:44:49 +0000 Received: by smtp419.mail.gq1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID f5adbc43251d1fd62ce46f58c5aaef3e; Wed, 04 Nov 2020 23:44:46 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov, linux-kernel@vger.kernel.org, bpf@vger.kernel.org Subject: [PATCH v22 02/23] LSM: Create and manage the lsmblob data structure. Date: Wed, 4 Nov 2020 15:40:53 -0800 Message-Id: <20201104234114.11346-3-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201104234114.11346-1-casey@schaufler-ca.com> References: <20201104234114.11346-1-casey@schaufler-ca.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org When more than one security module is exporting data to audit and networking sub-systems a single 32 bit integer is no longer sufficient to represent the data. Add a structure to be used instead. The lsmblob structure is currently an array of u32 "secids". There is an entry for each of the security modules built into the system that would use secids if active. The system assigns the module a "slot" when it registers hooks. If modules are compiled in but not registered there will be unused slots. A new lsm_id structure, which contains the name of the LSM and its slot number, is created. There is an instance for each LSM, which assigns the name and passes it to the infrastructure to set the slot. The audit rules data is expanded to use an array of security module data rather than a single instance. Because IMA uses the audit rule functions it is affected as well. Acked-by: Stephen Smalley Acked-by: Paul Moore Acked-by: John Johansen Signed-off-by: Casey Schaufler Cc: --- include/linux/audit.h | 4 +- include/linux/lsm_hooks.h | 12 ++++- include/linux/security.h | 67 +++++++++++++++++++++++++-- kernel/auditfilter.c | 24 +++++----- kernel/auditsc.c | 12 ++--- security/apparmor/lsm.c | 7 ++- security/bpf/hooks.c | 12 ++++- security/commoncap.c | 7 ++- security/integrity/ima/ima_policy.c | 40 +++++++++++----- security/loadpin/loadpin.c | 8 +++- security/lockdown/lockdown.c | 7 ++- security/safesetid/lsm.c | 8 +++- security/security.c | 72 ++++++++++++++++++++++++----- security/selinux/hooks.c | 8 +++- security/smack/smack_lsm.c | 7 ++- security/tomoyo/tomoyo.c | 8 +++- security/yama/yama_lsm.c | 7 ++- 17 files changed, 254 insertions(+), 56 deletions(-) diff --git a/include/linux/audit.h b/include/linux/audit.h index b3d859831a31..ba1cd38d601b 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -65,8 +66,9 @@ struct audit_field { kuid_t uid; kgid_t gid; struct { + bool lsm_isset; char *lsm_str; - void *lsm_rule; + void *lsm_rules[LSMBLOB_ENTRIES]; }; }; u32 op; diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index d8f492ed6ebf..fe9203f15993 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -1545,6 +1545,14 @@ struct security_hook_heads { #undef LSM_HOOK } __randomize_layout; +/* + * Information that identifies a security module. + */ +struct lsm_id { + const char *lsm; /* Name of the LSM */ + int slot; /* Slot in lsmblob if one is allocated */ +}; + /* * Security module hook list structure. * For use with generic list macros for common operations. @@ -1553,7 +1561,7 @@ struct security_hook_list { struct hlist_node list; struct hlist_head *head; union security_list_options hook; - char *lsm; + struct lsm_id *lsmid; } __randomize_layout; /* @@ -1588,7 +1596,7 @@ extern struct security_hook_heads security_hook_heads; extern char *lsm_names; extern void security_add_hooks(struct security_hook_list *hooks, int count, - char *lsm); + struct lsm_id *lsmid); #define LSM_FLAG_LEGACY_MAJOR BIT(0) #define LSM_FLAG_EXCLUSIVE BIT(1) diff --git a/include/linux/security.h b/include/linux/security.h index bc2725491560..fdb6e95c98e8 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -132,6 +132,65 @@ enum lockdown_reason { extern const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1]; +/* + * Data exported by the security modules + * + * Any LSM that provides secid or secctx based hooks must be included. + */ +#define LSMBLOB_ENTRIES ( \ + (IS_ENABLED(CONFIG_SECURITY_SELINUX) ? 1 : 0) + \ + (IS_ENABLED(CONFIG_SECURITY_SMACK) ? 1 : 0) + \ + (IS_ENABLED(CONFIG_SECURITY_APPARMOR) ? 1 : 0) + \ + (IS_ENABLED(CONFIG_BPF_LSM) ? 1 : 0)) + +struct lsmblob { + u32 secid[LSMBLOB_ENTRIES]; +}; + +#define LSMBLOB_INVALID -1 /* Not a valid LSM slot number */ +#define LSMBLOB_NEEDED -2 /* Slot requested on initialization */ +#define LSMBLOB_NOT_NEEDED -3 /* Slot not requested */ + +/** + * lsmblob_init - initialize an lsmblob structure. + * @blob: Pointer to the data to initialize + * @secid: The initial secid value + * + * Set all secid for all modules to the specified value. + */ +static inline void lsmblob_init(struct lsmblob *blob, u32 secid) +{ + int i; + + for (i = 0; i < LSMBLOB_ENTRIES; i++) + blob->secid[i] = secid; +} + +/** + * lsmblob_is_set - report if there is an value in the lsmblob + * @blob: Pointer to the exported LSM data + * + * Returns true if there is a secid set, false otherwise + */ +static inline bool lsmblob_is_set(struct lsmblob *blob) +{ + struct lsmblob empty = {}; + + return !!memcmp(blob, &empty, sizeof(*blob)); +} + +/** + * lsmblob_equal - report if the two lsmblob's are equal + * @bloba: Pointer to one LSM data + * @blobb: Pointer to the other LSM data + * + * Returns true if all entries in the two are equal, false otherwise + */ +static inline bool lsmblob_equal(struct lsmblob *bloba, struct lsmblob *blobb) +{ + return !memcmp(bloba, blobb, sizeof(*bloba)); +} + /* These functions are in security/commoncap.c */ extern int cap_capable(const struct cred *cred, struct user_namespace *ns, int cap, unsigned int opts); @@ -1833,8 +1892,8 @@ static inline int security_key_getsecurity(struct key *key, char **_buffer) #ifdef CONFIG_SECURITY int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule); int security_audit_rule_known(struct audit_krule *krule); -int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule); -void security_audit_rule_free(void *lsmrule); +int security_audit_rule_match(u32 secid, u32 field, u32 op, void **lsmrule); +void security_audit_rule_free(void **lsmrule); #else @@ -1850,12 +1909,12 @@ static inline int security_audit_rule_known(struct audit_krule *krule) } static inline int security_audit_rule_match(u32 secid, u32 field, u32 op, - void *lsmrule) + void **lsmrule) { return 0; } -static inline void security_audit_rule_free(void *lsmrule) +static inline void security_audit_rule_free(void **lsmrule) { } #endif /* CONFIG_SECURITY */ diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 333b3bcfc545..45da229f9f1f 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -74,7 +74,7 @@ static void audit_free_lsm_field(struct audit_field *f) case AUDIT_OBJ_LEV_LOW: case AUDIT_OBJ_LEV_HIGH: kfree(f->lsm_str); - security_audit_rule_free(f->lsm_rule); + security_audit_rule_free(f->lsm_rules); } } @@ -519,9 +519,10 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, goto exit_free; } entry->rule.buflen += f_val; + f->lsm_isset = true; f->lsm_str = str; err = security_audit_rule_init(f->type, f->op, str, - (void **)&f->lsm_rule); + f->lsm_rules); /* Keep currently invalid fields around in case they * become valid after a policy reload. */ if (err == -EINVAL) { @@ -774,7 +775,7 @@ static int audit_compare_rule(struct audit_krule *a, struct audit_krule *b) return 0; } -/* Duplicate LSM field information. The lsm_rule is opaque, so must be +/* Duplicate LSM field information. The lsm_rules is opaque, so must be * re-initialized. */ static inline int audit_dupe_lsm_field(struct audit_field *df, struct audit_field *sf) @@ -788,9 +789,9 @@ static inline int audit_dupe_lsm_field(struct audit_field *df, return -ENOMEM; df->lsm_str = lsm_str; - /* our own (refreshed) copy of lsm_rule */ + /* our own (refreshed) copy of lsm_rules */ ret = security_audit_rule_init(df->type, df->op, df->lsm_str, - (void **)&df->lsm_rule); + df->lsm_rules); /* Keep currently invalid fields around in case they * become valid after a policy reload. */ if (ret == -EINVAL) { @@ -842,7 +843,7 @@ struct audit_entry *audit_dupe_rule(struct audit_krule *old) new->tree = old->tree; memcpy(new->fields, old->fields, sizeof(struct audit_field) * fcount); - /* deep copy this information, updating the lsm_rule fields, because + /* deep copy this information, updating the lsm_rules fields, because * the originals will all be freed when the old rule is freed. */ for (i = 0; i < fcount; i++) { switch (new->fields[i].type) { @@ -1358,10 +1359,11 @@ int audit_filter(int msgtype, unsigned int listtype) case AUDIT_SUBJ_TYPE: case AUDIT_SUBJ_SEN: case AUDIT_SUBJ_CLR: - if (f->lsm_rule) { + if (f->lsm_isset) { security_task_getsecid(current, &sid); result = security_audit_rule_match(sid, - f->type, f->op, f->lsm_rule); + f->type, f->op, + f->lsm_rules); } break; case AUDIT_EXE: @@ -1388,7 +1390,7 @@ int audit_filter(int msgtype, unsigned int listtype) return ret; } -static int update_lsm_rule(struct audit_krule *r) +static int update_lsm_rules(struct audit_krule *r) { struct audit_entry *entry = container_of(r, struct audit_entry, rule); struct audit_entry *nentry; @@ -1420,7 +1422,7 @@ static int update_lsm_rule(struct audit_krule *r) return err; } -/* This function will re-initialize the lsm_rule field of all applicable rules. +/* This function will re-initialize the lsm_rules field of all applicable rules. * It will traverse the filter lists serarching for rules that contain LSM * specific filter fields. When such a rule is found, it is copied, the * LSM field is re-initialized, and the old rule is replaced with the @@ -1435,7 +1437,7 @@ int audit_update_lsm_rules(void) for (i = 0; i < AUDIT_NR_FILTERS; i++) { list_for_each_entry_safe(r, n, &audit_rules_list[i], list) { - int res = update_lsm_rule(r); + int res = update_lsm_rules(r); if (!err) err = res; } diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 8dba8f0983b5..16e3430f7d07 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -667,14 +667,14 @@ static int audit_filter_rules(struct task_struct *tsk, match for now to avoid losing information that may be wanted. An error message will also be logged upon error */ - if (f->lsm_rule) { + if (f->lsm_isset) { if (need_sid) { security_task_getsecid(tsk, &sid); need_sid = 0; } result = security_audit_rule_match(sid, f->type, f->op, - f->lsm_rule); + f->lsm_rules); } break; case AUDIT_OBJ_USER: @@ -684,21 +684,21 @@ static int audit_filter_rules(struct task_struct *tsk, case AUDIT_OBJ_LEV_HIGH: /* The above note for AUDIT_SUBJ_USER...AUDIT_SUBJ_CLR also applies here */ - if (f->lsm_rule) { + if (f->lsm_isset) { /* Find files that match */ if (name) { result = security_audit_rule_match( name->osid, f->type, f->op, - f->lsm_rule); + f->lsm_rules); } else if (ctx) { list_for_each_entry(n, &ctx->names_list, list) { if (security_audit_rule_match( n->osid, f->type, f->op, - f->lsm_rule)) { + f->lsm_rules)) { ++result; break; } @@ -709,7 +709,7 @@ static int audit_filter_rules(struct task_struct *tsk, break; if (security_audit_rule_match(ctx->ipc.osid, f->type, f->op, - f->lsm_rule)) + f->lsm_rules)) ++result; } break; diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index f1c365905d5e..432915c1d427 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -1152,6 +1152,11 @@ struct lsm_blob_sizes apparmor_blob_sizes __lsm_ro_after_init = { .lbs_sock = sizeof(struct aa_sk_ctx), }; +static struct lsm_id apparmor_lsmid __lsm_ro_after_init = { + .lsm = "apparmor", + .slot = LSMBLOB_NEEDED +}; + static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check), LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme), @@ -1852,7 +1857,7 @@ static int __init apparmor_init(void) goto buffers_out; } security_add_hooks(apparmor_hooks, ARRAY_SIZE(apparmor_hooks), - "apparmor"); + &apparmor_lsmid); /* Report that AppArmor successfully initialized */ apparmor_initialized = 1; diff --git a/security/bpf/hooks.c b/security/bpf/hooks.c index 788667d582ae..a1a5032a4d87 100644 --- a/security/bpf/hooks.c +++ b/security/bpf/hooks.c @@ -14,9 +14,19 @@ static struct security_hook_list bpf_lsm_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(inode_free_security, bpf_inode_storage_free), }; +/* + * slot has to be LSMBLOB_NEEDED because some of the hooks + * supplied by this module require a slot. + */ +struct lsm_id bpf_lsmid __lsm_ro_after_init = { + .lsm = "bpf", + .slot = LSMBLOB_NEEDED +}; + static int __init bpf_lsm_init(void) { - security_add_hooks(bpf_lsm_hooks, ARRAY_SIZE(bpf_lsm_hooks), "bpf"); + security_add_hooks(bpf_lsm_hooks, ARRAY_SIZE(bpf_lsm_hooks), + &bpf_lsmid); pr_info("LSM support for eBPF active\n"); return 0; } diff --git a/security/commoncap.c b/security/commoncap.c index 59bf3c1674c8..959a9f96b7f1 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -1341,6 +1341,11 @@ int cap_mmap_file(struct file *file, unsigned long reqprot, #ifdef CONFIG_SECURITY +static struct lsm_id capability_lsmid __lsm_ro_after_init = { + .lsm = "capability", + .slot = LSMBLOB_NOT_NEEDED +}; + static struct security_hook_list capability_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(capable, cap_capable), LSM_HOOK_INIT(settime, cap_settime), @@ -1365,7 +1370,7 @@ static struct security_hook_list capability_hooks[] __lsm_ro_after_init = { static int __init capability_init(void) { security_add_hooks(capability_hooks, ARRAY_SIZE(capability_hooks), - "capability"); + &capability_lsmid); return 0; } diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index 9b5adeaa47fc..cd393aaa17d5 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -79,7 +79,7 @@ struct ima_rule_entry { bool (*fowner_op)(kuid_t, kuid_t); /* uid_eq(), uid_gt(), uid_lt() */ int pcr; struct { - void *rule; /* LSM file metadata specific */ + void *rules[LSMBLOB_ENTRIES]; /* LSM file metadata specific */ char *args_p; /* audit value */ int type; /* audit type */ } lsm[MAX_LSM_RULES]; @@ -88,6 +88,22 @@ struct ima_rule_entry { struct ima_template_desc *template; }; +/** + * ima_lsm_isset - Is a rule set for any of the active security modules + * @rules: The set of IMA rules to check. + * + * If a rule is set for any LSM return true, otherwise return false. + */ +static inline bool ima_lsm_isset(void *rules[]) +{ + int i; + + for (i = 0; i < LSMBLOB_ENTRIES; i++) + if (rules[i]) + return true; + return false; +} + /* * Without LSM specific knowledge, the default policy can only be * written in terms of .action, .func, .mask, .fsmagic, .uid, and .fowner @@ -326,9 +342,11 @@ static void ima_free_rule_opt_list(struct ima_rule_opt_list *opt_list) static void ima_lsm_free_rule(struct ima_rule_entry *entry) { int i; + int r; for (i = 0; i < MAX_LSM_RULES; i++) { - ima_filter_rule_free(entry->lsm[i].rule); + for (r = 0; r < LSMBLOB_ENTRIES; r++) + ima_filter_rule_free(entry->lsm[i].rules[r]); kfree(entry->lsm[i].args_p); } } @@ -379,8 +397,8 @@ static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry) ima_filter_rule_init(nentry->lsm[i].type, Audit_equal, nentry->lsm[i].args_p, - &nentry->lsm[i].rule); - if (!nentry->lsm[i].rule) + &nentry->lsm[i].rules[0]); + if (!ima_lsm_isset(nentry->lsm[i].rules)) pr_warn("rule for LSM \'%s\' is undefined\n", nentry->lsm[i].args_p); } @@ -545,7 +563,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode, int rc = 0; u32 osid; - if (!rule->lsm[i].rule) { + if (!ima_lsm_isset(rule->lsm[i].rules)) { if (!rule->lsm[i].args_p) continue; else @@ -558,14 +576,14 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode, security_inode_getsecid(inode, &osid); rc = ima_filter_rule_match(osid, rule->lsm[i].type, Audit_equal, - rule->lsm[i].rule); + rule->lsm[i].rules); break; case LSM_SUBJ_USER: case LSM_SUBJ_ROLE: case LSM_SUBJ_TYPE: rc = ima_filter_rule_match(secid, rule->lsm[i].type, Audit_equal, - rule->lsm[i].rule); + rule->lsm[i].rules); default: break; } @@ -952,7 +970,7 @@ static int ima_lsm_rule_init(struct ima_rule_entry *entry, { int result; - if (entry->lsm[lsm_rule].rule) + if (ima_lsm_isset(entry->lsm[lsm_rule].rules)) return -EINVAL; entry->lsm[lsm_rule].args_p = match_strdup(args); @@ -962,8 +980,8 @@ static int ima_lsm_rule_init(struct ima_rule_entry *entry, entry->lsm[lsm_rule].type = audit_type; result = ima_filter_rule_init(entry->lsm[lsm_rule].type, Audit_equal, entry->lsm[lsm_rule].args_p, - &entry->lsm[lsm_rule].rule); - if (!entry->lsm[lsm_rule].rule) { + &entry->lsm[lsm_rule].rules[0]); + if (!ima_lsm_isset(entry->lsm[lsm_rule].rules)) { pr_warn("rule for LSM \'%s\' is undefined\n", entry->lsm[lsm_rule].args_p); @@ -1733,7 +1751,7 @@ int ima_policy_show(struct seq_file *m, void *v) } for (i = 0; i < MAX_LSM_RULES; i++) { - if (entry->lsm[i].rule) { + if (ima_lsm_isset(entry->lsm[i].rules)) { switch (i) { case LSM_OBJ_USER: seq_printf(m, pt(Opt_obj_user), diff --git a/security/loadpin/loadpin.c b/security/loadpin/loadpin.c index b12f7d986b1e..b569f3bc170b 100644 --- a/security/loadpin/loadpin.c +++ b/security/loadpin/loadpin.c @@ -192,6 +192,11 @@ static int loadpin_load_data(enum kernel_load_data_id id, bool contents) return loadpin_read_file(NULL, (enum kernel_read_file_id) id, contents); } +static struct lsm_id loadpin_lsmid __lsm_ro_after_init = { + .lsm = "loadpin", + .slot = LSMBLOB_NOT_NEEDED +}; + static struct security_hook_list loadpin_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(sb_free_security, loadpin_sb_free_security), LSM_HOOK_INIT(kernel_read_file, loadpin_read_file), @@ -239,7 +244,8 @@ static int __init loadpin_init(void) pr_info("ready to pin (currently %senforcing)\n", enforce ? "" : "not "); parse_exclude(); - security_add_hooks(loadpin_hooks, ARRAY_SIZE(loadpin_hooks), "loadpin"); + security_add_hooks(loadpin_hooks, ARRAY_SIZE(loadpin_hooks), + &loadpin_lsmid); return 0; } diff --git a/security/lockdown/lockdown.c b/security/lockdown/lockdown.c index 87cbdc64d272..4e24ea3f7b7e 100644 --- a/security/lockdown/lockdown.c +++ b/security/lockdown/lockdown.c @@ -75,6 +75,11 @@ static struct security_hook_list lockdown_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(locked_down, lockdown_is_locked_down), }; +static struct lsm_id lockdown_lsmid __lsm_ro_after_init = { + .lsm = "lockdown", + .slot = LSMBLOB_NOT_NEEDED +}; + static int __init lockdown_lsm_init(void) { #if defined(CONFIG_LOCK_DOWN_KERNEL_FORCE_INTEGRITY) @@ -83,7 +88,7 @@ static int __init lockdown_lsm_init(void) lock_kernel_down("Kernel configuration", LOCKDOWN_CONFIDENTIALITY_MAX); #endif security_add_hooks(lockdown_hooks, ARRAY_SIZE(lockdown_hooks), - "lockdown"); + &lockdown_lsmid); return 0; } diff --git a/security/safesetid/lsm.c b/security/safesetid/lsm.c index 8a176b6adbe5..7c7ac9bfe5cd 100644 --- a/security/safesetid/lsm.c +++ b/security/safesetid/lsm.c @@ -244,6 +244,11 @@ static int safesetid_task_fix_setgid(struct cred *new, return -EACCES; } +static struct lsm_id safesetid_lsmid __lsm_ro_after_init = { + .lsm = "safesetid", + .slot = LSMBLOB_NOT_NEEDED +}; + static struct security_hook_list safesetid_security_hooks[] = { LSM_HOOK_INIT(task_fix_setuid, safesetid_task_fix_setuid), LSM_HOOK_INIT(task_fix_setgid, safesetid_task_fix_setgid), @@ -253,7 +258,8 @@ static struct security_hook_list safesetid_security_hooks[] = { static int __init safesetid_security_init(void) { security_add_hooks(safesetid_security_hooks, - ARRAY_SIZE(safesetid_security_hooks), "safesetid"); + ARRAY_SIZE(safesetid_security_hooks), + &safesetid_lsmid); /* Report that SafeSetID successfully initialized */ safesetid_initialized = 1; diff --git a/security/security.c b/security/security.c index 5da8b3643680..d01363cb0082 100644 --- a/security/security.c +++ b/security/security.c @@ -341,6 +341,7 @@ static void __init ordered_lsm_init(void) init_debug("msg_msg blob size = %d\n", blob_sizes.lbs_msg_msg); init_debug("sock blob size = %d\n", blob_sizes.lbs_sock); init_debug("task blob size = %d\n", blob_sizes.lbs_task); + init_debug("lsmblob size = %zu\n", sizeof(struct lsmblob)); /* * Create any kmem_caches needed for blobs @@ -468,21 +469,36 @@ static int lsm_append(const char *new, char **result) return 0; } +/* + * Current index to use while initializing the lsmblob secid list. + */ +static int lsm_slot __lsm_ro_after_init; + /** * security_add_hooks - Add a modules hooks to the hook lists. * @hooks: the hooks to add * @count: the number of hooks to add - * @lsm: the name of the security module + * @lsmid: the the identification information for the security module * * Each LSM has to register its hooks with the infrastructure. + * If the LSM is using hooks that export secids allocate a slot + * for it in the lsmblob. */ void __init security_add_hooks(struct security_hook_list *hooks, int count, - char *lsm) + struct lsm_id *lsmid) { int i; + if (lsmid->slot == LSMBLOB_NEEDED) { + if (lsm_slot >= LSMBLOB_ENTRIES) + panic("%s Too many LSMs registered.\n", __func__); + lsmid->slot = lsm_slot++; + init_debug("%s assigned lsmblob slot %d\n", lsmid->lsm, + lsmid->slot); + } + for (i = 0; i < count; i++) { - hooks[i].lsm = lsm; + hooks[i].lsmid = lsmid; hlist_add_tail_rcu(&hooks[i].list, hooks[i].head); } @@ -491,7 +507,7 @@ void __init security_add_hooks(struct security_hook_list *hooks, int count, * and fix this up afterwards. */ if (slab_is_available()) { - if (lsm_append(lsm, &lsm_names) < 0) + if (lsm_append(lsmid->lsm, &lsm_names) < 0) panic("%s - Cannot get early memory.\n", __func__); } } @@ -2005,7 +2021,7 @@ int security_getprocattr(struct task_struct *p, const char *lsm, char *name, struct security_hook_list *hp; hlist_for_each_entry(hp, &security_hook_heads.getprocattr, list) { - if (lsm != NULL && strcmp(lsm, hp->lsm)) + if (lsm != NULL && strcmp(lsm, hp->lsmid->lsm)) continue; return hp->hook.getprocattr(p, name, value); } @@ -2018,7 +2034,7 @@ int security_setprocattr(const char *lsm, const char *name, void *value, struct security_hook_list *hp; hlist_for_each_entry(hp, &security_hook_heads.setprocattr, list) { - if (lsm != NULL && strcmp(lsm, hp->lsm)) + if (lsm != NULL && strcmp(lsm, hp->lsmid->lsm)) continue; return hp->hook.setprocattr(name, value, size); } @@ -2510,7 +2526,24 @@ int security_key_getsecurity(struct key *key, char **_buffer) int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule) { - return call_int_hook(audit_rule_init, 0, field, op, rulestr, lsmrule); + struct security_hook_list *hp; + bool one_is_good = false; + int rc = 0; + int trc; + + hlist_for_each_entry(hp, &security_hook_heads.audit_rule_init, list) { + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + trc = hp->hook.audit_rule_init(field, op, rulestr, + &lsmrule[hp->lsmid->slot]); + if (trc == 0) + one_is_good = true; + else + rc = trc; + } + if (one_is_good) + return 0; + return rc; } int security_audit_rule_known(struct audit_krule *krule) @@ -2518,14 +2551,31 @@ int security_audit_rule_known(struct audit_krule *krule) return call_int_hook(audit_rule_known, 0, krule); } -void security_audit_rule_free(void *lsmrule) +void security_audit_rule_free(void **lsmrule) { - call_void_hook(audit_rule_free, lsmrule); + struct security_hook_list *hp; + + hlist_for_each_entry(hp, &security_hook_heads.audit_rule_free, list) { + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + hp->hook.audit_rule_free(lsmrule[hp->lsmid->slot]); + } } -int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule) +int security_audit_rule_match(u32 secid, u32 field, u32 op, void **lsmrule) { - return call_int_hook(audit_rule_match, 0, secid, field, op, lsmrule); + struct security_hook_list *hp; + int rc; + + hlist_for_each_entry(hp, &security_hook_heads.audit_rule_match, list) { + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + rc = hp->hook.audit_rule_match(secid, field, op, + &lsmrule[hp->lsmid->slot]); + if (rc) + return rc; + } + return 0; } #endif /* CONFIG_AUDIT */ diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 2748281a5cca..52a50d7ca534 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -6933,6 +6933,11 @@ static int selinux_perf_event_write(struct perf_event *event) } #endif +static struct lsm_id selinux_lsmid __lsm_ro_after_init = { + .lsm = "selinux", + .slot = LSMBLOB_NEEDED +}; + /* * IMPORTANT NOTE: When adding new hooks, please be careful to keep this order: * 1. any hooks that don't belong to (2.) or (3.) below, @@ -7244,7 +7249,8 @@ static __init int selinux_init(void) hashtab_cache_init(); - security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks), "selinux"); + security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks), + &selinux_lsmid); if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET)) panic("SELinux: Unable to register AVC netcache callback\n"); diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index ca4a6c862732..f96be93d1a75 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -4693,6 +4693,11 @@ struct lsm_blob_sizes smack_blob_sizes __lsm_ro_after_init = { .lbs_sock = sizeof(struct socket_smack), }; +static struct lsm_id smack_lsmid __lsm_ro_after_init = { + .lsm = "smack", + .slot = LSMBLOB_NEEDED +}; + static struct security_hook_list smack_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(ptrace_access_check, smack_ptrace_access_check), LSM_HOOK_INIT(ptrace_traceme, smack_ptrace_traceme), @@ -4892,7 +4897,7 @@ static __init int smack_init(void) /* * Register with LSM */ - security_add_hooks(smack_hooks, ARRAY_SIZE(smack_hooks), "smack"); + security_add_hooks(smack_hooks, ARRAY_SIZE(smack_hooks), &smack_lsmid); smack_enabled = 1; pr_info("Smack: Initializing.\n"); diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c index 1f3cd432d830..22f62c67f2ec 100644 --- a/security/tomoyo/tomoyo.c +++ b/security/tomoyo/tomoyo.c @@ -523,6 +523,11 @@ static void tomoyo_task_free(struct task_struct *task) } } +static struct lsm_id tomoyo_lsmid __lsm_ro_after_init = { + .lsm = "tomoyo", + .slot = LSMBLOB_NOT_NEEDED +}; + /* * tomoyo_security_ops is a "struct security_operations" which is used for * registering TOMOYO. @@ -575,7 +580,8 @@ static int __init tomoyo_init(void) struct tomoyo_task *s = tomoyo_task(current); /* register ourselves with the security framework */ - security_add_hooks(tomoyo_hooks, ARRAY_SIZE(tomoyo_hooks), "tomoyo"); + security_add_hooks(tomoyo_hooks, ARRAY_SIZE(tomoyo_hooks), + &tomoyo_lsmid); pr_info("TOMOYO Linux initialized\n"); s->domain_info = &tomoyo_kernel_domain; atomic_inc(&tomoyo_kernel_domain.users); diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c index 06e226166aab..a9639ea541f7 100644 --- a/security/yama/yama_lsm.c +++ b/security/yama/yama_lsm.c @@ -421,6 +421,11 @@ static int yama_ptrace_traceme(struct task_struct *parent) return rc; } +static struct lsm_id yama_lsmid __lsm_ro_after_init = { + .lsm = "yama", + .slot = LSMBLOB_NOT_NEEDED +}; + static struct security_hook_list yama_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(ptrace_access_check, yama_ptrace_access_check), LSM_HOOK_INIT(ptrace_traceme, yama_ptrace_traceme), @@ -477,7 +482,7 @@ static inline void yama_init_sysctl(void) { } static int __init yama_init(void) { pr_info("Yama: becoming mindful.\n"); - security_add_hooks(yama_hooks, ARRAY_SIZE(yama_hooks), "yama"); + security_add_hooks(yama_hooks, ARRAY_SIZE(yama_hooks), &yama_lsmid); yama_init_sysctl(); return 0; } From patchwork Wed Nov 4 23:40:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11882587 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C82E6C4741F for ; Wed, 4 Nov 2020 23:48:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 75EB720825 for ; Wed, 4 Nov 2020 23:48:52 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="qSjCSL2S" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387570AbgKDXsw (ORCPT ); Wed, 4 Nov 2020 18:48:52 -0500 Received: from sonic313-15.consmr.mail.ne1.yahoo.com ([66.163.185.38]:45375 "EHLO sonic313-15.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387551AbgKDXsL (ORCPT ); Wed, 4 Nov 2020 18:48:11 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604533689; bh=erYMDd+BdGzaMY+IvBFczstUTN3hSKUThjOkBNjJt+c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=qSjCSL2S2gBTEuXRhfCDrlb8RKq1lUu7x2yOcsZId5zsjEJ1kQ9HKLrh/behyMpEEZK19JD64/PCgLiy1L2vRjMMJ3HFhO7fR6pnFC+TzTmvyjJgrrmGF0HS5g/BItFaPoGfEwr+eX+9TgqccCz7zDNeQkxU2X/DJGbiLgBr3BnfgTIp6WyqS95DNacX+5bLSVYylO+PFqY0R2BI2dZCMq+DaDLlW9ixV6GrCXpdYyBFgKh3q/RkWhh/GAgEh0tFVWQdC17VmkYl5+jTRBxbgrNLp3Qdx2QYrVFAl+SFgkCpNFn9O4pXknpUWGm/biTt+j0UMlhjAxM741+zeNFNhA== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604533689; bh=4lh4PWuyVUUM3xU9NJmf3tXgWtHj3/WbGvOmkowUM2E=; h=From:To:Subject:Date; b=NMG+ICDf3kO+TC8jjtjhtnXz6wlJjRoEkJEexO1YkT1EIW27StyVN6WChmms26tzdFtP7kD1S9eHhNs+XXrZjs74wafvPBtW1blet1vkJUASXa3ycat1KzcYcrdPmror7WnbU0zc+OnCz2pTh+1kpxzOAnRhgWeROzy/tum5cxMwBko727JrIqjo2AJrPzmPmNDeYsSxKGjwTgbzP1GYYoASJBTdnOYfXSKIKFY3LvO+YiyzHXfbzy1GLiR+cc+PBs9ahmvPHAv3emRUhBDjY5eEFvxFlS+s8TYrhZHidJftoLTC+Ax9zufBTeHhNk7sdHefFnDUO5U48+zXF8V10g== X-YMail-OSG: sr93T28VM1n6TGxeFIa62emefs8J6r4XSXUwAUnAyj1PNJ3H6lNuTVA1_U2E7Mg ZSmmEwSymITOoXHHVaYK4x1J9qz9nz83aD_TGzlIs7_PhEgtv.9JuQxTk3ot6bzxp1Xp2uJN3xOK pnu9lz7nhkkKt5c_5TwkPw_qjVZeqfVZ6Ra2jBY_2oR8SAV0KIjcUbhzdUMLHhQ8Hu6zCHjUDk4k Cw653g.CNkl4Z17j58v9adxh3cXFvc9HvxVkpKkXEp2NYfoqnRNu0VNnmPrVn76MGkEGItm.qqkV AQIMvMthHtJcrsK70fvFeH8V8WZ8Pq50UnFekarLI8Acw0OVOJf99gRmD2APZGFG_Y56ptOkiuiG NhkKTO1XAEKmTZeFCwMIcjWn386FpExsBJ.BqP2pmvgoQCyUTAfsMyGOThfMiu7L1No65Rhep6f6 PMvmM5tk0Xd0yFJ7RhmTDEslcoqcSQIrxpiv_h4MAfeQyAH1M_Ox0NnY0zRr4DR1nKNhlvbldwns q9fdASJy6APn.2omVejmsSTwSkdf7Vu7.5wR3dqIZ96wNZumeYSWZ3oFf1nHgwxk0dbK1JU8tnQt 5Wutxnw2dWUrwTCznH432GAp_bpHvYiIT_FF1Bk7Orf13SUbzV.zph39PR_s5tpqhnSKczL.NBBh KljkhkVpkrf0JDijbWCLEtPMIW9F6X_i9lrRBg9hy9JMwprQAcuz.EzccSWh.A9be0IpCuDHD2IR TMduVV3.KkX81HzDnN_m0Hbzc1mWZxOUGSu_x.nJ9aDaQ7qbsWYg59Q1BChLDw2rHGp4kx0ljma6 qKsLoNTtZD0ZMbHhbiEHzBwRbXhtKBGbzNeGm8I6t.SMKFgukIhQ98.pstw24Skm425sMwLNa6_P TKPGiI7SVCcVaDtuMbZUNS.YdAIAiE9gFzsf48I8P2SRPtqW79v3v8eutsnu2hNno6BQiL4Bn3Wn fR93FSXbNTcfYWSPsUvWoYZrpj6HI3PGWgmaE9kr.KenwNEuCSlFM2RHWAFL48bVEaC9oE9C7_dR IWSe4KcZjB_Zrv_7WyyzSyt7_HqAMB8Q8wv_l7YMWab9VDVqFME6nE4WOzMzWzLFzVJtsHGsKbBy UCGydTbxCHHyYACZA60tilGh3lwnDQg8pqXzAFAhb1Z_wAhq.jcv5xihZdKASpPE4y81Py.uC8Wc .QsyLoznKLA1hp2XD.OrYYqI99WNrYzSIqNoH.NkMz9D97DS7DI5VL2HQldxiYP3ZTI6CnUe2eog j4Nro6ER9pvQM9VUo4cjT2rVxEbT3rHMl_pkedFuJK_X.LCpYMqNHRyd.IfKzq05ejZWhzCSxObI CbsRNRkA_uT_c9TmTVXURZ15jXJiviJ7TPj46J1t4_lZ1qQgcVrM7srZrqG1emZPZYJCu8X.uDC0 9NC2oNL3v1iHN7_wVhhRt4pxW68Q55HmTQGaBrcZx9Xb4WVxJdaHHWVtjY_nLEcr8tOl6kPVYgVU A451baUuNtXetTRura0IiZRcmffOm4jpNo3XpjfPpCmnpSe798CTg4U0CywTsRI8LhLhnPKjyvta vK.7GAzR1nH1iSv.Z25CcnNF.KNwcb39MF3xcXmKqRuVXErZPXulOSoUq17JXYMbpF2pyicGPbUM QvPHIYhd0csOjTx2ovhKggaZszXY9SPXXgv_E7qV_N0fnO5xjMk0qHU7jbrtgyQ9hTiQkFBUOKSD ayDdq1u3Q8vpmzoNVloTBlD3kO5FUKDVrwi_fdLysCZ6x0SmwjXbcOQnRYCRmyWw2AeRFcmXIRYv t8IGr5AMl_rpfquSkfHelUkmgi16hp_R_KtzHRbLy4mVlPHOJdJ4vcT8o4SjTa3BYwh4hc5jY1Vw bEB6LlUejv9gI4jjZ3mlC7.hom7zyQKWB0uOLzQJsP8dI8k_ZWRsRuEZRjqES8sBItbrWRltzwR0 3hE.gW7QUjMKDxNXyHV5mXL4rhIifRINBqEWDeDgjSp45gPpPWUgvYc8k_BFuNQl.AXBkNr5h7BN mNhpy_LrTyWyqAPFyFT6r5dBd4Z8wcpABxrFw4317b4aRAh8zulFWbuZKao49bbBSXFRrUs6SYYq 4q95fcJum4oDu5zvVI2bwVZKXtEytzoyVcncqQzbK0WVUdZJ52EzMEIdDUQXhc5KKLE8rluS44PG yEE4DxWY.N2hDpIcioxgNm81xnZdAde68oeoJnyoRad5VIyPpVA4jXaI5k3O1DUDn4QccaEjJHo1 IOwGOZU_Eqe1ejKtq7sWWe0WajzqntOc3aVa.lS24wrDWWBd9rIdQoTvRN3crEI9fKIlmI4SF8f3 _XOVu5PmlO1uU5iAvu4zz_Ug25n2Q5g_HGKXqwbT4BpRpFibyNyRdV81i_rlblYzpToC0duMo_UM GjHg3jeQo_4ivjqX53hKMmUMEw4opYwoH1xZITw6jWAUj04_lsza1aSvzU32UnnoPtdDPJbhiSMN qPIC_FClg_ducXblqeXPVzkBY6QEUV.e0zNQNBdhJS1qf4vTfcNnhHQ_RKvcewdyuBrLO2bFOg5v sxXRdAmSQLAKaixmFX3tTR0UnhMWa4LXHHP51g4Vvp7vt2uOqwylV48x7xorCyuzTRE1nrA9KQLA gA5AuqU2yZwMJ2sxwOukmDLPiZ3yqBaCfUxHtPQ9s0LpVWJbBIqNWtFDaVk555yjder6FaQFBeeS GxJ6A.XHEGKmH4733IJPIITv80LeaLO1ytcH5WVljBxsf7uquFKNrV6ftg6rbiHqoQ3fjkSFrIo5 oEuNeLSydCCmdBi6PYPs3j.gqK.IgnDuQkgrTNfmlpkIm6.lkU5AG9x3tl2VNoKFlokONhK5leJx wr0mQITLkmj49fG.2J47SjPWr.2pIE.potr9K6AQhoGJBVxscO3IxoyMnEF68yeGAJxIrJeWrFSH FQavIdssvVF_TPb.Pmm6GlmPaoOCaF9_ojW4wI1ffNTnrtMUaX4P_LMOTKnCoyLWVFVwgwZsTXTg mhl6aOxW1DNr5QJUwarpxMUmlqvvPQ6ks42wtdR2QwHuO.d4Crwr3IQH3pbBqhjMGq2gmXxzEac_ zYnrhYWfoEijgTTjerCZd01rC4eDke44U339AzUr1rEBuIuY5W.kTYJx8unD_UBqWd1vg3Tldtxu 1RWCwDvwvs3JwNgnF2XasdeiEooozlUuNCQZ9Rghr1WfCTz_ZOJ.fYIvdLNT9qfUZZb97eYY06bq HaJdO6yXbEtXpWIl_3SRiM6LsiftyfRS7UtR5DB5GAqUhu0y7jAxfc7x1vk8W4Pt86avaJ5EhWJz 3.k.3hsP32XFaqQ57cdrCilO8nmIRvy7_SptjajVSYGgwOZy2iOBDeRvujwPEbZkyBpiOsdwsmCd XEUJQ5i0GdoqnI9lJW1Cd00iSjPzAoqZII2Ps0PjHmA-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic313.consmr.mail.ne1.yahoo.com with HTTP; Wed, 4 Nov 2020 23:48:09 +0000 Received: by smtp425.mail.ne1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID d53b5fa43e99ee2806ceeb620b264b91; Wed, 04 Nov 2020 23:48:06 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov, linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH v22 05/23] LSM: Use lsmblob in security_secctx_to_secid Date: Wed, 4 Nov 2020 15:40:56 -0800 Message-Id: <20201104234114.11346-6-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201104234114.11346-1-casey@schaufler-ca.com> References: <20201104234114.11346-1-casey@schaufler-ca.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Change the security_secctx_to_secid interface to use a lsmblob structure in place of the single u32 secid in support of module stacking. Change its callers to do the same. The security module hook is unchanged, still passing back a secid. The infrastructure passes the correct entry from the lsmblob. Signed-off-by: Casey Schaufler Cc: netdev@vger.kernel.org --- include/linux/security.h | 26 ++++++++++++++++++-- kernel/cred.c | 4 +--- net/netfilter/nft_meta.c | 10 ++++---- net/netfilter/xt_SECMARK.c | 7 +++++- net/netlabel/netlabel_unlabeled.c | 23 +++++++++++------- security/security.c | 40 ++++++++++++++++++++++++++----- 6 files changed, 85 insertions(+), 25 deletions(-) diff --git a/include/linux/security.h b/include/linux/security.h index 948d12a5eb25..0766725a6b21 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -191,6 +191,27 @@ static inline bool lsmblob_equal(struct lsmblob *bloba, struct lsmblob *blobb) return !memcmp(bloba, blobb, sizeof(*bloba)); } +/** + * lsmblob_value - find the first non-zero value in an lsmblob structure. + * @blob: Pointer to the data + * + * This needs to be used with extreme caution, as the cases where + * it is appropriate are rare. + * + * Return the first secid value set in the lsmblob. + * There should only be one. + */ +static inline u32 lsmblob_value(const struct lsmblob *blob) +{ + int i; + + for (i = 0; i < LSMBLOB_ENTRIES; i++) + if (blob->secid[i]) + return blob->secid[i]; + + return 0; +} + /* These functions are in security/commoncap.c */ extern int cap_capable(const struct cred *cred, struct user_namespace *ns, int cap, unsigned int opts); @@ -508,7 +529,8 @@ int security_setprocattr(const char *lsm, const char *name, void *value, int security_netlink_send(struct sock *sk, struct sk_buff *skb); int security_ismaclabel(const char *name); int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen); -int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid); +int security_secctx_to_secid(const char *secdata, u32 seclen, + struct lsmblob *blob); void security_release_secctx(char *secdata, u32 seclen); void security_inode_invalidate_secctx(struct inode *inode); int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen); @@ -1335,7 +1357,7 @@ static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 *secle static inline int security_secctx_to_secid(const char *secdata, u32 seclen, - u32 *secid) + struct lsmblob *blob) { return -EOPNOTSUPP; } diff --git a/kernel/cred.c b/kernel/cred.c index 22e0e7cbefde..848306c7d823 100644 --- a/kernel/cred.c +++ b/kernel/cred.c @@ -757,14 +757,12 @@ EXPORT_SYMBOL(set_security_override); int set_security_override_from_ctx(struct cred *new, const char *secctx) { struct lsmblob blob; - u32 secid; int ret; - ret = security_secctx_to_secid(secctx, strlen(secctx), &secid); + ret = security_secctx_to_secid(secctx, strlen(secctx), &blob); if (ret < 0) return ret; - lsmblob_init(&blob, secid); return set_security_override(new, &blob); } EXPORT_SYMBOL(set_security_override_from_ctx); diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c index b37bd02448d8..f1b9b0021414 100644 --- a/net/netfilter/nft_meta.c +++ b/net/netfilter/nft_meta.c @@ -811,21 +811,21 @@ static const struct nla_policy nft_secmark_policy[NFTA_SECMARK_MAX + 1] = { static int nft_secmark_compute_secid(struct nft_secmark *priv) { - u32 tmp_secid = 0; + struct lsmblob blob; int err; - err = security_secctx_to_secid(priv->ctx, strlen(priv->ctx), &tmp_secid); + err = security_secctx_to_secid(priv->ctx, strlen(priv->ctx), &blob); if (err) return err; - if (!tmp_secid) + if (!lsmblob_is_set(&blob)) return -ENOENT; - err = security_secmark_relabel_packet(tmp_secid); + err = security_secmark_relabel_packet(lsmblob_value(&blob)); if (err) return err; - priv->secid = tmp_secid; + priv->secid = lsmblob_value(&blob); return 0; } diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c index 75625d13e976..9845d98e6b77 100644 --- a/net/netfilter/xt_SECMARK.c +++ b/net/netfilter/xt_SECMARK.c @@ -43,13 +43,14 @@ secmark_tg(struct sk_buff *skb, const struct xt_action_param *par) static int checkentry_lsm(struct xt_secmark_target_info *info) { + struct lsmblob blob; int err; info->secctx[SECMARK_SECCTX_MAX - 1] = '\0'; info->secid = 0; err = security_secctx_to_secid(info->secctx, strlen(info->secctx), - &info->secid); + &blob); if (err) { if (err == -EINVAL) pr_info_ratelimited("invalid security context \'%s\'\n", @@ -57,6 +58,10 @@ static int checkentry_lsm(struct xt_secmark_target_info *info) return err; } + /* xt_secmark_target_info can't be changed to use lsmblobs because + * it is exposed as an API. Use lsmblob_value() to get the one + * value that got set by security_secctx_to_secid(). */ + info->secid = lsmblob_value(&blob); if (!info->secid) { pr_info_ratelimited("unable to map security context \'%s\'\n", info->secctx); diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 2e8e3f7b2111..8c064342169f 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -882,7 +882,7 @@ static int netlbl_unlabel_staticadd(struct sk_buff *skb, void *addr; void *mask; u32 addr_len; - u32 secid; + struct lsmblob blob; struct netlbl_audit audit_info; /* Don't allow users to add both IPv4 and IPv6 addresses for a @@ -906,13 +906,18 @@ static int netlbl_unlabel_staticadd(struct sk_buff *skb, ret_val = security_secctx_to_secid( nla_data(info->attrs[NLBL_UNLABEL_A_SECCTX]), nla_len(info->attrs[NLBL_UNLABEL_A_SECCTX]), - &secid); + &blob); if (ret_val != 0) return ret_val; + /* netlbl_unlhsh_add will be changed to pass a struct lsmblob * + * instead of a u32 later in this patch set. security_secctx_to_secid() + * will only be setting one entry in the lsmblob struct, so it is + * safe to use lsmblob_value() to get that one value. */ + return netlbl_unlhsh_add(&init_net, - dev_name, addr, mask, addr_len, secid, - &audit_info); + dev_name, addr, mask, addr_len, + lsmblob_value(&blob), &audit_info); } /** @@ -933,7 +938,7 @@ static int netlbl_unlabel_staticadddef(struct sk_buff *skb, void *addr; void *mask; u32 addr_len; - u32 secid; + struct lsmblob blob; struct netlbl_audit audit_info; /* Don't allow users to add both IPv4 and IPv6 addresses for a @@ -955,13 +960,15 @@ static int netlbl_unlabel_staticadddef(struct sk_buff *skb, ret_val = security_secctx_to_secid( nla_data(info->attrs[NLBL_UNLABEL_A_SECCTX]), nla_len(info->attrs[NLBL_UNLABEL_A_SECCTX]), - &secid); + &blob); if (ret_val != 0) return ret_val; + /* security_secctx_to_secid() will only put one secid into the lsmblob + * so it's safe to use lsmblob_value() to get the secid. */ return netlbl_unlhsh_add(&init_net, - NULL, addr, mask, addr_len, secid, - &audit_info); + NULL, addr, mask, addr_len, + lsmblob_value(&blob), &audit_info); } /** diff --git a/security/security.c b/security/security.c index 3a88a90ddba6..eac7c10b8cfa 100644 --- a/security/security.c +++ b/security/security.c @@ -2081,10 +2081,22 @@ int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) } EXPORT_SYMBOL(security_secid_to_secctx); -int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) +int security_secctx_to_secid(const char *secdata, u32 seclen, + struct lsmblob *blob) { - *secid = 0; - return call_int_hook(secctx_to_secid, 0, secdata, seclen, secid); + struct security_hook_list *hp; + int rc; + + lsmblob_init(blob, 0); + hlist_for_each_entry(hp, &security_hook_heads.secctx_to_secid, list) { + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + rc = hp->hook.secctx_to_secid(secdata, seclen, + &blob->secid[hp->lsmid->slot]); + if (rc != 0) + return rc; + } + return 0; } EXPORT_SYMBOL(security_secctx_to_secid); @@ -2235,10 +2247,26 @@ int security_socket_getpeersec_stream(struct socket *sock, char __user *optval, optval, optlen, len); } -int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid) +int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, + u32 *secid) { - return call_int_hook(socket_getpeersec_dgram, -ENOPROTOOPT, sock, - skb, secid); + struct security_hook_list *hp; + int rc = -ENOPROTOOPT; + + /* + * Only one security module should provide a real hook for + * this. A stub or bypass like is used in BPF should either + * (somehow) leave rc unaltered or return -ENOPROTOOPT. + */ + hlist_for_each_entry(hp, &security_hook_heads.socket_getpeersec_dgram, + list) { + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + rc = hp->hook.socket_getpeersec_dgram(sock, skb, secid); + if (rc != -ENOPROTOOPT) + break; + } + return rc; } EXPORT_SYMBOL(security_socket_getpeersec_dgram); From patchwork Wed Nov 4 23:40:59 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11882697 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D8575C55178 for ; Wed, 4 Nov 2020 23:53:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 72FA0206C3 for ; Wed, 4 Nov 2020 23:53:13 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="i551Wzt3" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387851AbgKDXxK (ORCPT ); Wed, 4 Nov 2020 18:53:10 -0500 Received: from sonic301-38.consmr.mail.ne1.yahoo.com ([66.163.184.207]:44122 "EHLO sonic301-38.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387619AbgKDXv3 (ORCPT ); Wed, 4 Nov 2020 18:51:29 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604533887; bh=eZeO09DJlcX2wY8AdT21fgnfDkYz/4ihUnMP/xr6IW4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=i551Wzt33ltZfd8lOj0K7F8tISSsfwFLA+MV6ZW3oRBErZn+RKI5gFwGYBOCHMq1y8GPqjOMpqwPS7/XgNpnd9SNzHYFxHlH6U/PcLY7TUD2JczJFJkQiY+dG/9naLRFZ+p3BFbwLDQamE8f5JFSAeZ6X51cHG8ycg7OaGN02FBDqD3uo9XPQLR5mHF+XeorCD/Mw4O0T317cbf1paPCNeq9Vv3Il5BO970kKyQaVIFL1ZWIQzeKdkcXBn41eR/XDpbohqDIEyq2zNkowD85eDARV5qhbwYLFzRlLsgUpR5kIRLXWbILg+v030Ph0BEeGpNaCqihXnCyf4dTbTaQrQ== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604533887; bh=Pz5ZBcP0XdSBWBdSYxf4t3NLqu3W/7Yxa+xzAYcjUq9=; h=From:To:Subject:Date; b=SuMvk9WXeNGevQd447PnvN2YqWxjEzUpZMa/9Z+ajHGhhmbnyGB8MM51RGrPu3Z3MNzY3PmqGHrQAC8/wW2z4xNOxQlpLh2jN+ZzuMOaQNZ0C/1mW0U08qkitk21AT4AJa2FZsBYHVZYETlbkZ+Wl+AoZxSNwBuPLS9my4V+SL77u5Ha4kanHBGIJELlbgegzk2wvba/LG+RkLQHYGSLLyUaszcJFfLGx+8GvMFb18/4LZmNUYBwxYq08iQ2O9+R5ekBnLDs4aGXTNWGfiVCjCycz0L5pht0q9Mz17kfT1DOnIIC1fcZsJXe28cNmibO62fr8g8wh2bm59rIit/TCQ== X-YMail-OSG: JWufGrMVM1nvQtbpG73LNP6MlH08ll8BtZg7sbfpx85QxKbObE0ypmzwwyppB49 g07GIL3aSsv.E.rQzCmv6CisKz7CfzzjmhMceD35jJ8Gu0Mt9zzT0hPz4tSVXMvwvB5u5ldXwUQ6 LV7rxBcg0oQpzdRCzxhJAKHfuqDdaeoVffDJRqRJAbhWUS_3auzSjQOzaQadC6dqOvTWaJjZieoG ZGlxM97smw51PNGFRrqekfwGSOexvEuPkTMtuV0DSYQ64dxNt.AUW6oXi1BsfF6wA0OSbH8wqKoY 5ycrD1tL798OSGaIGuZr70aewIs4QkH9KY3CuP0lyKtPIeU8NDHAcZI6EEJ9ZaZuzSD1jeVlek72 b3HTCShFwNv_oK9SO5_DpyTS27nOqjIXg.ABrXHl2SKQ_czL7QEsv_dAwZSHa46X2f5I4JdiTHlb 7Pr77lr4tLqKYlD_sp8n.LcPMI_C39rFcnkPTHlNxKubaEpYa.REvDfWV7vQ6UHpMP2rZxmjiTRo tnZoyAsQUbKwn_xlGrrzcV8DTuVmzPeOT0VbqLgOCQf0Bwad_XVmCZENBWa6SONtgZX6JJ39mTFd UCil8Pz2hpxYhX6YVbsOe.SrCwQfkHIcUQtc3eYjC4YKs.kxq_tCvSbmTDrgXHNyfYoEspcZcSL5 xOQViMywIBc7QMACoPWwGNmkOF_4M2Nl98BOH61kjpXlD5jKHX8j1XsAR.WUicGEk0I3PY0Okf77 AcoMRnOZV.ALEXfMoLLYyesRpyg94n95gvxmqeIGP3Zh7Erxu0V3dbU3Jw0oA1OL6fsq.kRU5r8s O90LFaQg5lEsLZiZBrqxytP6QexjUjSf.mAxV9KGUHxiGym6e_Tkn3vHOeIrIiKh5WkS6K2n5IcW 9c6CNT3QEJzKXQIgx6N1MRbUafA4co6k3nAiT2mJDLRs4_slUsITGKCgMMsicQBD7CpsHBWJbWVe kc3SeKxtN1S5QNEOfuqyzusNJmzLcV5UmEyYpyJp47wDY9rdn5lmX_FykO8nb6XVQuxVqExX4KZZ ajJs4p6biVO51XqKKY9hhRSM_hWIq6lyvIF9C8foa0Ar8U356yupv8DblMvdZJ7eWOt3mBjyr3A4 dKLbtJLtGiDQ1OiAdpGSx3lB3BzjL5hlREVjAfpO1JdvscGKrgynyWfkuCzlAc_bnVnCc3sX9Evr Ko3MOE.9TXTmE1Tsxr.syMACCV9ITHRGJFMpFLiH8.eR.nmwG3NLuyfoohiTGVC5N610Stu19E1i p4hlN4bKKTldpxVzgeQpWs8gTEWcTZKXm4XOsjy74dU7IhCpmJeg2vY.xBKZD4ah.zYgwIvPeZPB RhjETfoJA_u7MUIrKDwrLst4zch6zTOSz0.LlX3TEpKmkb7eFWmhW48.VNlbn1wb.kzxuoK11OmB aVZ_sVJVe5D_H3hyTJBkvnbYHn71GmsPoq5aU4Js3wjBVlnmSBc2b_3pdZYpxCRpW90TgXG0dL9z bfRukSnGGzQikJZZaxyPy7hWq5xIbvN32.OUskcaPRqZlZTr9py1UmYjhWg9Zc3Ez4dJ3e5q8A80 bnT6stCrdYpF.kT9WWE2zvMq1E42xualJ7LlkVY.lExZlfkb_FvSLhDruPLNka71zf5_TUWo0dFf JaSO1eUm3cj.xDGRFb38pff6Cn_wDutpwjC4zSa0U9Q2LEetY6H4shsWFkk4o8Z1Tc6tb8vD4ly6 ZutEq7ZHbcLeQ2BIky1kmJRz1ch4fQc9vtAoexctP1F9ejdjxZnGVR8NbLYylmizlViwaX8LyOT_ 3mR7rb_NoFskC.hNzsIqbMry_5jeGCj7E7Y_lAYA_X1GfF81ij0tX.mIJK93OJHQSaZhpMPzOPMP 0GOZz0MExNTr.YS8hojxWPvoSdLhYfjmtnRL_fr0Kfw.fXdYmbMuMxQ0oKFTf40p.xa1dj8F_PrM AzoiT464k_SzSnN1iwBbU3BIgr1ERudLraKplKOhO85eQuMOwgEhS6wSZTy.WNqe0YRgHH6YMcvW A8lZ7Hr73irEFjvgSKBNdNyQrsIP3AnaBIjcYgKnlG_vC5UxfP_bwLc2nVBPfBnj7rfXZpvHk09e 2kalcOpPvMEaIL4ZQEP4UisX8V5BbL2XR08z9ytzlzqELGnUQm6H0vpRfWpdUmNeFO1S5.ZQUpPk cDAAiPTsBjh_X60CsQZXOx57KiZQGD0QSk5BUQg0S.1ynfR.RvYRPP8aV7_Dh4CgrsTK8p7g_w9l kixEE8Zu5_1IKtFVMQh46.W1GUhkNrTuJnHdXlUpl5JCNhlLQz_bMzoOzUxTolaMRYZr5sHaRWRc G2OZkAXl7sZ7YzrUyLpf1spJqtG6bP4kmOqrc4bWNy2foRQYydobFJoIE7OS8RfTySeXXEGKKEEm 3DjxjuZ55PF_qcEW2K.IfDPJiKOHx__rREtZouqQRQG34NreiitJWZnTgHMFeLNEqQyLlY_MbVbz TjvLX1ygIPGAhXAGqQQrGbJwCnrque2ICAQzL.GGqXZSA9cjr55.lzgPNoYm4nT6qEqXfPzGOuUz S8ELXU505OAu6HHIF1YB2Ax2vDIUgF53FGCxFvAIyuP8iuHqEoPH4C.fDtJoQz_amwfpqRA65cHw wUuuDp8i4BAXuhr3LPT9em2YzKtyOLfR3C0N9YOM6D89sYS8oF_2Zq5jnno7Lc3KULne333_pakF srcd2Lhu.Ivvqfv_LG9qx_h2xcPRZo1m3woEGObyBtRxaqUzjhgPh4M2m2GWu9Zg5Yc8BHa5Vc3P 5MMVnEZT7QjF9qLou_VfvyzoFtJiizTWkKqpjuzt1G0L1xX_SJiGadD_JthBgsXsz3Wlse_R1wR. GOxY4xaSGzBjCxN7Q_lEpfFMSGHFYgOfmpjEnDOyHlnUG7zAzmx7s3bDQ_S_rHEZIKgy8df2z9Uk ldxvjtcDZ0guSZLRKVi2cb0t1fPml5vNSy8qTj6c4FFWq4FZY9MiAWlRYt0DIr.OC0vnN2ONZDzV wz8HsGXPI4PDCYRKdS0FmOMoyKTCjOdWkYzfXH4J0EtA1txhwGRnImEotASzNNW77odP2gqtGigC P40NRJT8gpuUF0heBFY91cAAjZE9wXZw2tx2HwutHv2Kd2.gJqsS6jhWMyKCT8us5xRnKNtqTa1m R18LuA05b1zjCjTWpzpANj.3s6QoVnmVblvOdvAD4xS6VDwVCGaKfOcPOx5dxq7XEklI7SaJjSaf kkIptLVEfDBkxtZj9zuNyY3pVtZiybzMbfru1L4CXww.gJQuIToWfWxH7_QGAnqSxCeHv1V4W60t d5t0uzAcaMeyApLJRlJTreuIJORgQnMzutgXt6_4HgrTCpce3NDx12bPhfDYRAiUef11EkjWFa2o omEyNuwQ.Pm0NvoV5P16cObJz0orrPsE4eyjEqrEyDERtKqun5gXg3Ke2Xi0ZRndNvaj27CGByBc 3FfCDIkyoaYLhPozPxDDreQNAJcbPAF3YMdt7xQmPH5SAxtEHxQ-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic301.consmr.mail.ne1.yahoo.com with HTTP; Wed, 4 Nov 2020 23:51:27 +0000 Received: by smtp414.mail.ne1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID aaf521eb30ad00320d4ff2ee1d353ff2; Wed, 04 Nov 2020 23:51:22 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov, linux-kernel@vger.kernel.org, linux-integrity@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH v22 08/23] LSM: Use lsmblob in security_task_getsecid Date: Wed, 4 Nov 2020 15:40:59 -0800 Message-Id: <20201104234114.11346-9-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201104234114.11346-1-casey@schaufler-ca.com> References: <20201104234114.11346-1-casey@schaufler-ca.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Change the security_task_getsecid() interface to fill in a lsmblob structure instead of a u32 secid in support of LSM stacking. Audit interfaces will need to collect all possible secids for possible reporting. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley Acked-by: Paul Moore Signed-off-by: Casey Schaufler Cc: linux-integrity@vger.kernel.org Cc: linux-audit@redhat.com Cc: netdev@vger.kernel.org --- drivers/android/binder.c | 12 +----- include/linux/security.h | 7 ++-- kernel/audit.c | 16 +++----- kernel/auditfilter.c | 4 +- kernel/auditsc.c | 25 ++++++------ net/netlabel/netlabel_unlabeled.c | 5 ++- net/netlabel/netlabel_user.h | 6 ++- security/integrity/ima/ima_appraise.c | 10 +++-- security/integrity/ima/ima_main.c | 56 +++++++++++++++------------ security/security.c | 12 ++++-- 10 files changed, 80 insertions(+), 73 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 55f3fa073c7b..08737a07f997 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -3087,20 +3087,10 @@ static void binder_transaction(struct binder_proc *proc, t->priority = task_nice(current); if (target_node && target_node->txn_security_ctx) { - u32 secid; struct lsmblob blob; size_t added_size; - security_task_getsecid(proc->tsk, &secid); - /* - * Later in this patch set security_task_getsecid() will - * provide a lsmblob instead of a secid. lsmblob_init - * is used to ensure that all the secids in the lsmblob - * get the value returned from security_task_getsecid(), - * which means that the one expected by - * security_secid_to_secctx() will be set. - */ - lsmblob_init(&blob, secid); + security_task_getsecid(proc->tsk, &blob); ret = security_secid_to_secctx(&blob, &secctx, &secctx_sz); if (ret) { return_error = BR_FAILED_REPLY; diff --git a/include/linux/security.h b/include/linux/security.h index be8db737da74..6b9e3571960d 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -482,7 +482,7 @@ int security_task_fix_setgid(struct cred *new, const struct cred *old, int security_task_setpgid(struct task_struct *p, pid_t pgid); int security_task_getpgid(struct task_struct *p); int security_task_getsid(struct task_struct *p); -void security_task_getsecid(struct task_struct *p, u32 *secid); +void security_task_getsecid(struct task_struct *p, struct lsmblob *blob); int security_task_setnice(struct task_struct *p, int nice); int security_task_setioprio(struct task_struct *p, int ioprio); int security_task_getioprio(struct task_struct *p); @@ -1155,9 +1155,10 @@ static inline int security_task_getsid(struct task_struct *p) return 0; } -static inline void security_task_getsecid(struct task_struct *p, u32 *secid) +static inline void security_task_getsecid(struct task_struct *p, + struct lsmblob *blob) { - *secid = 0; + lsmblob_init(blob, 0); } static inline int security_task_setnice(struct task_struct *p, int nice) diff --git a/kernel/audit.c b/kernel/audit.c index 4cd6339e513d..9e3eec0a9c29 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -2136,19 +2136,12 @@ int audit_log_task_context(struct audit_buffer *ab) char *ctx = NULL; unsigned len; int error; - u32 sid; struct lsmblob blob; - security_task_getsecid(current, &sid); - if (!sid) + security_task_getsecid(current, &blob); + if (!lsmblob_is_set(&blob)) return 0; - /* - * lsmblob_init sets all values in the lsmblob to sid. - * This is temporary until security_task_getsecid is converted - * to use a lsmblob, which happens later in this patch set. - */ - lsmblob_init(&blob, sid); error = security_secid_to_secctx(&blob, &ctx, &len); if (error) { if (error != -EINVAL) @@ -2356,6 +2349,7 @@ int audit_set_loginuid(kuid_t loginuid) int audit_signal_info(int sig, struct task_struct *t) { kuid_t uid = current_uid(), auid; + struct lsmblob blob; if (auditd_test_task(t) && (sig == SIGTERM || sig == SIGHUP || @@ -2366,7 +2360,9 @@ int audit_signal_info(int sig, struct task_struct *t) audit_sig_uid = auid; else audit_sig_uid = uid; - security_task_getsecid(current, &audit_sig_sid); + security_task_getsecid(current, &blob); + /* scaffolding until audit_sig_sid is converted */ + audit_sig_sid = blob.secid[0]; } return audit_signal_info_syscall(t); diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index e27424216159..9e73a7961665 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -1330,7 +1330,6 @@ int audit_filter(int msgtype, unsigned int listtype) for (i = 0; i < e->rule.field_count; i++) { struct audit_field *f = &e->rule.fields[i]; pid_t pid; - u32 sid; struct lsmblob blob; switch (f->type) { @@ -1361,8 +1360,7 @@ int audit_filter(int msgtype, unsigned int listtype) case AUDIT_SUBJ_SEN: case AUDIT_SUBJ_CLR: if (f->lsm_isset) { - security_task_getsecid(current, &sid); - lsmblob_init(&blob, sid); + security_task_getsecid(current, &blob); result = security_audit_rule_match( &blob, f->type, f->op, f->lsm_rules); diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 35d6bd0526a2..8916a13406c3 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -473,7 +473,6 @@ static int audit_filter_rules(struct task_struct *tsk, { const struct cred *cred; int i, need_sid = 1; - u32 sid; struct lsmblob blob; unsigned int sessionid; @@ -670,17 +669,9 @@ static int audit_filter_rules(struct task_struct *tsk, logged upon error */ if (f->lsm_isset) { if (need_sid) { - security_task_getsecid(tsk, &sid); + security_task_getsecid(tsk, &blob); need_sid = 0; } - /* - * lsmblob_init sets all values in the lsmblob - * to sid. This is temporary until - * security_task_getsecid() is converted to - * provide a lsmblob, which happens later in - * this patch set. - */ - lsmblob_init(&blob, sid); result = security_audit_rule_match(&blob, f->type, f->op, @@ -2440,12 +2431,15 @@ int __audit_sockaddr(int len, void *a) void __audit_ptrace(struct task_struct *t) { struct audit_context *context = audit_context(); + struct lsmblob blob; context->target_pid = task_tgid_nr(t); context->target_auid = audit_get_loginuid(t); context->target_uid = task_uid(t); context->target_sessionid = audit_get_sessionid(t); - security_task_getsecid(t, &context->target_sid); + security_task_getsecid(t, &blob); + /* scaffolding - until target_sid is converted */ + context->target_sid = blob.secid[0]; memcpy(context->target_comm, t->comm, TASK_COMM_LEN); } @@ -2461,6 +2455,7 @@ int audit_signal_info_syscall(struct task_struct *t) struct audit_aux_data_pids *axp; struct audit_context *ctx = audit_context(); kuid_t t_uid = task_uid(t); + struct lsmblob blob; if (!audit_signals || audit_dummy_context()) return 0; @@ -2472,7 +2467,9 @@ int audit_signal_info_syscall(struct task_struct *t) ctx->target_auid = audit_get_loginuid(t); ctx->target_uid = t_uid; ctx->target_sessionid = audit_get_sessionid(t); - security_task_getsecid(t, &ctx->target_sid); + security_task_getsecid(t, &blob); + /* scaffolding until target_sid is converted */ + ctx->target_sid = blob.secid[0]; memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN); return 0; } @@ -2493,7 +2490,9 @@ int audit_signal_info_syscall(struct task_struct *t) axp->target_auid[axp->pid_count] = audit_get_loginuid(t); axp->target_uid[axp->pid_count] = t_uid; axp->target_sessionid[axp->pid_count] = audit_get_sessionid(t); - security_task_getsecid(t, &axp->target_sid[axp->pid_count]); + security_task_getsecid(t, &blob); + /* scaffolding until target_sid is converted */ + axp->target_sid[axp->pid_count] = blob.secid[0]; memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN); axp->pid_count++; diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index ba74901b89a8..94071f67e461 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -1557,11 +1557,14 @@ int __init netlbl_unlabel_defconf(void) int ret_val; struct netlbl_dom_map *entry; struct netlbl_audit audit_info; + struct lsmblob blob; /* Only the kernel is allowed to call this function and the only time * it is called is at bootup before the audit subsystem is reporting * messages so don't worry to much about these values. */ - security_task_getsecid(current, &audit_info.secid); + security_task_getsecid(current, &blob); + /* scaffolding until audit_info.secid is converted */ + audit_info.secid = blob.secid[0]; audit_info.loginuid = GLOBAL_ROOT_UID; audit_info.sessionid = 0; diff --git a/net/netlabel/netlabel_user.h b/net/netlabel/netlabel_user.h index 3c67afce64f1..438b5db6c714 100644 --- a/net/netlabel/netlabel_user.h +++ b/net/netlabel/netlabel_user.h @@ -34,7 +34,11 @@ static inline void netlbl_netlink_auditinfo(struct sk_buff *skb, struct netlbl_audit *audit_info) { - security_task_getsecid(current, &audit_info->secid); + struct lsmblob blob; + + security_task_getsecid(current, &blob); + /* scaffolding until secid is converted */ + audit_info->secid = blob.secid[0]; audit_info->loginuid = audit_get_loginuid(current); audit_info->sessionid = audit_get_sessionid(current); } diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index 3dd8c2e4314e..2a18124af429 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c @@ -65,14 +65,16 @@ bool is_ima_appraise_enabled(void) */ int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func) { - u32 secid; + struct lsmblob blob; if (!ima_appraise) return 0; - security_task_getsecid(current, &secid); - return ima_match_policy(inode, current_cred(), secid, func, mask, - IMA_APPRAISE | IMA_HASH, NULL, NULL, NULL); + security_task_getsecid(current, &blob); + /* scaffolding the .secid[0] */ + return ima_match_policy(inode, current_cred(), blob.secid[0], func, + mask, IMA_APPRAISE | IMA_HASH, NULL, NULL, + NULL); } static int ima_fix_xattr(struct dentry *dentry, diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 2d1af8899cab..c9f1f6bddab5 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -388,12 +388,13 @@ static int process_measurement(struct file *file, const struct cred *cred, */ int ima_file_mmap(struct file *file, unsigned long prot) { - u32 secid; + struct lsmblob blob; if (file && (prot & PROT_EXEC)) { - security_task_getsecid(current, &secid); - return process_measurement(file, current_cred(), secid, NULL, - 0, MAY_EXEC, MMAP_CHECK); + security_task_getsecid(current, &blob); + /* scaffolding - until process_measurement changes */ + return process_measurement(file, current_cred(), blob.secid[0], + NULL, 0, MAY_EXEC, MMAP_CHECK); } return 0; @@ -419,9 +420,9 @@ int ima_file_mprotect(struct vm_area_struct *vma, unsigned long prot) char *pathbuf = NULL; const char *pathname = NULL; struct inode *inode; + struct lsmblob blob; int result = 0; int action; - u32 secid; int pcr; /* Is mprotect making an mmap'ed file executable? */ @@ -429,9 +430,10 @@ int ima_file_mprotect(struct vm_area_struct *vma, unsigned long prot) !(prot & PROT_EXEC) || (vma->vm_flags & VM_EXEC)) return 0; - security_task_getsecid(current, &secid); + security_task_getsecid(current, &blob); inode = file_inode(vma->vm_file); - action = ima_get_action(inode, current_cred(), secid, MAY_EXEC, + /* scaffolding */ + action = ima_get_action(NULL, current_cred(), blob.secid[0], 0, MMAP_CHECK, &pcr, &template, 0); /* Is the mmap'ed file in policy? */ @@ -468,10 +470,12 @@ int ima_bprm_check(struct linux_binprm *bprm) { int ret; u32 secid; + struct lsmblob blob; - security_task_getsecid(current, &secid); - ret = process_measurement(bprm->file, current_cred(), secid, NULL, 0, - MAY_EXEC, BPRM_CHECK); + security_task_getsecid(current, &blob); + /* scaffolding until process_measurement changes */ + ret = process_measurement(bprm->file, current_cred(), blob.secid[0], + NULL, 0, MAY_EXEC, BPRM_CHECK); if (ret) return ret; @@ -492,10 +496,11 @@ int ima_bprm_check(struct linux_binprm *bprm) */ int ima_file_check(struct file *file, int mask) { - u32 secid; + struct lsmblob blob; - security_task_getsecid(current, &secid); - return process_measurement(file, current_cred(), secid, NULL, 0, + security_task_getsecid(current, &blob); + /* scaffolding until process_measurement changes */ + return process_measurement(file, current_cred(), blob.secid[0], NULL, 0, mask & (MAY_READ | MAY_WRITE | MAY_EXEC | MAY_APPEND), FILE_CHECK); } @@ -629,7 +634,7 @@ int ima_read_file(struct file *file, enum kernel_read_file_id read_id, bool contents) { enum ima_hooks func; - u32 secid; + struct lsmblob blob; /* * Do devices using pre-allocated memory run the risk of the @@ -649,8 +654,9 @@ int ima_read_file(struct file *file, enum kernel_read_file_id read_id, /* Read entire file for all partial reads. */ func = read_idmap[read_id] ?: FILE_CHECK; - security_task_getsecid(current, &secid); - return process_measurement(file, current_cred(), secid, NULL, + security_task_getsecid(current, &blob); + /* scaffolding - until process_measurement changes */ + return process_measurement(file, current_cred(), blob.secid[0], NULL, 0, MAY_READ, func); } @@ -679,7 +685,7 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size, enum kernel_read_file_id read_id) { enum ima_hooks func; - u32 secid; + struct lsmblob blob; /* permit signed certs */ if (!file && read_id == READING_X509_CERTIFICATE) @@ -692,9 +698,10 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size, } func = read_idmap[read_id] ?: FILE_CHECK; - security_task_getsecid(current, &secid); - return process_measurement(file, current_cred(), secid, buf, size, - MAY_READ, func); + security_task_getsecid(current, &blob); + /* scaffolding until process_measurement changes */ + return process_measurement(file, current_cred(), blob.secid[0], buf, + size, MAY_READ, func); } /** @@ -809,7 +816,7 @@ void process_buffer_measurement(struct inode *inode, const void *buf, int size, } hash = {}; int violation = 0; int action = 0; - u32 secid; + struct lsmblob blob; if (!ima_policy_flag) return; @@ -822,9 +829,10 @@ void process_buffer_measurement(struct inode *inode, const void *buf, int size, * buffer measurements. */ if (func) { - security_task_getsecid(current, &secid); - action = ima_get_action(inode, current_cred(), secid, 0, func, - &pcr, &template, keyring); + security_task_getsecid(current, &blob); + /* scaffolding */ + action = ima_get_action(inode, current_cred(), blob.secid[0], + 0, func, &pcr, &template, keyring); if (!(action & IMA_MEASURE)) return; } diff --git a/security/security.c b/security/security.c index 9c1098ecea03..421ff85015da 100644 --- a/security/security.c +++ b/security/security.c @@ -1799,10 +1799,16 @@ int security_task_getsid(struct task_struct *p) return call_int_hook(task_getsid, 0, p); } -void security_task_getsecid(struct task_struct *p, u32 *secid) +void security_task_getsecid(struct task_struct *p, struct lsmblob *blob) { - *secid = 0; - call_void_hook(task_getsecid, p, secid); + struct security_hook_list *hp; + + lsmblob_init(blob, 0); + hlist_for_each_entry(hp, &security_hook_heads.task_getsecid, list) { + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + hp->hook.task_getsecid(p, &blob->secid[hp->lsmid->slot]); + } } EXPORT_SYMBOL(security_task_getsecid); From patchwork Wed Nov 4 23:41:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11882729 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.9 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,UNWANTED_LANGUAGE_BODY,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A9E94C2D0A3 for ; Wed, 4 Nov 2020 23:58:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4C005206C3 for ; Wed, 4 Nov 2020 23:58:49 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="TacPj9Ap" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1733250AbgKDX6s (ORCPT ); Wed, 4 Nov 2020 18:58:48 -0500 Received: from sonic305-28.consmr.mail.ne1.yahoo.com ([66.163.185.154]:34071 "EHLO sonic305-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732557AbgKDX5E (ORCPT ); Wed, 4 Nov 2020 18:57:04 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604534221; bh=NjD1+KtwElZe56/UGI6PApTnqSE+EEj9ZLVXzNuLfBA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=TacPj9ApVH+EUYrhvYkRyDwcUoWB4r/z2ezYwS6ns2zJCM31poZV0t16JAdi7acv5+NjGXcrpeA9zsRxq3TpupV4ttsa70JjKi5GoMCEJr1j7nxfdhCHEK5CDfUSf+A9mQTyTiI4uDivH/1FjB9ytosqLd87gDAvD8+vlPTO+jdZY1PC4PreHY/91Bq6KK+buM3q9BOWxFqj/19Mqy4a1eVKvIupMr1HRO9BKvF3tEwN8nWw2vGNqdm02GGAtOVlIBIBlJEd20c/B5jKNxHd6wW0OQOEXKECLFYwzF2EFcRiBD12aXVYUfnbVhGvWYIiLoNNkAiy2fpPtoMWtS/LmA== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604534221; bh=MdJFTVIwice8z6Qr31BjcYfd6OGiITBBohbEvul5xSK=; h=From:To:Subject:Date; b=VVYOH1ZuV8Gp39UyFQ6qxlimGlRLRprmQqFmICJm6iNTkQDDHmFP7o3D3ZeGi/TlQYYIDd+TpPEBkKL5bbfswmWQ8+LvDKd+TFjD83+Ldm/39oUJ7ybf1mAxayLPnWm7u13mcyL10cYJhZfyjUFG9mG/XxfUkboYBypUVxqiFdlOnSp+OMX3ybK584VqRgT5+j8L8YvyhEe01IFLVV7WNXC0QF3yuhX+Y7UkwcrxfbeOZIPg+2oZ3e2XNY5rCwA2Ww2+A0pCkhuBLYZkFVrDtJAp85A9nKsJJunROkb+wM9fIORKCpjM7rus2fIZCjnlwPJS/PixIftnlKF2SR0sPw== X-YMail-OSG: agIkQ8MVM1l.5pnlaHlRT3CENiUjgSNFPp7zfOkfh7jR.V.U6WTOMPzOL2kcuNX 6QzRoCOkBw5.jmYRuNqTTzgTMFl8RQ.v2bVN4cvF3ZscpUpxPTQjMgMt7wuw8Mp7LmIGMSCql_af kSvc2Wivk_2KN1sNG15GpHINxpvz3Kl.7DB2GTUkCKdJO7H92mw0wDnh8PgfTeL2aH9NB8JQy7A6 i.E.XrsYDZyrUyOC2JVqAZvOoM6DC7IGvUmGcQrYUHqomOzm3Opy247mEsk3pWRSKNLI_wDgydzC 7fs3UbYlsPXdi3uiVl.6d6_9NRozvMrUs0wIIul.v97a9m1fEaWOr.Ao2iwYuDLVNWdWUVCCY9dH qJ3vNbvttso5yaFnA1dl6xVl1n.TSGbsbXNe0D404uTFksALT3Wwwj2sU9r7teMWJDLKqsHeo7Ww wJFnKiO8bB6SnX7LOZrgacP_paYWpNRikGHz3vKA6NBpc3xwJ_gACd._olB79Z0WFtvihL6jHCAl sM89EStGS0_G4nAMBJWcHHaSt7GrlLuzTImBJ4KuRfHwPbfYDRCOtWA2z6_FEkNf8059MwNMNUGR XwzKCuFDMtBRWYhNSPk7mMraH88fr9mcB3Yt6T9HwpbkL2dMBE6B38NHx.Y.wXQGCkeGSFafdBEW XaRjZtkhpQiVsnTEC.se2A0nrXGUnCauxCOgkVkjrzKfCy95CLtusrK5BSTvvqL0PV9wSNrDPD8p 9vsQAOO3cpwJ3ncAKcF2XTEYcBwW8xx8OWJ5JBO66ZJ7WTqe1FxMAn.NIeBM11wpSYFBurcjR6RK DLUFVNdBD20Ifqmh2wyDGGBzXoB7UerohXg8lveyLkL2EzVwqMgroA12E_7R2vpGsHa7nrGhoo2u bBN0MfJdmhuKnyuf8lWOV2iXufSSDrIXxdasRmR7zF5kiC2LqgwxRrs9YxEDlFVNDtlmN5zlcPxL vvqSAC1uT0yESOF39WALZ2icDu7ASvOY2BphlqqYaujDSFfzO7fUmDWfH.4lF5sIQjbPUIWbfQn0 NOIOdjkKdvzufMV.cXEzx2ECQCOdrREGTiy6DuiwFIDP_DXnM_azSBQjU8EHUSx31Q_CBWe9AF8l 9tDIPlIrX8bnUuFxJvKsntcM7epFWMoSziPyPZjb5Q13wENKldgiTP2Tf_LM5yMb9w5CNH8eITgF qXIFjoSJob17B9jGAL5VJKyXmbf0r7YjQGipbS9qX9HVVpXI_AN8U5yhwzQCCagRv0alpp3wz6OA M22vMa.daiR9K.cKEBz7p6BT4vzZra7MiSKLqqc67xY27irdhWCS5vvXn_jZYyvuzxakF334dX36 MttX8lDMEBsCOXXnOmvM5GahQTQ_ygvnAyR3w8y6JVWNQD2SgXSisOYnLAiEM9QH0FapxSpIxxw9 Ce3tzp_ihzsUyz79T_02l.NlDsDj1besOPF3Tfq3xGHIOH92AUtx5lPUob9hWwZmOXrbX09XJLLq Aw3aFml2PrybJe.vFhrg6Afh7LPi_ybX5I_wqZOncaT7F0.Whsv_nhpzzzVL_eyLgjXqQBaN6Cc_ 5UMduR9bnwEZqisRE7vQdTXOYaTfgzyUJdas.lMd6QrT2LL9FKpbAwXx9QKxKzbpcLW2i4x2N.l1 SnX17VG6bIhdjzsh0W1QAzerx.DRaZkpjTT8ukiC0GYxzjLKOzWOfdvclXcz0g9puzqHtJ.rodmE E8GKh9GkWSL_dsRpvPMoGyp6sqtR_WYqYImTFaCodGrR9cGdKHwbkndXja_Yeue792pr06.9gY2l nHi9jqeh6HigDaLaLoIdEeqjhgeDrWtI7e4Xdsy.ABHz0kTa6vel9kOTmYoQfSMX1SqrPTG30gHN LyhF8HBlbgqJO0pwjSFH_kyvRmxHtLowALkhjunoTZJE1nnTTlCIHfyC8Zm0_zJIUA1PrhDI4Kl9 GJdoy9Vot3QTwprJkwQ28r6JWFB.dLH_t5lVVMChdMR4.FwZglwuaEkZjTS3_Q.y3fIu2YiwZqoZ HJ1_wiHFoAKqukHgVJceA7P7XZixDRyM6Vl5cPdkmw.gHCs70iRYuy6TyIVXxVMwuqVdjHXW_7AJ 8c2paT7AjYxwa6ED..8ovYJO.p4mk7jxlb_VQmwYRwqK5o07f_Cfok9BKAe2yVX8uoY2XBOenRXF 1kBSYdZQn1bIhWzFsb_AfmCBllvU9jos96GF5vXP63Q4qJVVTTDMQ2k06DXqHLJHDPWt6aX3Xa12 x3u.KB3Idv5Jr3ZdfRzFo4iWao2JeoSUDVDp.pDxIVGQbESBcr40Fa20uuffCQ.C8uYCsdhCYOCc 2.3bXTxYsrVYk3qsqPC4CICDYP2A_R2LTQos_9hartcEAo6J6CWfhgCE05U4luG4w5QVbQrD7zfe Bq0V_n1HVkf3vJsFVb5IRFJDKkx7._tXrO5XfMo4VEO5xCLaj5I6l0jgafonHH_Mg2dwGmPvK5om I6xYK.hZ8oPs7nzjePHjZGH9wSEK6ELBXqeB_E98zroysZYA5DLn7ldPa0hO9gc9u3M08ysauuUm gc5dKaAxwkPriU8c9_8H0wJ7NvTju1Xkjd6utJ1AWlobHN8b9Z2ioDUhGQOHv5lmPu2dmXvv0uiv A5usJbFLH84Kgt8or2R7Sag.daz2U1NAZN_0FqbzfgsM0etii7WH2pabodH67CtT0CBOx.0z4BuH X8PjspK_ahjaAeEeV3R9ItcuQR03Ws3..1l3cP7YJJeQBRzq8D_XdKqK2WkenqObPhVfNAz1GGyk LeaKFS60MXC5tQVZkz6cmUNtYbD_HDtZzZR6zokq10cvx5b3WpyRNgVvLYRwXHKQEPO24KOwfQsy 9KYqltzQCN5h7dpXbsK6amfbTR1X4O594.jJYCz6PM3k97D2NC20mPbPcERNpsVpd1dN3PW5ixAG yWvwoX_TofDzcU4Ss26bki2hANGA8iA3fIaE4d9GzlUGJGoU_BQXg8RthLshSASQuZ.Cb1tYKnZr 3_OS2dYeXADbGCsXaKviBxKPGwKmppRYe2Noj6zizn_4ESmnxm5e1S1Wme3OLiVoZeRpSZygJ5JU Cs.lv1TUn0WRh9eUlukui5bD.Ugj4IoW5MtcuA7JKXOUTcNOmHfhqmIttpsdFkaOw54.aa_Rv82g pABt3WTVFL_toqPY2ZxRFTcomQ9ENkRTlDDpczChCe8UI2Tchk7dSfW.VEaN3XsKamRaCP9E5sWK HTfGJYB3slNA0ufc6Ov8z08H9NRroPZsGE5PHNtaMogcPRDplZ0wyhOSStaaLF6NlKd4ub0WQseX CyIXGzLDxD3xmBb9ktnJFbrFX.04I63BQ3_Wnflg7_D6FSk5Rvvu3HZ.01y6wEGkRQ6pPCi4EZlx 8iF4Xf4jiR1Yzqk9VsftyLabO8sco2gOyjyugGOXzwKT2W7BTfv8GoVu0gd1ApC7u2mBTHV27DWL LiwZ3i5PkTpp7.b93r9MKo2hE3Od.PkeFWLzpYtwNYWLUUfhfRg8kVurQ2OFAgRegFw-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic305.consmr.mail.ne1.yahoo.com with HTTP; Wed, 4 Nov 2020 23:57:01 +0000 Received: by smtp404.mail.ne1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID d10307ef7e6d7a3eff163ccc4c899d4e; Wed, 04 Nov 2020 23:56:59 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov, linux-kernel@vger.kernel.org, linux-integrity@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH v22 13/23] LSM: Ensure the correct LSM context releaser Date: Wed, 4 Nov 2020 15:41:04 -0800 Message-Id: <20201104234114.11346-14-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201104234114.11346-1-casey@schaufler-ca.com> References: <20201104234114.11346-1-casey@schaufler-ca.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Add a new lsmcontext data structure to hold all the information about a "security context", including the string, its size and which LSM allocated the string. The allocation information is necessary because LSMs have different policies regarding the lifecycle of these strings. SELinux allocates and destroys them on each use, whereas Smack provides a pointer to an entry in a list that never goes away. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley Signed-off-by: Casey Schaufler Cc: linux-integrity@vger.kernel.org Cc: netdev@vger.kernel.org Cc: linux-audit@redhat.com --- drivers/android/binder.c | 10 ++++--- fs/ceph/xattr.c | 6 ++++- fs/nfs/nfs4proc.c | 8 ++++-- fs/nfsd/nfs4xdr.c | 7 +++-- include/linux/security.h | 35 +++++++++++++++++++++++-- include/net/scm.h | 5 +++- kernel/audit.c | 14 +++++++--- kernel/auditsc.c | 12 ++++++--- net/ipv4/ip_sockglue.c | 4 ++- net/netfilter/nf_conntrack_netlink.c | 4 ++- net/netfilter/nf_conntrack_standalone.c | 4 ++- net/netfilter/nfnetlink_queue.c | 13 ++++++--- net/netlabel/netlabel_unlabeled.c | 19 +++++++++++--- net/netlabel/netlabel_user.c | 4 ++- security/security.c | 11 ++++---- 15 files changed, 121 insertions(+), 35 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 08737a07f997..05266b064c38 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2838,6 +2838,7 @@ static void binder_transaction(struct binder_proc *proc, int t_debug_id = atomic_inc_return(&binder_last_id); char *secctx = NULL; u32 secctx_sz = 0; + struct lsmcontext scaff; /* scaffolding */ e = binder_transaction_log_add(&binder_transaction_log); e->debug_id = t_debug_id; @@ -3140,7 +3141,8 @@ static void binder_transaction(struct binder_proc *proc, t->security_ctx = 0; WARN_ON(1); } - security_release_secctx(secctx, secctx_sz); + lsmcontext_init(&scaff, secctx, secctx_sz, 0); + security_release_secctx(&scaff); secctx = NULL; } t->buffer->debug_id = t->debug_id; @@ -3473,8 +3475,10 @@ static void binder_transaction(struct binder_proc *proc, binder_alloc_free_buf(&target_proc->alloc, t->buffer); err_binder_alloc_buf_failed: err_bad_extra_size: - if (secctx) - security_release_secctx(secctx, secctx_sz); + if (secctx) { + lsmcontext_init(&scaff, secctx, secctx_sz, 0); + security_release_secctx(&scaff); + } err_get_secctx_failed: kfree(tcomplete); binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE); diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index 197cb1234341..5dfd08357dc3 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c @@ -1273,12 +1273,16 @@ int ceph_security_init_secctx(struct dentry *dentry, umode_t mode, void ceph_release_acl_sec_ctx(struct ceph_acl_sec_ctx *as_ctx) { +#ifdef CONFIG_CEPH_FS_SECURITY_LABEL + struct lsmcontext scaff; /* scaffolding */ +#endif #ifdef CONFIG_CEPH_FS_POSIX_ACL posix_acl_release(as_ctx->acl); posix_acl_release(as_ctx->default_acl); #endif #ifdef CONFIG_CEPH_FS_SECURITY_LABEL - security_release_secctx(as_ctx->sec_ctx, as_ctx->sec_ctxlen); + lsmcontext_init(&scaff, as_ctx->sec_ctx, as_ctx->sec_ctxlen, 0); + security_release_secctx(&scaff); #endif if (as_ctx->pagelist) ceph_pagelist_release(as_ctx->pagelist); diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 9e0ca9b2b210..4b03a3e596e9 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -139,8 +139,12 @@ nfs4_label_init_security(struct inode *dir, struct dentry *dentry, static inline void nfs4_label_release_security(struct nfs4_label *label) { - if (label) - security_release_secctx(label->label, label->len); + struct lsmcontext scaff; /* scaffolding */ + + if (label) { + lsmcontext_init(&scaff, label->label, label->len, 0); + security_release_secctx(&scaff); + } } static inline u32 *nfs4_bitmask(struct nfs_server *server, struct nfs4_label *label) { diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 833a2c64dfe8..4ae7e156ea87 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -2717,6 +2717,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, int err; struct nfs4_acl *acl = NULL; #ifdef CONFIG_NFSD_V4_SECURITY_LABEL + struct lsmcontext scaff; /* scaffolding */ void *context = NULL; int contextlen; #endif @@ -3228,8 +3229,10 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, out: #ifdef CONFIG_NFSD_V4_SECURITY_LABEL - if (context) - security_release_secctx(context, contextlen); + if (context) { + lsmcontext_init(&scaff, context, contextlen, 0); /*scaffolding*/ + security_release_secctx(&scaff); + } #endif /* CONFIG_NFSD_V4_SECURITY_LABEL */ kfree(acl); if (tempfh) { diff --git a/include/linux/security.h b/include/linux/security.h index dacd64d2d141..4ed7a0790cc5 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -132,6 +132,37 @@ enum lockdown_reason { extern const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1]; +/* + * A "security context" is the text representation of + * the information used by LSMs. + * This structure contains the string, its length, and which LSM + * it is useful for. + */ +struct lsmcontext { + char *context; /* Provided by the module */ + u32 len; + int slot; /* Identifies the module */ +}; + +/** + * lsmcontext_init - initialize an lsmcontext structure. + * @cp: Pointer to the context to initialize + * @context: Initial context, or NULL + * @size: Size of context, or 0 + * @slot: Which LSM provided the context + * + * Fill in the lsmcontext from the provided information. + * This is a scaffolding function that will be removed when + * lsmcontext integration is complete. + */ +static inline void lsmcontext_init(struct lsmcontext *cp, char *context, + u32 size, int slot) +{ + cp->slot = slot; + cp->context = context; + cp->len = size; +} + /* * Data exported by the security modules * @@ -531,7 +562,7 @@ int security_ismaclabel(const char *name); int security_secid_to_secctx(struct lsmblob *blob, char **secdata, u32 *seclen); int security_secctx_to_secid(const char *secdata, u32 seclen, struct lsmblob *blob); -void security_release_secctx(char *secdata, u32 seclen); +void security_release_secctx(struct lsmcontext *cp); void security_inode_invalidate_secctx(struct inode *inode); int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen); int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen); @@ -1366,7 +1397,7 @@ static inline int security_secctx_to_secid(const char *secdata, return -EOPNOTSUPP; } -static inline void security_release_secctx(char *secdata, u32 seclen) +static inline void security_release_secctx(struct lsmcontext *cp) { } diff --git a/include/net/scm.h b/include/net/scm.h index 23a35ff1b3f2..f273c4d777ec 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -92,6 +92,7 @@ static __inline__ int scm_send(struct socket *sock, struct msghdr *msg, #ifdef CONFIG_SECURITY_NETWORK static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm) { + struct lsmcontext context; struct lsmblob lb; char *secdata; u32 seclen; @@ -106,7 +107,9 @@ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct sc if (!err) { put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, secdata); - security_release_secctx(secdata, seclen); + /*scaffolding*/ + lsmcontext_init(&context, secdata, seclen, 0); + security_release_secctx(&context); } } } diff --git a/kernel/audit.c b/kernel/audit.c index 1f987ac23e90..8867df3de920 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1192,6 +1192,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) struct audit_sig_info *sig_data; char *ctx = NULL; u32 len; + struct lsmcontext scaff; /* scaffolding */ err = audit_netlink_ok(skb, msg_type); if (err) @@ -1449,15 +1450,18 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) } sig_data = kmalloc(sizeof(*sig_data) + len, GFP_KERNEL); if (!sig_data) { - if (lsmblob_is_set(&audit_sig_lsm)) - security_release_secctx(ctx, len); + if (lsmblob_is_set(&audit_sig_lsm)) { + lsmcontext_init(&scaff, ctx, len, 0); + security_release_secctx(&scaff); + } return -ENOMEM; } sig_data->uid = from_kuid(&init_user_ns, audit_sig_uid); sig_data->pid = audit_sig_pid; if (lsmblob_is_set(&audit_sig_lsm)) { memcpy(sig_data->ctx, ctx, len); - security_release_secctx(ctx, len); + lsmcontext_init(&scaff, ctx, len, 0); + security_release_secctx(&scaff); } audit_send_reply(skb, seq, AUDIT_SIGNAL_INFO, 0, 0, sig_data, sizeof(*sig_data) + len); @@ -2129,6 +2133,7 @@ int audit_log_task_context(struct audit_buffer *ab) unsigned len; int error; struct lsmblob blob; + struct lsmcontext scaff; /* scaffolding */ security_task_getsecid(current, &blob); if (!lsmblob_is_set(&blob)) @@ -2142,7 +2147,8 @@ int audit_log_task_context(struct audit_buffer *ab) } audit_log_format(ab, " subj=%s", ctx); - security_release_secctx(ctx, len); + lsmcontext_init(&scaff, ctx, len, 0); + security_release_secctx(&scaff); return 0; error_path: diff --git a/kernel/auditsc.c b/kernel/auditsc.c index b15222181700..2b06171bedeb 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -998,6 +998,7 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, struct lsmblob *blob, char *comm) { struct audit_buffer *ab; + struct lsmcontext lsmcxt; char *ctx = NULL; u32 len; int rc = 0; @@ -1015,7 +1016,8 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, rc = 1; } else { audit_log_format(ab, " obj=%s", ctx); - security_release_secctx(ctx, len); + lsmcontext_init(&lsmcxt, ctx, len, 0); /*scaffolding*/ + security_release_secctx(&lsmcxt); } } audit_log_format(ab, " ocomm="); @@ -1228,6 +1230,7 @@ static void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name) static void show_special(struct audit_context *context, int *call_panic) { + struct lsmcontext lsmcxt; struct audit_buffer *ab; int i; @@ -1261,7 +1264,8 @@ static void show_special(struct audit_context *context, int *call_panic) *call_panic = 1; } else { audit_log_format(ab, " obj=%s", ctx); - security_release_secctx(ctx, len); + lsmcontext_init(&lsmcxt, ctx, len, 0); + security_release_secctx(&lsmcxt); } } if (context->ipc.has_perm) { @@ -1407,6 +1411,7 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n, char *ctx = NULL; u32 len; struct lsmblob blob; + struct lsmcontext lsmcxt; lsmblob_init(&blob, n->osid); if (security_secid_to_secctx(&blob, &ctx, &len)) { @@ -1415,7 +1420,8 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n, *call_panic = 2; } else { audit_log_format(ab, " obj=%s", ctx); - security_release_secctx(ctx, len); + lsmcontext_init(&lsmcxt, ctx, len, 0); /* scaffolding */ + security_release_secctx(&lsmcxt); } } diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 2f089733ada7..a7e4c1b34b6c 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -130,6 +130,7 @@ static void ip_cmsg_recv_checksum(struct msghdr *msg, struct sk_buff *skb, static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) { + struct lsmcontext context; struct lsmblob lb; char *secdata; u32 seclen, secid; @@ -145,7 +146,8 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) return; put_cmsg(msg, SOL_IP, SCM_SECURITY, seclen, secdata); - security_release_secctx(secdata, seclen); + lsmcontext_init(&context, secdata, seclen, 0); /* scaffolding */ + security_release_secctx(&context); } static void ip_cmsg_recv_dstaddr(struct msghdr *msg, struct sk_buff *skb) diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 8627ec7e13fb..5d2784461798 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -334,6 +334,7 @@ static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct) int len, ret; char *secctx; struct lsmblob blob; + struct lsmcontext context; /* lsmblob_init() puts ct->secmark into all of the secids in blob. * security_secid_to_secctx() will know which security module @@ -354,7 +355,8 @@ static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct) ret = 0; nla_put_failure: - security_release_secctx(secctx, len); + lsmcontext_init(&context, secctx, len, 0); /* scaffolding */ + security_release_secctx(&context); return ret; } #else diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index 54da1a3e8cb1..e2bdc851a477 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -176,6 +176,7 @@ static void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) u32 len; char *secctx; struct lsmblob blob; + struct lsmcontext context; lsmblob_init(&blob, ct->secmark); ret = security_secid_to_secctx(&blob, &secctx, &len); @@ -184,7 +185,8 @@ static void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) seq_printf(s, "secctx=%s ", secctx); - security_release_secctx(secctx, len); + lsmcontext_init(&context, secctx, len, 0); /* scaffolding */ + security_release_secctx(&context); } #else static inline void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index a6dbef71fc32..dcc31cb7f287 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -398,6 +398,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, enum ip_conntrack_info ctinfo; struct nfnl_ct_hook *nfnl_ct; bool csum_verify; + struct lsmcontext scaff; /* scaffolding */ char *secdata = NULL; u32 seclen = 0; @@ -628,8 +629,10 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, } nlh->nlmsg_len = skb->len; - if (seclen) - security_release_secctx(secdata, seclen); + if (seclen) { + lsmcontext_init(&scaff, secdata, seclen, 0); + security_release_secctx(&scaff); + } return skb; nla_put_failure: @@ -637,8 +640,10 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, kfree_skb(skb); net_err_ratelimited("nf_queue: error creating packet message\n"); nlmsg_failure: - if (seclen) - security_release_secctx(secdata, seclen); + if (seclen) { + lsmcontext_init(&scaff, secdata, seclen, 0); + security_release_secctx(&scaff); + } return NULL; } diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 94071f67e461..3e06efe29cfa 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -374,6 +374,7 @@ int netlbl_unlhsh_add(struct net *net, struct net_device *dev; struct netlbl_unlhsh_iface *iface; struct audit_buffer *audit_buf = NULL; + struct lsmcontext context; char *secctx = NULL; u32 secctx_len; struct lsmblob blob; @@ -447,7 +448,9 @@ int netlbl_unlhsh_add(struct net *net, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " sec_obj=%s", secctx); - security_release_secctx(secctx, secctx_len); + /* scaffolding */ + lsmcontext_init(&context, secctx, secctx_len, 0); + security_release_secctx(&context); } audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0); audit_log_end(audit_buf); @@ -478,6 +481,7 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, struct netlbl_unlhsh_addr4 *entry; struct audit_buffer *audit_buf; struct net_device *dev; + struct lsmcontext context; char *secctx; u32 secctx_len; struct lsmblob blob; @@ -509,7 +513,9 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " sec_obj=%s", secctx); - security_release_secctx(secctx, secctx_len); + /* scaffolding */ + lsmcontext_init(&context, secctx, secctx_len, 0); + security_release_secctx(&context); } audit_log_format(audit_buf, " res=%u", entry != NULL ? 1 : 0); audit_log_end(audit_buf); @@ -546,6 +552,7 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, struct netlbl_unlhsh_addr6 *entry; struct audit_buffer *audit_buf; struct net_device *dev; + struct lsmcontext context; char *secctx; u32 secctx_len; struct lsmblob blob; @@ -576,7 +583,8 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " sec_obj=%s", secctx); - security_release_secctx(secctx, secctx_len); + lsmcontext_init(&context, secctx, secctx_len, 0); + security_release_secctx(&context); } audit_log_format(audit_buf, " res=%u", entry != NULL ? 1 : 0); audit_log_end(audit_buf); @@ -1095,6 +1103,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, int ret_val = -ENOMEM; struct netlbl_unlhsh_walk_arg *cb_arg = arg; struct net_device *dev; + struct lsmcontext context; void *data; u32 secid; char *secctx; @@ -1165,7 +1174,9 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, NLBL_UNLABEL_A_SECCTX, secctx_len, secctx); - security_release_secctx(secctx, secctx_len); + /* scaffolding */ + lsmcontext_init(&context, secctx, secctx_len, 0); + security_release_secctx(&context); if (ret_val != 0) goto list_cb_failure; diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c index 893301ae0131..ef139d8ae7cd 100644 --- a/net/netlabel/netlabel_user.c +++ b/net/netlabel/netlabel_user.c @@ -84,6 +84,7 @@ struct audit_buffer *netlbl_audit_start_common(int type, struct netlbl_audit *audit_info) { struct audit_buffer *audit_buf; + struct lsmcontext context; char *secctx; u32 secctx_len; struct lsmblob blob; @@ -103,7 +104,8 @@ struct audit_buffer *netlbl_audit_start_common(int type, if (audit_info->secid != 0 && security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " subj=%s", secctx); - security_release_secctx(secctx, secctx_len); + lsmcontext_init(&context, secctx, secctx_len, 0);/*scaffolding*/ + security_release_secctx(&context); } return audit_buf; diff --git a/security/security.c b/security/security.c index f9d9f68d40cf..9107ca5a6af3 100644 --- a/security/security.c +++ b/security/security.c @@ -2245,16 +2245,17 @@ int security_secctx_to_secid(const char *secdata, u32 seclen, } EXPORT_SYMBOL(security_secctx_to_secid); -void security_release_secctx(char *secdata, u32 seclen) +void security_release_secctx(struct lsmcontext *cp) { struct security_hook_list *hp; - int display = lsm_task_display(current); hlist_for_each_entry(hp, &security_hook_heads.release_secctx, list) - if (display == LSMBLOB_INVALID || display == hp->lsmid->slot) { - hp->hook.release_secctx(secdata, seclen); - return; + if (cp->slot == hp->lsmid->slot) { + hp->hook.release_secctx(cp->context, cp->len); + break; } + + memset(cp, 0, sizeof(*cp)); } EXPORT_SYMBOL(security_release_secctx); From patchwork Wed Nov 4 23:41:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11882727 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.9 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,UNWANTED_LANGUAGE_BODY,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 99192C388F7 for ; Wed, 4 Nov 2020 23:58:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 24C87206C3 for ; Wed, 4 Nov 2020 23:58:41 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="aZ4zBTGZ" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387704AbgKDX6e (ORCPT ); Wed, 4 Nov 2020 18:58:34 -0500 Received: from sonic301-38.consmr.mail.ne1.yahoo.com ([66.163.184.207]:41824 "EHLO sonic301-38.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387684AbgKDX6N (ORCPT ); Wed, 4 Nov 2020 18:58:13 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604534290; bh=RhDyTRIUUvKNSYKelEuTITA9CN5VF/9jr5GLz/2ip2o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=aZ4zBTGZgg1m3MMEBn6o0upk7HTkMhInWaMHPB+kHOjIgv+XIZnzTUhTY0+7UIfEUVq09wZCD/bmNK0epbiPsyXzruUVvkSbhfOrrpiyVqW9dX2WSCJQtt2Vn/KQd5ZW3c1TJ183OuECbqEWfpcHs1TjnJCexWcVjxWaVyFqeIYq7in8jPjVzY9prmPPVLrL6GGPyE2JM8PZoT/SNG30EkzMyWJEK99Li0VtQ15q1s1zmbMxA8eyMXLHzvSS9ihLjsqvU12YCiLWVBtMHwnC5l41R8XH9+iAU7TIzKZpmWGXfoHqpZ6O24wgW3Ata5paXH228ECk2Qa/3ChmmAYxXw== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604534290; bh=lQGd0BcZGYtqgVxtWlSl6QnZLTOX4pQdSmJHCOFdylJ=; h=From:To:Subject:Date; b=MjIkUvkisdvf6IRzIOTFAmza/+jvwGUe1OkEYF2bjw66S5FHSnN/W6ouwhZt0w95x1iYiH3d+izAv4bLPovjmDPqaGqGDduEgff0ox8497jAFhrS7rtHhUc/AYMSgRRN+gTPCOr6ITnPBYrPbIhAw1xDV+H/4bHIg4rBFAKya9VyLCrTGtNoy9gBVIhIDvGzH+UBveUS6pYSbqoKMGRRvxdRLUk9Hr9iz1kMjS8EJcaF2nJxgX9PK+QiGOlgJVdzsOhk4l/pOASGgHBS2WJN4pGc0nT0VVpurpjKgxx/zKGISJKDFSkcmho2l8pV8Jh5id8hv/Tij8ub3aXqAuzEpA== X-YMail-OSG: cCaCev4VM1kK3p1bU1FRbahaBTqsJF3jB62BO6Pqq8rltXYqiG4LKxSiSCXcF45 6iyEol7HM5meV3ZzApteiC3IxnKClQcUQ0muEIN54Qlrg0Ce0Pcdj08l.boonZUy6SA9onOcDOFI MnOXcMvyW9rm6v0BUnPJ1PF95Tha7y1.di0rXwyAnv_MWjRAdwNzHRnzALlzzBLIm482bHu7QXEQ BVbY3DmvqAgMuYHxJpPhZyAM81fag_d1_eiq3Kam9lhJjKbquGTEwi1hc4.3PxxoH1CPzrSXJv94 2PUv2uMg_7w2QEbxeb58Iig5NQw3SFaAa.nJmYu_efqAWYkYZ5YNokHoMZQhhXqHGCsJAtHoNnHx U1rprwjGUgMYtpOPuZrSPKqfHKomXYHQIV29sRBgzRzQR32gF7oFEfxJL_6TVQsCQB8Glwcz9nMI ZO5hL9cFNwxVez4B7aKtNtIJEfEPrgBfEGL.QXUyxmCZd3BIRFtYgJHVLnAmGYLGNyfm8qrlx0Ve mz0_gcxIKpB_ht4enYj.TEjUyp507HPw4SSAgY7YXgGobedT2oa5MeUWKscOM3QtPIM6zEwAUhN4 oTczL1akAC5l1bBXMKyoYhT3m.1gw3jKtmshGVE.vv7FgLFo2Tap2cmvAXCFYSS6L_TXJgaOCTXV sw__LppMFKd1vcwrtw5QrwxcJUBdoShvCZWf7QkxKvFxwXx5SyzRqDSvZFDGEspTDiNk0sVbb6GX 9Kz_B7Svku7_ks7WdNhJcpRsyw.4QGgmEbbazKULoOadV5qMxOBET37uiIgJgnY7Sf1zbdVPxrwy hot3LvvoW2gXWKNtrOZaTuDLLzSzRFZtY0F4jh_tA6S1Bbb041I6cAUO0FR0Vl.21iMxDPTTBznk VaWNkRON.stc5cBkqEnzThDT4eijz__W6eyMnrlXghYScY6.h.tBLH10xrSLo45eWj3x4KAwYE6w NDUSh2sWpARo0Sx8xSf.ajz3ikxQhuy4GpezP1X_MpSuDcmSY2_3lg_aHnI_fP8o0UiVjHPhfBNL VHMNfZFlo9.zn2tAXjicionIRxtNh_NmpnA_F74pETmVIjUSqi5YHvsbSpXVVYPOtC7c7x7SIPjM Ofn0Zytg3NPx9T5.FigvCxQPfpRfYCR0KJ7aZWKgtE3I3AuWMIg0AO2y7xRbEvxr4vNYHRLoUjBj .ILsG7Dn2dB3uxYGoWsP35N9VBfxulTAnJ9fzzO5lQvB5NEZ5iCeIeGhCvS2d6iDx.vbn.xplZD1 I.JfKECYEHDLGtMAg1PwJ479drG2mg3pdJDN357ZhetmQdi2PMKyrPmY07qPEBrQeECLCQ_NwJ8I dtp304mlOKjER9EABPJdTBrMeoCytoRdUKhxtKdSS7X8eH75Jtd5rIUxBVnyzn7rigtXp5xVj3Sb t.XMIiLO27mPZCPJx8wTc_kdfH35NzynMXrH8NtKNPKo5p_uayTBglWEgYRHsw4C3DnjoJdUa0E_ YErK5lRzf5fN.d6XmJHqbAf2e1VxwXSw9KIBOzKjPawTM3eKqCOOX6fYgb3Q_DwNIbcM9pSjgbJh kIAp_IiWxuuZbslN_JcGkCXFQLIirg7psbghvJ1wpaGB4VQFs9jD4VxbUPquTldrUPBtZM3HyNVR nZbIzlg0AvcvFYxUZgD281hY_1SLJqbK46XoHief5w1v0rjFAgIyABmEZLv0.NfPsmBt.Zoe0Byt axB4Q.bPssl8aIRvqjHOowBz1W0sR6XdcjChON1NtNBA.pj6SczKT56w5ZKLKhlAAiCjPENwDJIn agLDHHR.Exm4kdQha2TDl4oJpGkRo7aK.NhsjvqksOVpuUYImDfDqvbfOTnabZB5G1kEoamDPnXs bqU4caLbWyBkeOSqWv6S0gUv4qIX70xpOabM46SFjHwZPXAtj5iBpbUyqGdw.itzIrSL3aq2w3Hk j_0czHsxqhYKjVJfCvgOp5lJcbWSbFWNKZAbDb7g4v0Ntsep5tSX9Yl9cQ32_lv8B73Zdo_K78IC JRwV5xhAZzYjI1cjXI1z3YxVsx2Ny58ckAtXlSS9fZzZZo4n71GuCsKburapExAYE1V6FlSl8Wfk viid8oXx13SIQGWAsUym7q4w8BoszKnarloctl2hI7ujf7W4lLNs.scF_9dLGOoDT8Cz1KbmrSEh Cc0gUj4dNV6ED4Xm2YyaCbGxKz6YXuStn3nFy_QYD7iP3IX.IpTp1nq1.J3eNgZxFjQj4WHk4Aoq pk1WBmSNRHnDx0BelrAns_H9BDt7TUYYyt2p9yeiJ0G_.OGu07t5mk0pMXLHvIVhh7dQIkxnlRlV aTrdqZQz5K_4h.A01ydBbH078c4ZEnuqznDp_HIRYkFu74MKyYapUazt5oHK8f4RDJ0UmpAbrPpR 8NhPV.sQpMlqIvKMl2r7jxgK9nMSHoltbUcdMceQZZubFZAGulIUvBeyQsdT4Uq_N74aONfizum3 wn13mCFfZ1dPTmc_txCz7.7XMZLK9zqFZ8hnzGNbTalcTewuUsOFZxxqxYje57slegadZe9HVZFe WnSrvrYbZThoJLkbqzfDI0twv.Ks_lGbIi4Ie49HhPydSWE3gn.xY5hxB6qqmzj8wV7cvuhVi6lw QfJ5vntsaDNc2lvzUYBZpg7NOfXiuosnfVdrq3lqmIGCK2G8pGrgZSk5oHbx84SUi_tpArTw15ND G8GEd.fa39EzFZWORM6MnoEFJTyMSwPpcRHbk43PlqwOtXxAthwBaBwuhIxLXDPgGBCreopbxjj6 lSy7_MKEcdtSbebhzdG2FE9_aCla8hJwVJD5eTPmlebHftlsIo4lDwNmkWUSqPK.DKfYyJIV7LP9 wLwM2zEJkvYlVpAA71mTS4PlddRW1ZcV99nRt3EGAHaQXFItg6lZASNaFY9cCqSyOoiS2o9rxZYP BsfPlvDhtzKn9OmK4L_Gg4k8DLefFDav5.8JdpEy_OjLydXo9miOEFFqEH82XWMwuzzzjCSJmCfj 0e5h.fuZXm0U5jMqMNYT6Ms4CtHyj3QPjPi3tLmxwjho5arvSwCFb8.8nKZQeJOQhWlHlWtVfGxZ 3nFZzP340jHNsvJeIPmh_cvK88h29eNTU.QjRTwk1ESjbWqFXF3NKL3LQuFbd1C8eAOFpmTTRqaP FGVuGaf9_6xct6r__LzTJDInvazqyWy0Nw3YDua0V24P_BpqHuuFiDDod9ud7cGsR.2OtimTNWdU 1MLpvJtkRBFfAryhUXYd6mzAVR.7sfDUregHEMuSVc9erNtwghXLBWr8Q77_GJPMR29ckign0zQ4 tuI2dtvDwu2ccCQgs5cnPr6IHBuqmH62Hx.Brrehry59ZvZ7GAFx5bpfR2XSaOylG7A52WilYhky cxrQQ4_qo9Gml9NcNXUrR33l3uWuW94BJ3M4UyywP6fN9DMHRp6ZNNUpJ7ypE Received: from sonic.gate.mail.ne1.yahoo.com by sonic301.consmr.mail.ne1.yahoo.com with HTTP; Wed, 4 Nov 2020 23:58:10 +0000 Received: by smtp421.mail.bf1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 747a85aac485fd10d2f221e176742fa9; Wed, 04 Nov 2020 23:58:06 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov, linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH v22 14/23] LSM: Use lsmcontext in security_secid_to_secctx Date: Wed, 4 Nov 2020 15:41:05 -0800 Message-Id: <20201104234114.11346-15-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201104234114.11346-1-casey@schaufler-ca.com> References: <20201104234114.11346-1-casey@schaufler-ca.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Replace the (secctx,seclen) pointer pair with a single lsmcontext pointer to allow return of the LSM identifier along with the context and context length. This allows security_release_secctx() to know how to release the context. Callers have been modified to use or save the returned data from the new structure. Reviewed-by: Kees Cook Acked-by: Stephen Smalley Acked-by: Paul Moore Signed-off-by: Casey Schaufler Cc: netdev@vger.kernel.org Cc: linux-audit@redhat.com --- drivers/android/binder.c | 26 +++++++--------- include/linux/security.h | 4 +-- include/net/scm.h | 9 ++---- kernel/audit.c | 39 +++++++++++------------- kernel/auditsc.c | 31 +++++++------------ net/ipv4/ip_sockglue.c | 8 ++--- net/netfilter/nf_conntrack_netlink.c | 18 +++++------ net/netfilter/nf_conntrack_standalone.c | 7 ++--- net/netfilter/nfnetlink_queue.c | 5 +++- net/netlabel/netlabel_unlabeled.c | 40 ++++++++----------------- net/netlabel/netlabel_user.c | 7 ++--- security/security.c | 10 +++++-- 12 files changed, 81 insertions(+), 123 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 05266b064c38..a75ffcd0270a 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2836,9 +2836,7 @@ static void binder_transaction(struct binder_proc *proc, binder_size_t last_fixup_min_off = 0; struct binder_context *context = proc->context; int t_debug_id = atomic_inc_return(&binder_last_id); - char *secctx = NULL; - u32 secctx_sz = 0; - struct lsmcontext scaff; /* scaffolding */ + struct lsmcontext lsmctx = { }; e = binder_transaction_log_add(&binder_transaction_log); e->debug_id = t_debug_id; @@ -3092,14 +3090,14 @@ static void binder_transaction(struct binder_proc *proc, size_t added_size; security_task_getsecid(proc->tsk, &blob); - ret = security_secid_to_secctx(&blob, &secctx, &secctx_sz); + ret = security_secid_to_secctx(&blob, &lsmctx); if (ret) { return_error = BR_FAILED_REPLY; return_error_param = ret; return_error_line = __LINE__; goto err_get_secctx_failed; } - added_size = ALIGN(secctx_sz, sizeof(u64)); + added_size = ALIGN(lsmctx.len, sizeof(u64)); extra_buffers_size += added_size; if (extra_buffers_size < added_size) { /* integer overflow of extra_buffers_size */ @@ -3126,24 +3124,22 @@ static void binder_transaction(struct binder_proc *proc, t->buffer = NULL; goto err_binder_alloc_buf_failed; } - if (secctx) { + if (lsmctx.context) { int err; size_t buf_offset = ALIGN(tr->data_size, sizeof(void *)) + ALIGN(tr->offsets_size, sizeof(void *)) + ALIGN(extra_buffers_size, sizeof(void *)) - - ALIGN(secctx_sz, sizeof(u64)); + ALIGN(lsmctx.len, sizeof(u64)); t->security_ctx = (uintptr_t)t->buffer->user_data + buf_offset; err = binder_alloc_copy_to_buffer(&target_proc->alloc, t->buffer, buf_offset, - secctx, secctx_sz); + lsmctx.context, lsmctx.len); if (err) { t->security_ctx = 0; WARN_ON(1); } - lsmcontext_init(&scaff, secctx, secctx_sz, 0); - security_release_secctx(&scaff); - secctx = NULL; + security_release_secctx(&lsmctx); } t->buffer->debug_id = t->debug_id; t->buffer->transaction = t; @@ -3199,7 +3195,7 @@ static void binder_transaction(struct binder_proc *proc, off_end_offset = off_start_offset + tr->offsets_size; sg_buf_offset = ALIGN(off_end_offset, sizeof(void *)); sg_buf_end_offset = sg_buf_offset + extra_buffers_size - - ALIGN(secctx_sz, sizeof(u64)); + ALIGN(lsmctx.len, sizeof(u64)); off_min = 0; for (buffer_offset = off_start_offset; buffer_offset < off_end_offset; buffer_offset += sizeof(binder_size_t)) { @@ -3475,10 +3471,8 @@ static void binder_transaction(struct binder_proc *proc, binder_alloc_free_buf(&target_proc->alloc, t->buffer); err_binder_alloc_buf_failed: err_bad_extra_size: - if (secctx) { - lsmcontext_init(&scaff, secctx, secctx_sz, 0); - security_release_secctx(&scaff); - } + if (lsmctx.context) + security_release_secctx(&lsmctx); err_get_secctx_failed: kfree(tcomplete); binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE); diff --git a/include/linux/security.h b/include/linux/security.h index 4ed7a0790cc5..c86c9870b352 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -559,7 +559,7 @@ int security_setprocattr(const char *lsm, const char *name, void *value, size_t size); int security_netlink_send(struct sock *sk, struct sk_buff *skb); int security_ismaclabel(const char *name); -int security_secid_to_secctx(struct lsmblob *blob, char **secdata, u32 *seclen); +int security_secid_to_secctx(struct lsmblob *blob, struct lsmcontext *cp); int security_secctx_to_secid(const char *secdata, u32 seclen, struct lsmblob *blob); void security_release_secctx(struct lsmcontext *cp); @@ -1385,7 +1385,7 @@ static inline int security_ismaclabel(const char *name) } static inline int security_secid_to_secctx(struct lsmblob *blob, - char **secdata, u32 *seclen) + struct lsmcontext *cp) { return -EOPNOTSUPP; } diff --git a/include/net/scm.h b/include/net/scm.h index f273c4d777ec..b77a52f93389 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -94,8 +94,6 @@ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct sc { struct lsmcontext context; struct lsmblob lb; - char *secdata; - u32 seclen; int err; if (test_bit(SOCK_PASSSEC, &sock->flags)) { @@ -103,12 +101,11 @@ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct sc * and the infrastructure will know which it is. */ lsmblob_init(&lb, scm->secid); - err = security_secid_to_secctx(&lb, &secdata, &seclen); + err = security_secid_to_secctx(&lb, &context); if (!err) { - put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, secdata); - /*scaffolding*/ - lsmcontext_init(&context, secdata, seclen, 0); + put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, context.len, + context.context); security_release_secctx(&context); } } diff --git a/kernel/audit.c b/kernel/audit.c index 8867df3de920..4e219d1c1781 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1190,9 +1190,6 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) struct audit_buffer *ab; u16 msg_type = nlh->nlmsg_type; struct audit_sig_info *sig_data; - char *ctx = NULL; - u32 len; - struct lsmcontext scaff; /* scaffolding */ err = audit_netlink_ok(skb, msg_type); if (err) @@ -1440,33 +1437,34 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) kfree(new); break; } - case AUDIT_SIGNAL_INFO: - len = 0; + case AUDIT_SIGNAL_INFO: { + struct lsmcontext context = { }; + int len = 0; + if (lsmblob_is_set(&audit_sig_lsm)) { - err = security_secid_to_secctx(&audit_sig_lsm, &ctx, - &len); + err = security_secid_to_secctx(&audit_sig_lsm, + &context); if (err) return err; } - sig_data = kmalloc(sizeof(*sig_data) + len, GFP_KERNEL); + sig_data = kmalloc(sizeof(*sig_data) + context.len, GFP_KERNEL); if (!sig_data) { - if (lsmblob_is_set(&audit_sig_lsm)) { - lsmcontext_init(&scaff, ctx, len, 0); - security_release_secctx(&scaff); - } + if (lsmblob_is_set(&audit_sig_lsm)) + security_release_secctx(&context); return -ENOMEM; } sig_data->uid = from_kuid(&init_user_ns, audit_sig_uid); sig_data->pid = audit_sig_pid; if (lsmblob_is_set(&audit_sig_lsm)) { - memcpy(sig_data->ctx, ctx, len); - lsmcontext_init(&scaff, ctx, len, 0); - security_release_secctx(&scaff); + len = context.len; + memcpy(sig_data->ctx, context.context, len); + security_release_secctx(&context); } audit_send_reply(skb, seq, AUDIT_SIGNAL_INFO, 0, 0, sig_data, sizeof(*sig_data) + len); kfree(sig_data); break; + } case AUDIT_TTY_GET: { struct audit_tty_status s; unsigned int t; @@ -2129,26 +2127,23 @@ void audit_log_key(struct audit_buffer *ab, char *key) int audit_log_task_context(struct audit_buffer *ab) { - char *ctx = NULL; - unsigned len; int error; struct lsmblob blob; - struct lsmcontext scaff; /* scaffolding */ + struct lsmcontext context; security_task_getsecid(current, &blob); if (!lsmblob_is_set(&blob)) return 0; - error = security_secid_to_secctx(&blob, &ctx, &len); + error = security_secid_to_secctx(&blob, &context); if (error) { if (error != -EINVAL) goto error_path; return 0; } - audit_log_format(ab, " subj=%s", ctx); - lsmcontext_init(&scaff, ctx, len, 0); - security_release_secctx(&scaff); + audit_log_format(ab, " subj=%s", context.context); + security_release_secctx(&context); return 0; error_path: diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 2b06171bedeb..4af5861bcb9a 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -998,9 +998,7 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, struct lsmblob *blob, char *comm) { struct audit_buffer *ab; - struct lsmcontext lsmcxt; - char *ctx = NULL; - u32 len; + struct lsmcontext lsmctx; int rc = 0; ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID); @@ -1011,13 +1009,12 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, from_kuid(&init_user_ns, auid), from_kuid(&init_user_ns, uid), sessionid); if (lsmblob_is_set(blob)) { - if (security_secid_to_secctx(blob, &ctx, &len)) { + if (security_secid_to_secctx(blob, &lsmctx)) { audit_log_format(ab, " obj=(none)"); rc = 1; } else { - audit_log_format(ab, " obj=%s", ctx); - lsmcontext_init(&lsmcxt, ctx, len, 0); /*scaffolding*/ - security_release_secctx(&lsmcxt); + audit_log_format(ab, " obj=%s", lsmctx.context); + security_release_secctx(&lsmctx); } } audit_log_format(ab, " ocomm="); @@ -1230,7 +1227,6 @@ static void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name) static void show_special(struct audit_context *context, int *call_panic) { - struct lsmcontext lsmcxt; struct audit_buffer *ab; int i; @@ -1254,17 +1250,15 @@ static void show_special(struct audit_context *context, int *call_panic) from_kgid(&init_user_ns, context->ipc.gid), context->ipc.mode); if (osid) { - char *ctx = NULL; - u32 len; + struct lsmcontext lsmcxt; struct lsmblob blob; lsmblob_init(&blob, osid); - if (security_secid_to_secctx(&blob, &ctx, &len)) { + if (security_secid_to_secctx(&blob, &lsmcxt)) { audit_log_format(ab, " osid=%u", osid); *call_panic = 1; } else { - audit_log_format(ab, " obj=%s", ctx); - lsmcontext_init(&lsmcxt, ctx, len, 0); + audit_log_format(ab, " obj=%s", lsmcxt.context); security_release_secctx(&lsmcxt); } } @@ -1408,20 +1402,17 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n, MAJOR(n->rdev), MINOR(n->rdev)); if (n->osid != 0) { - char *ctx = NULL; - u32 len; struct lsmblob blob; - struct lsmcontext lsmcxt; + struct lsmcontext lsmctx; lsmblob_init(&blob, n->osid); - if (security_secid_to_secctx(&blob, &ctx, &len)) { + if (security_secid_to_secctx(&blob, &lsmctx)) { audit_log_format(ab, " osid=%u", n->osid); if (call_panic) *call_panic = 2; } else { - audit_log_format(ab, " obj=%s", ctx); - lsmcontext_init(&lsmcxt, ctx, len, 0); /* scaffolding */ - security_release_secctx(&lsmcxt); + audit_log_format(ab, " obj=%s", lsmctx.context); + security_release_secctx(&lsmctx); } } diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index a7e4c1b34b6c..ae073b642fa7 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -132,8 +132,7 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) { struct lsmcontext context; struct lsmblob lb; - char *secdata; - u32 seclen, secid; + u32 secid; int err; err = security_socket_getpeersec_dgram(NULL, skb, &secid); @@ -141,12 +140,11 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) return; lsmblob_init(&lb, secid); - err = security_secid_to_secctx(&lb, &secdata, &seclen); + err = security_secid_to_secctx(&lb, &context); if (err) return; - put_cmsg(msg, SOL_IP, SCM_SECURITY, seclen, secdata); - lsmcontext_init(&context, secdata, seclen, 0); /* scaffolding */ + put_cmsg(msg, SOL_IP, SCM_SECURITY, context.len, context.context); security_release_secctx(&context); } diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 5d2784461798..e6fdcd87ab3e 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -331,8 +331,7 @@ static int ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct) static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct) { struct nlattr *nest_secctx; - int len, ret; - char *secctx; + int ret; struct lsmblob blob; struct lsmcontext context; @@ -340,7 +339,7 @@ static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct) * security_secid_to_secctx() will know which security module * to use to create the secctx. */ lsmblob_init(&blob, ct->secmark); - ret = security_secid_to_secctx(&blob, &secctx, &len); + ret = security_secid_to_secctx(&blob, &context); if (ret) return 0; @@ -349,13 +348,12 @@ static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct) if (!nest_secctx) goto nla_put_failure; - if (nla_put_string(skb, CTA_SECCTX_NAME, secctx)) + if (nla_put_string(skb, CTA_SECCTX_NAME, context.context)) goto nla_put_failure; nla_nest_end(skb, nest_secctx); ret = 0; nla_put_failure: - lsmcontext_init(&context, secctx, len, 0); /* scaffolding */ security_release_secctx(&context); return ret; } @@ -655,15 +653,15 @@ static inline int ctnetlink_secctx_size(const struct nf_conn *ct) #ifdef CONFIG_NF_CONNTRACK_SECMARK int len, ret; struct lsmblob blob; + struct lsmcontext context; - /* lsmblob_init() puts ct->secmark into all of the secids in blob. - * security_secid_to_secctx() will know which security module - * to use to create the secctx. */ - lsmblob_init(&blob, ct->secmark); - ret = security_secid_to_secctx(&blob, NULL, &len); + ret = security_secid_to_secctx(&blob, &context); if (ret) return 0; + len = context.len; + security_release_secctx(&context); + return nla_total_size(0) /* CTA_SECCTX */ + nla_total_size(sizeof(char) * len); /* CTA_SECCTX_NAME */ #else diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index e2bdc851a477..c6112960fc73 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -173,19 +173,16 @@ static void ct_seq_stop(struct seq_file *s, void *v) static void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) { int ret; - u32 len; - char *secctx; struct lsmblob blob; struct lsmcontext context; lsmblob_init(&blob, ct->secmark); - ret = security_secid_to_secctx(&blob, &secctx, &len); + ret = security_secid_to_secctx(&blob, &context); if (ret) return; - seq_printf(s, "secctx=%s ", secctx); + seq_printf(s, "secctx=%s ", context.context); - lsmcontext_init(&context, secctx, len, 0); /* scaffolding */ security_release_secctx(&context); } #else diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index dcc31cb7f287..84be5a49a157 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -306,6 +306,7 @@ static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata) u32 seclen = 0; #if IS_ENABLED(CONFIG_NETWORK_SECMARK) struct lsmblob blob; + struct lsmcontext context = { }; if (!skb || !sk_fullsock(skb->sk)) return 0; @@ -317,10 +318,12 @@ static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata) * blob. security_secid_to_secctx() will know which security * module to use to create the secctx. */ lsmblob_init(&blob, skb->secmark); - security_secid_to_secctx(&blob, secdata, &seclen); + security_secid_to_secctx(&blob, &context); + *secdata = context.context; } read_unlock_bh(&skb->sk->sk_callback_lock); + seclen = context.len; #endif return seclen; } diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 3e06efe29cfa..7d426ca1aff6 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -375,8 +375,6 @@ int netlbl_unlhsh_add(struct net *net, struct netlbl_unlhsh_iface *iface; struct audit_buffer *audit_buf = NULL; struct lsmcontext context; - char *secctx = NULL; - u32 secctx_len; struct lsmblob blob; if (addr_len != sizeof(struct in_addr) && @@ -444,12 +442,9 @@ int netlbl_unlhsh_add(struct net *net, * security_secid_to_secctx() will know which security module * to use to create the secctx. */ lsmblob_init(&blob, secid); - if (security_secid_to_secctx(&blob, - &secctx, - &secctx_len) == 0) { - audit_log_format(audit_buf, " sec_obj=%s", secctx); - /* scaffolding */ - lsmcontext_init(&context, secctx, secctx_len, 0); + if (security_secid_to_secctx(&blob, &context) == 0) { + audit_log_format(audit_buf, " sec_obj=%s", + context.context); security_release_secctx(&context); } audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0); @@ -482,8 +477,6 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, struct audit_buffer *audit_buf; struct net_device *dev; struct lsmcontext context; - char *secctx; - u32 secctx_len; struct lsmblob blob; spin_lock(&netlbl_unlhsh_lock); @@ -510,11 +503,9 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, if (entry != NULL) lsmblob_init(&blob, entry->secid); if (entry != NULL && - security_secid_to_secctx(&blob, - &secctx, &secctx_len) == 0) { - audit_log_format(audit_buf, " sec_obj=%s", secctx); - /* scaffolding */ - lsmcontext_init(&context, secctx, secctx_len, 0); + security_secid_to_secctx(&blob, &context) == 0) { + audit_log_format(audit_buf, " sec_obj=%s", + context.context); security_release_secctx(&context); } audit_log_format(audit_buf, " res=%u", entry != NULL ? 1 : 0); @@ -553,8 +544,6 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, struct audit_buffer *audit_buf; struct net_device *dev; struct lsmcontext context; - char *secctx; - u32 secctx_len; struct lsmblob blob; spin_lock(&netlbl_unlhsh_lock); @@ -580,10 +569,9 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, if (entry != NULL) lsmblob_init(&blob, entry->secid); if (entry != NULL && - security_secid_to_secctx(&blob, - &secctx, &secctx_len) == 0) { - audit_log_format(audit_buf, " sec_obj=%s", secctx); - lsmcontext_init(&context, secctx, secctx_len, 0); + security_secid_to_secctx(&blob, &context) == 0) { + audit_log_format(audit_buf, " sec_obj=%s", + context.context); security_release_secctx(&context); } audit_log_format(audit_buf, " res=%u", entry != NULL ? 1 : 0); @@ -1106,8 +1094,6 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, struct lsmcontext context; void *data; u32 secid; - char *secctx; - u32 secctx_len; struct lsmblob blob; data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).portid, @@ -1167,15 +1153,13 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, * security_secid_to_secctx() will know which security module * to use to create the secctx. */ lsmblob_init(&blob, secid); - ret_val = security_secid_to_secctx(&blob, &secctx, &secctx_len); + ret_val = security_secid_to_secctx(&blob, &context); if (ret_val != 0) goto list_cb_failure; ret_val = nla_put(cb_arg->skb, NLBL_UNLABEL_A_SECCTX, - secctx_len, - secctx); - /* scaffolding */ - lsmcontext_init(&context, secctx, secctx_len, 0); + context.len, + context.context); security_release_secctx(&context); if (ret_val != 0) goto list_cb_failure; diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c index ef139d8ae7cd..951ba0639d20 100644 --- a/net/netlabel/netlabel_user.c +++ b/net/netlabel/netlabel_user.c @@ -85,8 +85,6 @@ struct audit_buffer *netlbl_audit_start_common(int type, { struct audit_buffer *audit_buf; struct lsmcontext context; - char *secctx; - u32 secctx_len; struct lsmblob blob; if (audit_enabled == AUDIT_OFF) @@ -102,9 +100,8 @@ struct audit_buffer *netlbl_audit_start_common(int type, lsmblob_init(&blob, audit_info->secid); if (audit_info->secid != 0 && - security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { - audit_log_format(audit_buf, " subj=%s", secctx); - lsmcontext_init(&context, secctx, secctx_len, 0);/*scaffolding*/ + security_secid_to_secctx(&blob, &context) == 0) { + audit_log_format(audit_buf, " subj=%s", context.context); security_release_secctx(&context); } diff --git a/security/security.c b/security/security.c index 9107ca5a6af3..007f23797de1 100644 --- a/security/security.c +++ b/security/security.c @@ -2209,18 +2209,22 @@ int security_ismaclabel(const char *name) } EXPORT_SYMBOL(security_ismaclabel); -int security_secid_to_secctx(struct lsmblob *blob, char **secdata, u32 *seclen) +int security_secid_to_secctx(struct lsmblob *blob, struct lsmcontext *cp) { struct security_hook_list *hp; int display = lsm_task_display(current); + memset(cp, 0, sizeof(*cp)); + hlist_for_each_entry(hp, &security_hook_heads.secid_to_secctx, list) { if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) continue; - if (display == LSMBLOB_INVALID || display == hp->lsmid->slot) + if (display == LSMBLOB_INVALID || display == hp->lsmid->slot) { + cp->slot = hp->lsmid->slot; return hp->hook.secid_to_secctx( blob->secid[hp->lsmid->slot], - secdata, seclen); + &cp->context, &cp->len); + } } return LSM_RET_DEFAULT(secid_to_secctx);