From patchwork Thu Nov 5 00:49:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11882801 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 75B78C388F7 for ; Thu, 5 Nov 2020 00:52:04 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2369E22203 for ; Thu, 5 Nov 2020 00:52:04 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="mFBxHsmk" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387863AbgKEAwB (ORCPT ); Wed, 4 Nov 2020 19:52:01 -0500 Received: from sonic305-28.consmr.mail.ne1.yahoo.com ([66.163.185.154]:40523 "EHLO sonic305-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387843AbgKEAwA (ORCPT ); Wed, 4 Nov 2020 19:52:00 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604537517; bh=Qo1Gfl7M/gEtL7nMaHAd4NMxP4V8Uuw/OZ3CtHIgtCI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=mFBxHsmk1vID+ioQGDfHX7lFwHvngyQtQluXaZhLpqxmsCQWAstLQJckJpRn6pi/6tbS033cn/mEUAKVTLyOvT3eQ7KdfT9s1tilDhxPeFHqMJ6trOmft4ClzodvB1fzO11bxPTB9rdok465E39ReMXiq1faPGx/rtBsO4O95vY3/i4RsdcoFF3oCkGEY9atSVswMDWzpHdqj1w+qyxpgGwSbF8MvqDHzyXdes8p1ZuRfbQzYxagEeHhZf0WRcd5klWM/dFk/rl3coSf+G9SMeqn9I/aR95EcIHt7SExvXuWu04NDGX5jaa1jzdx80mCDr9ilEUb7j2BGAKtFcanmg== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604537517; bh=Rf7+smlUAsKrGIJGmQuBaowT6zrVYB9pKp+tXGvMAsa=; h=From:To:Subject:Date; b=t2+wgxY5ffzQMA7Jw/vLk5kWRxsvErTOAxCM9HOG/uW5bPC0BTPhGqkOTfirGBPhhxdjmHMiL0zIn5Zx2rQGsLs1xWV/fZCuidwJzNoA2OZGpHstTfBXzztElwQsUAXncu0Y8P4QIazZOQjVZfuQ+zylFuuCGxlrIZnheN0T3raVQgwTg/ckuwA5XMCOSxUythDAHuVkqKjI+Z8xd1ehCK5lLtESZ33BVzVB+xl8DXjsjGQqzYjwUP80AHD5OaO1KuVl4GJgtgA/gdcMxFSG6Ub529FoSgMgWcvfqKYfPBPrAMfh0w5T9uKd8W5M55cUUCZTxh1VyF85rYbjiWjEMw== X-YMail-OSG: qo4IqgUVM1mJ0KqLrA7Qo52.g0PtsNsK6W5VNZkqj.1g0WfoQNo.cia1ip.X3ie 3utIzmsdOyWLICw5vtV3mlnuSZXXol8qqHG3208qzXp86TL3.OpmJA4jy3QYe2z2LtOnSR7sO5ui QaJhPhTho8uGwT8IoyZEkiiuHxtvwHXztnuvassa1Wkbealm4IZnv92PDtFx65i.pvTUbZpAA0aS hxywYyPYgHAnoOs7rMMyqpDwky0a0hvcpRWbKh1s4w8dHdNuWKCWb9wTZ2OvdVkKyUGN3NNI2Mqr gOGzpYFrvmCDzS.aEkYrnfM.L6VwQ06257ckAsqRlpNXbmerE51BpEtaTNm22OJ5sxhLyZpwh0ti SgTGoYwEAOcBJmQB2NkGxxp73t1B5MGRKT7yc9nKi1zzUVBPrSLUD5svJLcPoA64_F5akzeXxTVf 0n0NthCw61j3KhgD84yBlOojxs8Vs1s23QDOr_EyfaGEq13IxvIPjV41julwxl30tDmmDuqKPr1H Mt9tOvozF_kbqyJ7rlHBNWZZiawP9FfpgZhX4k4J9XVjhq1eshhzPIBddwBDXKalh46d9jbeZXnt vHPlGL_icM8U52rZxX2W6AB2liop2p7Wcxk4kd_NlokxvqOT4TtR4qDtiDFbuyJbpn3jiKHXoVRd 36CWe8jpyCZlg_qv.1SC2ydu2tesOdWE_Y7TNghFmg8Uq6kCAXD4QFaY4PtOIbNWOzcjI8PaQ09Y 3TiJQDrH9ElsecbgGSLyEv0wFU3fiyM0BMMdmybTzDoCRAydYdwKXD1Ga8hxBoiUX1IZ.JVpxvML pnd4A3Yt7deK_KVZ_vwW9cA26ZR20fpeYsfbXeop42B3jL6NWuumxuXU6nVMNbsNjYZZMJc65xpt bULNkVuh3ALKhOFZroR.98Ozeiw0TTVoalyIuzX5VYfBZWx6kXDyLJDP3fHKT7yxEXXnWTEuU76X ieUAi95M3VZZApFu90ij9r5_WVIRdN01kfqUwjjIJ2SCwZgUsoK6issan1SDNRx2MmzSTSk45u0A sC5_OmCouw2oe6DBKoUTAqEj3yTGzS6pLAPhgC7wPD6rPwqYfTR8Ut6z2DclNNFDbSlPS5FcTFBu nlSdVpPwYUjU3JSo5knRFPiLsXUeZITu87WCi54BTIzUwcg3ORaBaY5NF3xVVgsnwyaplZ8xvIkd jNX.v7vadAPWBtLHuNBNIIswz_WIhzfnA5CI4M16oZfnt4EcB.Lv.Jo4S6tpUfx5dlO6Ptv_ngqD kVnZ8rPj..qzykkSmFc5UQg_LAT5lbv1FDpJKvwjadF88OX03VRpSHge6IsbSLDyClBVSFuRACyT JqmVRy9buT72LBvyWRiV73YmL2a1dLdFqQBq3BfX02a_Y.K_WHLhGAauare_uMVpQkWzDBmfvvpy EdgqQqNSJEfSJ.xXSs4csaafsu6zmEJKu5zS4iUFONOJQS_f.Ck75jHSD8iJ8ODKqYAAQxIGZHVZ yTW0Kf3zLBkG4odBqGZtDFIIljotFuMUoHWoGMBR.dOuBZqdmfCClASLy6gpOuSPNGp8.Ptw5KPP JzTN_w6avl9EDmzsVm19ntsilTh4RGXspSJrRRZ725jLkRbHNo.S_dlcLyWAER_V4K2Dn7INjjsq ToTWql5lXu45BWyhwQRTpVc4nPTEHgdB_4X2TsYznbV4T8.wi1k.OfH0Rtj7UbyUiX0_NL0baWLQ D1tG7g8wNNrxEbrS6TSKg7H0a9ge3MiCCWoYcUyllm.M.3cI1.y1UtjxgTZHPRFUoQXOosCMZdij jXJElUUh1UCJcOuLxfKicbY8i3W91STg5TV9r.biOnQHdwak6QbfzCqnLUliSot17YyZYF0iPM34 AIG32sQGGPbuLozEAMzhJiDAW6Rbh682_lTJOdUYo3R507HdC2pOaHRCJYTC51Qqddc6jt7zZ8gl OMDn_Q.qI0wXEYtYT19J4cxQrKAoqHpmH42Sbdoxzg_iHmaF8MxH5TuSVxDjYUDih9PmwRnJcHS1 qA54MiMwtI.ssnbNSZmQiLVUAII5Qq.5dxJ3nqdYDEvuk4vubbm5Rbzhq0fzq8Yqdkpy.o8DVPuL tfr.pgzX6z2qhLdKs6yZ2.xQZfqOkxH.evXUs.HYsCdJ3jBBl3w8mqj2KJm2wbaoaabwVIvDqFsn P4Bz7sA8mPZR.6t57ZgTtfo2P2hvKHqZQcuRpf_c1wq7lwTYFqLKnDKf3fmUm0C4i3eNeRwO08nj K4QBuneJF8o13.qnY_2IevgY078YOXtpiphMrMNZIzEIoGhRf8VEr3d.ErGhFGHr_EdmS23Yj4S_ 4QJHoqksPWyn2pxuEMmdRZmJYZS9K1biKWP0ICLYTEMvcA91TLOlKJG7.FdW8zqoLCLsXOBbtQmw mEX6oFkVVEoA5iJItbdNbrOXnijfxozbDQMYH8zRz770shF_OAewukg3n185hJAzNs4D4nm1ELEo aeYiPdjCi582beD0dbGu_UDo2_CPLT3.Sb0a4iVh3kERmtH2oUU1cYbrD1reWNf9rEpjUv0ayH90 Y8TJEtF3RtJPkhoBp2YLdKDX61e27L2BVE7m22MAFEbBw2WPfeYjeQC3nD0iJf3GV8Qdw0aaFexD y_9KxCQs.jqTMAcvRDs8vwVQBxaLex3aqXW4y5mzpWbp8wM.kzzzNikb37IZPux3xzyOa19zJreC BE_YcVK.nuIxVXPxyyFpGdMdPkd.uLByxJ_95XzOHKemsTreQkEKSkxK7ChiilCb_iiPUg_.urkG Z5hPsgA_AE.9uEAcSdP1cform8WErBFlZSB2rGT3ZUJGIwGkYflgF3tS1kUke9HZLBU8nXPWCUEE Sz4hM8qYHEHVueVU4q0i4P8GljyBmmHXTV9GCZ9VWXHCxugCxgUhLAcBZ.13IjBemGREq8yw7WXA qo6Zn02.VaxjiuNq1N0y2dWUxsIKk9dUrYBZrjpRbih0jdkKzVpnleZykeVkPCpgkfbINODpWH._ okr_GTOo0PHC1SrHyoNiuksvkzmOcvQJcTAsCXXYfqZ_mR4srIInw_vdazVMGNNekIAlcQdkovYP 7ckFeahSpXfW1bzIp0X9QJxrEVCvUSSqjNHDOIzUZM5eKgoLlceQAOw.WKXPgKuJ.7Oc5ZR537Yr RxQp6WnaoK51Pr..aLqj4XUJQ_Vb2yX9mhy5W_KZMn7ehXZ5hxFYTrnRfvzHMDnQ6tmw9ccDrasZ wR5v8al27zs7Ir_F67o4iZbT0dlJ1p7ywwBcCa6DxYXQgQn4mBOi0Rs7dEFIctAr2ZPEqpVuuKUi kFpBS7P_DpqH_Syfzn17JhU9lJj1QkcCLSAi8sgA4uLCxKZOrALuUNhrg1HbcTaYdJxie9IixmJh UWCEHZDLFmVeJV0W7pRsDE2Y4XnjtW.Z5C_RhkFjYXMigpMkO0LWtjuq3OOskMM7oS.25czlZPc1 Rfl18pZS4 Received: from sonic.gate.mail.ne1.yahoo.com by sonic305.consmr.mail.ne1.yahoo.com with HTTP; Thu, 5 Nov 2020 00:51:57 +0000 Received: by smtp421.mail.ne1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID b3fc0268bd2da9109c33fc0f65d30824; Thu, 05 Nov 2020 00:51:51 +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 16:49:03 -0800 Message-Id: <20201105004924.11651-3-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201105004924.11651-1-casey@schaufler-ca.com> References: <20201105004924.11651-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 Thu Nov 5 00:49:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11882819 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 70422C4741F for ; Thu, 5 Nov 2020 00:55:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 08F1F22203 for ; Thu, 5 Nov 2020 00:55:31 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="gNGISfOi" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387905AbgKEAz3 (ORCPT ); Wed, 4 Nov 2020 19:55:29 -0500 Received: from sonic301-36.consmr.mail.ne1.yahoo.com ([66.163.184.205]:39754 "EHLO sonic301-36.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728717AbgKEAz1 (ORCPT ); Wed, 4 Nov 2020 19:55:27 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604537725; bh=erYMDd+BdGzaMY+IvBFczstUTN3hSKUThjOkBNjJt+c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=gNGISfOiWk2fzdoGhFWVLIhmwT+iNm+tJPML+ZZ54DkpBFYrCgeZjzIZUSwcvpC5iHLIL/faHFc+hZiEcqvHFD8GDHt1OINQD+U+YK8s2N3CnoWtpgkDUEsm58xPiqXK37bbT34UEmttvEUwehxV0Di1sLEIN0ncIb6tGJAs7PklELRQZQ8ft/m1BqqCnr8pkVD3VVqCbmErrA2HZLCtLtovWZkCRvX3Lk4ZtLtlI/aIGqjXgPNzVmGv9dLxQG+MCp6dbgMsc+lQMISfJhBcKS1B2v0lykZNWjABfjooia9H5rIyJj2VFxxFF7tuqzCOk/ZabQv4Z9QJGoPIBmDoew== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604537725; bh=M74AcuWFeus+Mgnv07Qu66TeASjwSlTPMczAoosiv4G=; h=From:To:Subject:Date; b=m0raMlkaGVYTivsXzdvKc62/iNbcieRzhfEXojIjpBL5VwZP1/jK6yB+HLclyIYD51cP9Q4RshH5p5+Be/jEW5xGUHEgs2tGtnmx6foh2ez5pBkEzudXk45uWUPW/Nu+uEr2nImBvHG91lA5qVmHatnQPiyEgtBQrsSoriyfnoP5tvHEq+/PVww6i4QzDZQzvWoPfGPDwZ988Q8M8TQF5Xr/52FdsGS0DvaZ4paO59cIkfcpuJOgYOqb8wQCuHm4OQacw8K9Z7dLoFXlzhWGS3PxWe4o8L1omkjmpizfmmquBw33wR0NvI0WK4uJQWh+A5Fyv+SNTZ1kDzBeKpID1A== X-YMail-OSG: T2clA8kVM1mqdO5v2Lsx86rbSI1KF9KQLIjjjIx95r41OW.GN5J8VMYc1XV536f iIGutFCvqaeyAvMQSC9vMgBi.YcRrxPyb3063I2xwFl7LxhpfXqjUTMSBY6taNXkj9n4o0_hpjyk B.YnF_3HWWg3x3e7Kd6v5dFybkTeE5grz0X_thRDZ86k5skRduOvohIe1D57Vl4rYM8Mb5LcuN1H EzQyv32Bp3mERkSVtTXC1ED2SGMJIZ5ZEsLoAXOL8iH8atMjRFfk9MsI0NfdWvtXZjI6SIEyUxME ph9JpveGeMErjSbF3aA20b8c_DN76UK1tBbuQvLPaOo.4hSdBsxU2HvtJO__oK52vk0LHiSyhSNT IVfY944Jb8run_X7HtXdlBrXsY4ewzWfJq4yMw7kARwc8Xd_G_hSnd_Wn7vneFjKCUVzk.kkOuK_ Pwm1bn_49wUjc8aKMEhxpnCPuCuIaceyOWl.0wEsi9zQI1EiZO8AKMtGibMWLNwakdy6kZyoBalB EFM_PE37ztHXAtq_8PFWVY0CDI2Ju3FZT3hSgJWYqCFCa1L6J4AT_yRMoTNp2j3NMuko80U5dCmv 5Co.sbrqhH5T0gFxWxPCZtsacM5P0Symo4t6qlFoUpCuFpqvKTel49rqFm7SO6xsaxzeGJ0W72J7 GG4GTYblBLBgKVyDJmI27ryml.tCUf4N_fgzEXsG05JRkygD5cPZqnkBFF5wHyY6II65HZIDDpCq IPCZCIVL2TNtYaA46DV344cISeyzValYL9ed2aduy1AKmoe2ZzBtqXOFHOyKdoF33COkVzJ2GWFc XJQeVOH8jY2dZYoLsqXuDdfUWiaAuZikyBnXgZleHMGqDCEjZbofd2iZX_jyStgLfG1PgAZS3oDq iyvUKWVkn89agzZyqKGFKAjoo5AraE9Y_zI2xD9.3C.MZl6XaeDUHI1jH7Ws7rspxPkoLIqq0S0b DNarY0uHXui0ZEAMl2Nn7D.1OZfiW28wMQIZDuLjSYBQRpN2pntkSaXdZvMoNCLYBOyk_gXOGNMb UxTJmYX37Hg012_UrAxuF.AzwDM5PR_7EiJ_n05nkSxgnHd0xTxdRozXUu1881Gz3B86S4ZmT7lw mDFT.MPnZxAoWE.HIBA0wL9DiFZ63BqZUZmn.QCgQQXd__fQOWYdxjUXWlCzVal4pjOuSt5HqTli oKjNYqzS2FILVvieezxq18d9b8ESA8MOIp5zdDZaErxjqwEtqUAMb9o7Pg3GjUW6cL4f5aT_1.ue 3Ylw6HTy_VZMNtOc3aqfHGbymRKPYCj6yGDFn__.yxZmFUxhQzBjOhYLgSpO.8qzc.kHTQCCpne1 GSKD_NLU19wZyGPk2CXWdPXiXD_Ng3sf7is8tQ5Kpe0qh2GpJPXsl4tK6j.LKOwBcI_zbpc2OPzg 8IPSjpnP8Y843E2fX1gbqZvbWfuvmqzA4d7YRQQmozVdBwEavl7iekv9ktSpYB.oyioMEIw_QB2u L424P.myMjD7hQZ9nfpxBNZE5bZInp3BGxMXUK51hCFgKQyqYVSwJbnFTFiMMemIwJ1gHGjA7wEW x0jzjsfI6iab3oZJhJvFm4ne5ncq_H9HqSh_CdMnMsnlZZFM.R6ekgsT43VczqOzK4oP42M4rGUl HGYtVhs1dzpyvZgYEKsBFpbhzkz7wkhYTf7vMSAPv.vA4chZxg9eiKHsx7_fDnSFYu5PfSqBIf8x Fht96WkCZgqOnQmCKdU92o3UB2z9Srnjk.GC7LwscB1zrntB6zt.oIjmituKF5gLaNZaHko4cvTA HncjpeWzXps3FNwTOs3Y8qvk9Ty2kAhJXA1BEsB0NzDXGxiOGJy6ZlYXdFxH91jaW3cQFdVuKfST 3vMBqd9NW..aiBNkh6zBPZ8KNWMjYnwqsS3kTyilluOlC_gOnMFTZ6is5qf9pj9wxECxf1GySxki vDFAFwRDZ25oyczoOM310F1k7cBtuNHHLHHRE7vUW2k4nOUJ9QVtQEMqkYxjSBIy3SwaaydxGvHT lwPXhaOfX4Oxu2uIxxaiMQx47gyOn3Rtj3ny8Hq00SciFWtIY.b3ip5DhhxifAsgXGOb4k138a2K 1J5ahZLbl4gOHU4zejPSelmJ4w0ed9BXEOYBuMEsSea2e8DS6rsw3r8R32mrYRyoXduoFRvrF6ud jwscQPa.w9guRv1XvxUx13Wc4nI43bGY5pC5dbaQQVCTNBoBMEawR4s1NveJjxwy8sokmtfdNu46 wd9hy0c_m_6iJHZ_oj21wwoF8pUNDIiYLOdYF4qilv691Ojto2IsPDhZk5VSLeuz6fQuXgWIMZ2U nhb.N1Pwgs2eZ0KpYEx0Larm9_nCT01WwJV0kAoBaI5ovD6lKSsH.tysYEYESM.nZlKLzafe8UuH IPiQQo9ePSYa4lgKx0_DvpO.HCKUBasAqTVDvDTt.uo2sbQ6yRi3o8TzerkYWn1_Yx8owd_iJ8sJ OSH7MbixPVg7TNQK5Q_nX8bBuWyrQQzC4WhMsVduZzDzE34UUFgpm8NtHvuIMJMs0A.aRg9XjgAl IU3Qkmgtbqp0qt.9V.pDh0kWFikC8m1__z26LFFPKaTr.xvN3AgplHakQ7JkZ5S7HxM_JG0P5xeC fbJOWKPjf.UkOKGHLswBAZFHBBEkDAZtqlzTf6pAp6sUHwdbetcQ2zE6mu.T1osJZF8TEA0Wdyk5 9EEZzmrUeE1LW9WQ3X_Ot3DUc5VgOv7SzMvZZCMgk.07p4ktz8bVgsMhp_JuxcYnjXi2.bKleDXv E.WcTF.JMHXwgwxIezknjEev7mNicauJPyqPH13ZsDgVXLpdJrt7c2WxyBWcIq6t0vKh3cSMcXEC aSkdg4GPsdgfK5hEDgfTr2uonm.z.rYiT2DRd_YngSCyVyG4jSe0H.tgJ9lJldm6mzUY9Z_W1ex0 MYRC_x911tkw22gGPOiDFaxI7WunhQIlmiA_fUWiFlfrvbYgPw7zAd1.ShMrDfEOZQsh5QypMRSe uVLZhOrdKSC0bjw8LfWaQdBPKVosGxL8f9XWfaEIDJw38LQbDHX6J0sdqfDCaaRDtWEwP.k92avW HCXWWXoQ2gCUDA9SKyj6_T5zJM3S4au.jdZnqCO8i4P.oo_h.g9v1qKgO6L0za477l48e1kYEdlo n0Q8nb6VmK3saoPimp5g29riInr0D_QJuiRYcAF5tsMnxpXvXd02B0rOiEg9l_abBCT8TYkA7qh9 nQPPtVCeizRYqSPDLDKQNu1mZ1dAD_5kbKw5DxePXWxvZ4ClETnPpE2CdwwMEpFgqgsrUaOKjz0x yGJUg8By.srI53rncnWQWTZkmoqWfS0stmOLsC6ZVjyTWdE0r2S_mRKE0sRQnmkg28jV1A9Tiitr c2ou_8u5hHD92uwJC773jFA0WiUY.FjNrx1rRpRYdzMB9 Received: from sonic.gate.mail.ne1.yahoo.com by sonic301.consmr.mail.ne1.yahoo.com with HTTP; Thu, 5 Nov 2020 00:55:25 +0000 Received: by smtp415.mail.bf1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 136375bc1c3fcc41c1f752a5ffaccee4; Thu, 05 Nov 2020 00:55: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, netdev@vger.kernel.org Subject: [PATCH v22 05/23] LSM: Use lsmblob in security_secctx_to_secid Date: Wed, 4 Nov 2020 16:49:06 -0800 Message-Id: <20201105004924.11651-6-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201105004924.11651-1-casey@schaufler-ca.com> References: <20201105004924.11651-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 Thu Nov 5 00:49:07 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11882825 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 7EB68C55179 for ; Thu, 5 Nov 2020 00:56:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 161B92067B for ; Thu, 5 Nov 2020 00:56:41 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="cZ5tb5lw" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387933AbgKEA4g (ORCPT ); Wed, 4 Nov 2020 19:56:36 -0500 Received: from sonic305-28.consmr.mail.ne1.yahoo.com ([66.163.185.154]:33440 "EHLO sonic305-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727923AbgKEA4g (ORCPT ); Wed, 4 Nov 2020 19:56:36 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604537794; bh=2NyewPO53/4iI2Tr/R68jXRbY58jiTgqBTe9D9i5YK0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=cZ5tb5lww/TOLmJH8neuejTKvWIXPLLQTKNRjWr8NXg5IuQU4zdLYKZQdJW8LIfHPHB3vfLW9njfdSAjKUS3M9mqsG3VAEDpa/p7h+i7DpY/SChyVlbxvNzxeg9o8At3n5LWqt9+4VZo3bXUvhAX6VXdJzSs9bzg/CFGxI86D0Ht3n0lzq4oDXtRO3etzG8acwGDfxysmLYm6tteLR7CrUBc60lS1SfAcbGjoZX8nrru2mk5j50uWdPnDh299OBoFDWpfCtFxk8Wwn5mwJz2Jnrw/ESxjMBF5VS5L0FCURWEBzvc1Iyt30Z6x6qxsELYFDwyqVT9+3eNq3Isd2muEg== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604537794; bh=rjRA7oKQSTliFAWaie/0qWKj0KcJxpZiaNbTsi3OtW9=; h=From:To:Subject:Date; b=UcA+CQjoCr+GIwccJsTK3M26WliOn8PvzDz784EJZ2G3Vb7TSQKevnOOk4IE7wOKqWIdJbMcO+OcIOqfhtfFLVeH56Ud7uAwYGAeUDEresW2w6ttQW0FMFW+FoH8hiuwWkoqlFmMgv8h21CSBnpI+PkwLTcx/OeE/dczql14k5qQeygeOBtcepTqy3NN8IEGu9SSPoVBJGtUZMPNor8a3z4hvGzXxw0WghbgUzoVw/RL5OzSK7IMfkJ+OK7HobH/BYkjrWFtsMAo/yNZuJz3pEfLnzTVD6e4QbTGmXEYXpCswmri7xbE2uYz+kuOP5ev7bDJaKQp6RzxifIaOlbQDQ== X-YMail-OSG: N5bqMWcVM1me_AEXwRrPbVnsXVnpF4SbkPSfmu9JGQFExNMVbXNumopx8DEaYmj Si7F3ZCTXlWnmrIgNU15ZfcgAYh2OuHX9GU27lP78mrHUXnsT2yBVpS7uPKFv8nhok77KtgPFMYI bM0eyTkv_GCw5JU5dKoE6t1I8ByWth42W4WGXBuJS948aUkZnH9Op5eeW0OSzq4Kl7Qfkqo76ial OIw8K9C2f7DVAhQFeBu28165XHnRdWBWVnNx4zE66J2jRwk3wEuF.D0mwkz.McfbHxN0lcApAO4q 68j1oKsHOCW1asjRo0hV.Ek0K8dHc.XGv2bO_Yxzs7L9HC_rNCrQX8CVyXYGL1FWvox4ClXb8QSo b1GpTmU8DA.qqJAhvp0MUcR9vlWqYwybSKXtNiEY5Vfciaw6rM_dA7p9z90KWYJfTDJPrdftqjTi l0WzQLbYcRTwsX8HUN0PCHOwyop7rGjw7D1TbfUVvTiozUG0Ws37S5vJPWua9uP7p2ZSnxBn58mw uvrdPFGRhjdqFOuFZNGmtWHDU4cWRTqdnstGiM5U3CLPvL1LJW94aL855Fj9koK123xQyr8BV8aA fDXWa2DpZDnCXWtjDWwyuD1nXir5tWzR3rjZ_52Umk.jBkcdqQNuluWsmACqBGkJT9kQ.9Vo1Bok U.S.Rb6r67VMUlRPeEn117UJKpPRbukVTXRqXVdIlc4j0hHkNf8Rf.iSKapMwy3eUc06eolFaoIg cuwXiNpA2li7rJ7VLmag58ErbXORw1Zc4g1O2rGJO6k7UqCsNQYcnIy5ITnSGD9ST_Qf3qIZ8gzz DDnjjQobP5hMy4aJwONvFQ5BZKL300TFfKSEcmAHp2.Ewt.Vz_J_fQXm92f6pyOeiMyb6pkoVdLt H9imvmoDKRZSci4MSAu5UEjTnJUoxZ26SUy2AcZ_9qYCLS94y5.Zv5BHyDsQUB_CFfFH6iVRo72G 1sqQUfQFblM4GlgpvvdbfBiVHEGq4qjolvWjM9Rj0rUQFZwF5_ONAWq_5cRnvDq4q2PQbqQG_Y3i plzq3bTxrSgK1eN1.WUHVqEyPJAYwNxYxMHDXmr5l59OqcAOEKkblq3ysmrpHUaRvP2nbw0sgEmh y70R4ow16W6YN7eWW9ub0ag96iis_AOBjDj79NK25CWk0Tm27lVtF0XWcf4ZyG30jtEQLBFRUwhK 1jmztI.zS6bFX3fbAAU.Q3dlcSYnh_iZhtw4iw2NUt.P2T_DcFH75VqXhRzMd1oAxcEvn6KFnP5z TtICFB1ljcFnayOQ6HrEAmJB_6heWgxEr29O.Eur2bHTt5XHpHI6.OnU0LYYSc_OUHbcH1K1tp.x 4om5MMGrHQiTUsWomR6LG8j8U9v5bptDPOpYkchZ_l5Irp58_7a_Teg_UEJjp8yLyJXwIf2UGSOh lHgp.670SfwMXIKmNKTNtfLQryyHalirbo3184OFwKUPMUggziA91ei7p2_Uzqd88biJpnqqfhP5 aKCRlmyLESuzVpsGoJiHsuRxPc0VyAYwXCLxQCLsqVSs02kovl4nZrA5axlbGDsHMRbSiPaBfsk9 .Kw7Oj_b8VUKpRvd1tRiBmpx5HDPyioEvo_Ka5Fon6kZ8S4bUIa4wnREJ2bZ0HlxH58CyrB12gxq 5olLU.44tXUgDJpkegeq00WhGKpUNmrU0xF8ueu2lGJsT3azbONE5VJ3azjTriPr5KUTKcLti6J5 YVY9jBKzaxJKvFSffG0l7zjh0_.WahjN.8sSjXj37Ae_aS2jeYxyr8X51F8dyTPKD1YdEQaxJRUS KqaLjROlOtO764Xq25CqkAWdmTaMRhi2J5bsWDKiVS6cvs_nMYsFFvpyzNUZzrMuovv1hsm2AwVO 1QMO5MYxI6bSvb9279Hk5VH4BuONxz1UvND9Mdo3LtlZySOa4DYfXglg.epPPF4WoTkwoN.kNkNV ajN8pd1ZIYqJocwDQo4ievbcxhhFa5HYgsvJbNA0kWamyqExsvxLFOVb3emazksGeYgSRc5RF30x q2cp4F9CoFHoxrFHSISQV4hE_DOtBHwohpYM1nuKWoDgiZo7b41elxRz8hNqC4zjXGEDeaIVgzdF hA7bG_s8sFWefLWfLxK3vkmieuXsso8ifprCx2vNAO6sJB2LQL8yxf7NlO3vDwToS7yD00GrX6Mx d2Nn4ynuhLLgEcXsG4CpYvjGZiiZcUUAxkpZ1B_qsjD2XHvsk9bttaETbGl3yBwLSt_KdecfAxx. uzQyv.IQEYGsZa69e9pcW.dVr9XfKmxW7Yy9nWmvvvLfqkdc0wn8RskmbWeVQIszElgkHly0TNnH KyPHzG8wb.ED8rbwnf6Q6AcEyd73XdJH5ZQACL7RNBFazPkGjEJeSKA7IWk2izXGiKPQ_6CKIGUM XoJTtrj8Ji9iLqfQ33fydQqrQ9t7su_AVukiNZyptbw9TRaanYRlJd2zZMgsnpl.FYDsoD3j68tu 1Pa.16IqWE3hrUUNj25CAL6NFe0Lip7QW3asdAy__ITINGJaO6T48u_7.MLAoa0mAo1C_cdmI5Eu 32kZNFehhjCgcXbduYcLwukTByQcHE8W0URFo1G6SGBqwbkXYr8rK0F9vnD26GoddmuciI8F9itl _Zwj8axcknP2IUg5PU744daOHx4gujE_t6B15hDpzPvuCq.pH3FxPxvxI37La9nVxf5A6BC8oamN ZfLFza_YXioqdeytDiZizfMasv.2visYUVbMO9fE3ROVmINq7OxIBXGo2l5JHT_LGq7rQXXQvQ8A 5w3mfZE1Ch_iJQ6rz1SPK4dPoVIgJaYV1BpoUkHT2vOLzqJYA5m79nxu.rkXVa9Xn4dXkZRy.gM1 .g0hLv_qod26HyqFntQc5thmctGpkuk4q0FvmZrtmETR_3uV_oS62U5YKiWNNTdGOMXF8HTuTI5N s__9f78mUsa5NGaWIJJD.Bg878R93H7j.4D0wGzzajYM81FVHYsRfzNcXx9SG6YzhI.7hgqcSWY1 Ksh8UXagCL.3_ZawKvM.YXJpv_T_VtxPgEZT1FjeqDxg6aNubu4vqfM5gRa7gGmHFJuqgJIAyUOW WFpUfTXmc97LmqM.LFTB8ctAPEsbSseI3N6qm8Ysci4R2ujaKFHyD0OdEl.BZMdel7zHlGRf1Dhc UPTwE.5Lw8_wUBMeHOApc7WnqgKkreLlrmklUn_u542AqFH._X4N2p81YV9AR4tdMEwC9z3IgIxW n2W0XpRR38YAcbsFV4pmP8Zi09f7grIduEHo2za2pI8Xr.MZ2UvSG6GoEZET_0E2csdfC0UA288m wXPswW1gP6K7sMioQ8ivrMqtC7wybM63pJ2j0jSBSyqHKIbTaEJTRE67L1mfOKDzQueLjRHK59XY xgrtXP_AHx2vwg1_YoOV9hE_ISQy6tfUhW7Pu6_q4oBpR3ceRug-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic305.consmr.mail.ne1.yahoo.com with HTTP; Thu, 5 Nov 2020 00:56:34 +0000 Received: by smtp417.mail.bf1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID d32dd9481194f8f302170fa4e066c7cd; Thu, 05 Nov 2020 00:56:32 +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 06/23] LSM: Use lsmblob in security_secid_to_secctx Date: Wed, 4 Nov 2020 16:49:07 -0800 Message-Id: <20201105004924.11651-7-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201105004924.11651-1-casey@schaufler-ca.com> References: <20201105004924.11651-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 security_secid_to_secctx() to take a lsmblob as input instead of a u32 secid. It will then call the LSM hooks using the lsmblob element allocated for that module. The callers have been updated as well. This allows for the possibility that more than one module may be called upon to translate a secid to a string, as can occur in the audit code. Signed-off-by: Casey Schaufler Cc: netdev@vger.kernel.org Cc: linux-audit@redhat.com --- drivers/android/binder.c | 12 +++++++++- include/linux/security.h | 5 +++-- include/net/scm.h | 7 +++++- kernel/audit.c | 20 +++++++++++++++-- kernel/auditsc.c | 28 +++++++++++++++++++---- net/ipv4/ip_sockglue.c | 4 +++- net/netfilter/nf_conntrack_netlink.c | 14 ++++++++++-- net/netfilter/nf_conntrack_standalone.c | 4 +++- net/netfilter/nfnetlink_queue.c | 11 +++++++-- net/netlabel/netlabel_unlabeled.c | 30 +++++++++++++++++++++---- net/netlabel/netlabel_user.c | 6 ++--- security/security.c | 11 +++++---- 12 files changed, 123 insertions(+), 29 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index b5117576792b..55f3fa073c7b 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -3088,10 +3088,20 @@ static void binder_transaction(struct binder_proc *proc, if (target_node && target_node->txn_security_ctx) { u32 secid; + struct lsmblob blob; size_t added_size; security_task_getsecid(proc->tsk, &secid); - ret = security_secid_to_secctx(secid, &secctx, &secctx_sz); + /* + * 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); + ret = security_secid_to_secctx(&blob, &secctx, &secctx_sz); if (ret) { return_error = BR_FAILED_REPLY; return_error_param = ret; diff --git a/include/linux/security.h b/include/linux/security.h index 0766725a6b21..fad361bf320e 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -528,7 +528,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(u32 secid, char **secdata, u32 *seclen); +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); @@ -1350,7 +1350,8 @@ static inline int security_ismaclabel(const char *name) return 0; } -static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) +static inline int security_secid_to_secctx(struct lsmblob *blob, + char **secdata, u32 *seclen) { return -EOPNOTSUPP; } diff --git a/include/net/scm.h b/include/net/scm.h index 1ce365f4c256..23a35ff1b3f2 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -92,12 +92,17 @@ 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 lsmblob lb; char *secdata; u32 seclen; int err; if (test_bit(SOCK_PASSSEC, &sock->flags)) { - err = security_secid_to_secctx(scm->secid, &secdata, &seclen); + /* There can only be one security module using the secid, + * and the infrastructure will know which it is. + */ + lsmblob_init(&lb, scm->secid); + err = security_secid_to_secctx(&lb, &secdata, &seclen); if (!err) { put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, secdata); diff --git a/kernel/audit.c b/kernel/audit.c index 68cee3bc8cfe..4cd6339e513d 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1442,7 +1442,16 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) case AUDIT_SIGNAL_INFO: len = 0; if (audit_sig_sid) { - err = security_secid_to_secctx(audit_sig_sid, &ctx, &len); + struct lsmblob blob; + + /* + * lsmblob_init sets all values in the lsmblob + * to audit_sig_sid. This is temporary until + * audit_sig_sid is converted to a lsmblob, which + * happens later in this patch set. + */ + lsmblob_init(&blob, audit_sig_sid); + err = security_secid_to_secctx(&blob, &ctx, &len); if (err) return err; } @@ -2128,12 +2137,19 @@ int audit_log_task_context(struct audit_buffer *ab) unsigned len; int error; u32 sid; + struct lsmblob blob; security_task_getsecid(current, &sid); if (!sid) return 0; - error = security_secid_to_secctx(sid, &ctx, &len); + /* + * 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) goto error_path; diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 7dd6b815a9eb..5f9bdd62f78d 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -673,6 +673,13 @@ static int audit_filter_rules(struct task_struct *tsk, security_task_getsecid(tsk, &sid); 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, @@ -690,6 +697,13 @@ static int audit_filter_rules(struct task_struct *tsk, if (f->lsm_isset) { /* Find files that match */ if (name) { + /* + * lsmblob_init sets all values in the + * lsmblob to sid. This is temporary + * until name->osid is converted to a + * lsmblob, which happens later in + * this patch set. + */ lsmblob_init(&blob, name->osid); result = security_audit_rule_match( &blob, @@ -995,6 +1009,7 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, char *ctx = NULL; u32 len; int rc = 0; + struct lsmblob blob; ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID); if (!ab) @@ -1004,7 +1019,8 @@ 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 (sid) { - if (security_secid_to_secctx(sid, &ctx, &len)) { + lsmblob_init(&blob, sid); + if (security_secid_to_secctx(&blob, &ctx, &len)) { audit_log_format(ab, " obj=(none)"); rc = 1; } else { @@ -1247,7 +1263,10 @@ static void show_special(struct audit_context *context, int *call_panic) if (osid) { char *ctx = NULL; u32 len; - if (security_secid_to_secctx(osid, &ctx, &len)) { + struct lsmblob blob; + + lsmblob_init(&blob, osid); + if (security_secid_to_secctx(&blob, &ctx, &len)) { audit_log_format(ab, " osid=%u", osid); *call_panic = 1; } else { @@ -1397,9 +1416,10 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n, if (n->osid != 0) { char *ctx = NULL; u32 len; + struct lsmblob blob; - if (security_secid_to_secctx( - n->osid, &ctx, &len)) { + lsmblob_init(&blob, n->osid); + if (security_secid_to_secctx(&blob, &ctx, &len)) { audit_log_format(ab, " osid=%u", n->osid); if (call_panic) *call_panic = 2; diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index ec6036713e2c..2f089733ada7 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 lsmblob lb; char *secdata; u32 seclen, secid; int err; @@ -138,7 +139,8 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) if (err) return; - err = security_secid_to_secctx(secid, &secdata, &seclen); + lsmblob_init(&lb, secid); + err = security_secid_to_secctx(&lb, &secdata, &seclen); if (err) return; diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 3d0fd33be018..8627ec7e13fb 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -333,8 +333,13 @@ static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct) struct nlattr *nest_secctx; int len, ret; char *secctx; + struct lsmblob blob; - ret = security_secid_to_secctx(ct->secmark, &secctx, &len); + /* 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, &secctx, &len); if (ret) return 0; @@ -647,8 +652,13 @@ static inline int ctnetlink_secctx_size(const struct nf_conn *ct) { #ifdef CONFIG_NF_CONNTRACK_SECMARK int len, ret; + struct lsmblob blob; - ret = security_secid_to_secctx(ct->secmark, NULL, &len); + /* 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); if (ret) return 0; diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index 46c5557c1fec..54da1a3e8cb1 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -175,8 +175,10 @@ static void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) int ret; u32 len; char *secctx; + struct lsmblob blob; - ret = security_secid_to_secctx(ct->secmark, &secctx, &len); + lsmblob_init(&blob, ct->secmark); + ret = security_secid_to_secctx(&blob, &secctx, &len); if (ret) return; diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index d1d8bca03b4f..a6dbef71fc32 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -305,13 +305,20 @@ static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata) { u32 seclen = 0; #if IS_ENABLED(CONFIG_NETWORK_SECMARK) + struct lsmblob blob; + if (!skb || !sk_fullsock(skb->sk)) return 0; read_lock_bh(&skb->sk->sk_callback_lock); - if (skb->secmark) - security_secid_to_secctx(skb->secmark, secdata, &seclen); + if (skb->secmark) { + /* 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, skb->secmark); + security_secid_to_secctx(&blob, secdata, &seclen); + } read_unlock_bh(&skb->sk->sk_callback_lock); #endif diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 8c064342169f..ba74901b89a8 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -376,6 +376,7 @@ int netlbl_unlhsh_add(struct net *net, struct audit_buffer *audit_buf = NULL; char *secctx = NULL; u32 secctx_len; + struct lsmblob blob; if (addr_len != sizeof(struct in_addr) && addr_len != sizeof(struct in6_addr)) @@ -438,7 +439,11 @@ int netlbl_unlhsh_add(struct net *net, unlhsh_add_return: rcu_read_unlock(); if (audit_buf != NULL) { - if (security_secid_to_secctx(secid, + /* lsmblob_init() puts secid 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, secid); + if (security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " sec_obj=%s", secctx); @@ -475,6 +480,7 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, struct net_device *dev; char *secctx; u32 secctx_len; + struct lsmblob blob; spin_lock(&netlbl_unlhsh_lock); list_entry = netlbl_af4list_remove(addr->s_addr, mask->s_addr, @@ -494,8 +500,13 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, addr->s_addr, mask->s_addr); if (dev != NULL) dev_put(dev); + /* lsmblob_init() puts entry->secid into all of the secids + * in blob. security_secid_to_secctx() will know which + * security module to use to create the secctx. */ + if (entry != NULL) + lsmblob_init(&blob, entry->secid); if (entry != NULL && - security_secid_to_secctx(entry->secid, + security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " sec_obj=%s", secctx); security_release_secctx(secctx, secctx_len); @@ -537,6 +548,7 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, struct net_device *dev; char *secctx; u32 secctx_len; + struct lsmblob blob; spin_lock(&netlbl_unlhsh_lock); list_entry = netlbl_af6list_remove(addr, mask, &iface->addr6_list); @@ -555,8 +567,13 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, addr, mask); if (dev != NULL) dev_put(dev); + /* lsmblob_init() puts entry->secid into all of the secids + * in blob. security_secid_to_secctx() will know which + * security module to use to create the secctx. */ + if (entry != NULL) + lsmblob_init(&blob, entry->secid); if (entry != NULL && - security_secid_to_secctx(entry->secid, + security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " sec_obj=%s", secctx); security_release_secctx(secctx, secctx_len); @@ -1082,6 +1099,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, u32 secid; char *secctx; u32 secctx_len; + struct lsmblob blob; data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).portid, cb_arg->seq, &netlbl_unlabel_gnl_family, @@ -1136,7 +1154,11 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, secid = addr6->secid; } - ret_val = security_secid_to_secctx(secid, &secctx, &secctx_len); + /* lsmblob_init() secid 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, secid); + ret_val = security_secid_to_secctx(&blob, &secctx, &secctx_len); if (ret_val != 0) goto list_cb_failure; ret_val = nla_put(cb_arg->skb, diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c index 3ed4fea2a2de..893301ae0131 100644 --- a/net/netlabel/netlabel_user.c +++ b/net/netlabel/netlabel_user.c @@ -86,6 +86,7 @@ struct audit_buffer *netlbl_audit_start_common(int type, struct audit_buffer *audit_buf; char *secctx; u32 secctx_len; + struct lsmblob blob; if (audit_enabled == AUDIT_OFF) return NULL; @@ -98,10 +99,9 @@ struct audit_buffer *netlbl_audit_start_common(int type, from_kuid(&init_user_ns, audit_info->loginuid), audit_info->sessionid); + lsmblob_init(&blob, audit_info->secid); if (audit_info->secid != 0 && - security_secid_to_secctx(audit_info->secid, - &secctx, - &secctx_len) == 0) { + security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " subj=%s", secctx); security_release_secctx(secctx, secctx_len); } diff --git a/security/security.c b/security/security.c index eac7c10b8cfa..ea927a00de18 100644 --- a/security/security.c +++ b/security/security.c @@ -2062,17 +2062,16 @@ int security_ismaclabel(const char *name) } EXPORT_SYMBOL(security_ismaclabel); -int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) +int security_secid_to_secctx(struct lsmblob *blob, char **secdata, u32 *seclen) { struct security_hook_list *hp; int rc; - /* - * Currently, only one LSM can implement secid_to_secctx (i.e this - * LSM hook is not "stackable"). - */ hlist_for_each_entry(hp, &security_hook_heads.secid_to_secctx, list) { - rc = hp->hook.secid_to_secctx(secid, secdata, seclen); + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + rc = hp->hook.secid_to_secctx(blob->secid[hp->lsmid->slot], + secdata, seclen); if (rc != LSM_RET_DEFAULT(secid_to_secctx)) return rc; } From patchwork Thu Nov 5 00:49:09 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11882841 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 3083BC2D0A3 for ; Thu, 5 Nov 2020 00:58:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B88F42072E for ; Thu, 5 Nov 2020 00:58:57 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="ZxI4ZwVj" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387997AbgKEA6z (ORCPT ); Wed, 4 Nov 2020 19:58:55 -0500 Received: from sonic301-36.consmr.mail.ne1.yahoo.com ([66.163.184.205]:33864 "EHLO sonic301-36.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387957AbgKEA6z (ORCPT ); Wed, 4 Nov 2020 19:58:55 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604537932; bh=eZeO09DJlcX2wY8AdT21fgnfDkYz/4ihUnMP/xr6IW4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=ZxI4ZwVjQY4n1pGC1v99I7NObkXT6Voi9ZlqfGnpgWQrj9raNndSjbhvx89OAO2g852gdtb1pcQ2nrQe1Y9ZW0OZGII+qUPudujm8n2hQ4ycTosQNiSQ3T1RjKIozzfPY5QaXc3WFtdZG3ayJQiSi5n7fRCX2n1iI/H9UomKNrmpaI2BjNxbSwh3ADeUyCk04zwg1iJ4GDFwSdTviiAU7/tvOqyS/1gs6jfg5zpnom51m7V9H/ia2Uj4u5VGV2KZsIenggXEvQaNv2OzEKZ9jMJNO4JdJ8TtKWSStaV3vTpx1OxLq4YraPLGgmGCSs3iXNs0j/eq8qH3IMsWj7D0EQ== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604537932; bh=U92zcroqCccal2Vy2U5Og48M2/YnohAQu2wwg724827=; h=From:To:Subject:Date; b=ZPkpeXPII78NfFIDGO5xIl92NbpJtORCZU7cXo+hH7UjwMlIcoYKbQNcijSt+WNQVg/4cQN14onpygg9NUWTsCeo8WJozETWXRVqx69qGQZMvMiH2CE7PQvglKC9uksylBjknqykM9MgbxLjHv0aSpdljiFXv40UGT7uasht7y0Qwl9y3TjpCZtF6lEE9NRB3XQ38o3rE7lm7GGbGoxs5Dpb4pitq2WR3Dc7mF5ig6y0VDOQm/rWp+Cm2qGXEavoQMv4rFAd2T87h2uV5KEoXdaZU2LyIXNWTLOXkxVV4F+0g2z/er989CZ6QQcMJkBT1/c9WcTlP4/V8Dq00v1sZA== X-YMail-OSG: 9urMCVQVM1kLeM.GHp429ckZ0OIGDuO6NjibPIrFWcZsHMxFDTFhYhV1JvGS5iC jBy8qaf18_ZLgbCnDHsfoV2Ej6irCRmwclX4fnOyXaWFvnHsJJOHJcgVNs85sDfRBy2xhJLRipZb 1fa8SqJCYoLYzGcer2G8MFRZy_qGYBEUnazmyNJmUWclaSzgPyorkRJCUxNgLEhO0qneu8qV5WAr NsU5tFq.kVqK6wnlhBX6fq79PDsZD86RC.eVSK12wnr.2BsmvKTAD9ju3PA20Q1mK4RTIdkOy6aD B_vylP0EP3duB.zvP7ahD_WvfMAXe33e1yyyeBxF1usk8d9l3A2LqUWU45ttfHAB6XC.CadGpFzl aZ7M4xjH5ZjKCuQmOPMtm_VrAjIVU_dYB2yfL6LpcEROgI9Hw7REduCeN9Ufn.PidCD451eDTH3D x.QMgD31nVCRrGM.18dHiuexh2Qa5ZffZ7G573rtI0LcAnsHngaXBA.NvgFyQEKey1tgWwjbANpD VdOB3qnaltee7ySGuyr4Gf6L1OoG4L10E0wj1PZymuCyiAQfQwTEobVylwZQgXE3e5M5kcIpWM3. CHwKC0oggCyVVLSvBe8fLYKNB3CyDmewNf.aw9opjN6RsENdJCzZZjZt60kW9MK.TxF_42JtQo4. kVeDjJ57.E4m_bU20YRWTIMl2brhn.SZYV8_bJBYucupIlG2rJc802bG_m2_kKQGmTcxEw311FzK ZcKr2bt9omSmSFS0fgizqieOz75gA2oykkQsOGniIUL.YCJL2Nzs4J7npo4VWHbyY18u1VYJjqo8 lOSHkV65FjtTBHODVZyd9B.nd0Av70FTP8BIK.DOstCDge6aUHMI5eB85rVQ9Zlwrb0H8S59us5g CxLWrZIk1vKAj9PHchq.pZ7cJH7GE5p.EIx2Dm4W.fXiWuxoNcFDceu76wOaIRdOUVDpeEiHEQQ. dnbeUWOdI_e2C3Nyw5.JEd7OD56twEWxIAYn3dnBzOVasWzqa3EP1lMeM85LPM0Iv4tFPMnImn9y mprr5wnblMuwbuhrYkr4PnaHJUQvD9NMhZOHjeEXshyUxqg5vQ46MoqdMgymRYlGMQlcFEhWJG3T kFpZy5huVYJEuzrX4G9XNaXG78KdjLqEEfM3aAGSNoNOjlL1tVAN9mjZU.MJWXOGM8KBuH1B3z7M vNd_80A_vIOUZ0yB9U.ptFkszMRuV.luhfIsbIyizoTgY9bniThtIHzFFhkE3BTRaFSCXNi00DJu 0TYgHjgdVg5EwXgtZbs2UiKAZpw46apTjEJDTzRNYB7dIMJ834WCk2QpRMN3kyotzJSSvi2J3plZ BzFycmM.ox7xZY9widT1cL0Nug9IJbqysU6Cgl77DWAcuJ6U5ZhHQC1Oni3INE8PDzxzON5Ofed6 RTrX._R_Sgq03Ghib4CySmO54t9BP449lPCUjNzIntuZaJOppsjgBkm4YzYM0M_gJ02lyEqkPLfu kttwBpyCHFqvme0z4.t28dgG5MScgQj.C.GItcLhoQ.BPLosXdCe9Npn5DaDYRcaHdTDn66ng27c szSsjdzQvCKQjrtNTIp5v62S1ixHr0KlPEjN1gnC8Sfq1.TjfXp8CMnflOQT0BUrBxPy4okLGN1n KAItNq3w5zeD0rSy8bDWKwUEMye3ggIthkRncfUXxUa0qwD4zhZrz1foBsXbKVtN0I7Z6xi1.Um0 Y_tDlt3PerIhdiBMFpWVxavGHH.f5XKl_pkapf_tlBrtYtJrvubd2SVmtxfbOkgm2moasYecboR. tIldQXYje8C3Jxjco9UZEv2270gBtJ1GwaGa4_WYVO.AMjJFyxIR.N92xmrT7b8T8xZS0QxEw0Ek PXdKBwOUHaXuRWrqQqM99tP2cLKa2LYnPxcpOdJiSAfeoZyxySoIzrTtxos4K8dfH.mQhKxZZTuy lnyWjeT1yf4RyB9Vg.w_POz7oZJd5pPydAAbyWPTkLiWP6rsF.1K.GF5UbfTpf74KGFW3sysOmrm q6JAe_ePOViYuuOzlEt0PKkGFTCi5xYEGnRMufg0jnvvVGUa.ZM8YAqlWcpv1oBwCKTuC9ytCNml O.NGSr1mLWZsFInujSW8Me74rMyGQe_VcVc5nXddaAPLQgxvsb5WmdXYcyirBROJyOoodueVBmeX PjV5zrCBLdYBj1UPENUO7m5yagHApvYmRLXEUviH_2vKwOe0JZ1u7A0eg3tczyzz5O7z361LLQEz T9mAlxKs4jnEb1bwkoji.Hy2PdulxLqgvYagUR9dXZVihXxJhUdpKrnxv4pF.SBKsni6dhF_1CXi NJyy_x2PBIQo_BADPg67G4._gJNmHmqrzwWd9CaRX1OUyGVYnn__v2p0gpLCeR5GUroCT9qGBX_g tNsCQq0eSENmWQB6hXqed9VLWYiG6xfwFPPfj0w5gKPISWbVBuaZsy5EWv69lZWL_MJBDP.7Kujd vZ8i39K13K9TcBVCkI4FMXacxHLG9B7aGhur2mlMqf1z_D4b4sFVfl7gkHZWFw80mHkMOp5irCKv nIgtSo73y_dyuyvwpXPbSfoE_QQYh.9nM0ooLjW16i4mZ70dftiCSH4ypkdEuYh4a5CCwdjnTnVB 0ppUKFXOZG0dwbXuHc0XyFU2TFbe_RHsq3iT04ycSr0bu3yg7CPrncSegSYcuHvuxck3IRLZiPsv J73LVvvhgJ4mjhgHyUHJBArsSnCSR.NBd0lUR45H3Mm.fmGuj0THFyELJcrpC1aI_GWm.tf1DFbK Bjc_IFUIDprv15Jg9IkouacqW27e0RkC7rVLvPdnmx2qs1bjNCOTmMj9UPzt35DeeC27VCYaCbCF irUQbaDw_AdKSjauOiAd9ecdw629mE.h.zCWjQ4NKAGB7eIFOMNvkqm74iP95uKvZy33TiDdPOr9 q_rVV1ilAHDvZdNX25ZFRQhWUQFF3imvcDK5SaHS_MIp9EwAPnoEqEHZvH9WF2ot9W0K31rm191A fZ0ROzeXXFRtJ5LdgABLbghpthG97n.f0.AF3eGEfdGWTWq2xGK3ea_nb0D_dvLOdgZs5xRMbQAM nHyyFdCdjFkvSI6kNZNFLI_ewx0VzF6SdvEmdh_CRXls9paqERwLke06V.x8RHwhNBaMRtKwYuOU SiYCGMRSwTU_2KWb0QTe9qX0cMHGgx35rKSvouvK1N1SG4vB8jUGgqLc226fXANT53yYJ3kEJGWz IxaAswdIb8KXU.ij.9OxEqKgZcrjBvnT4VixMOMhjrLVzpCsIZ_3lU34Od3yfeexoxVc4kXB7B8H CSrs0pgYrgyZGCxvvOPQno5bwe5lp86n8XzncLYy0W43sLUPLfPSB65NC5iktyEp83ZW6ea8pVOd F1PBK4yiyn8o2tk00xaBQE_OM.kUwH22jlzcr3YUVNe2Vei_LMNCBENBh9VcYWDLEU3KoHUUECva lED4G74DwaSbJJYlrqvE28cLG3PNDgq8V0iTH2i4jf14BjBLjUj8jZfq5KhTr.bjQvL8R3Vkg4tb t Received: from sonic.gate.mail.ne1.yahoo.com by sonic301.consmr.mail.ne1.yahoo.com with HTTP; Thu, 5 Nov 2020 00:58:52 +0000 Received: by smtp407.mail.gq1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 7f534deb0e26511a545991947c953a34; Thu, 05 Nov 2020 00:58:49 +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 16:49:09 -0800 Message-Id: <20201105004924.11651-9-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201105004924.11651-1-casey@schaufler-ca.com> References: <20201105004924.11651-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 Thu Nov 5 00:49:14 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11882887 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 42F7DC2D0A3 for ; Thu, 5 Nov 2020 01:04:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D3D5C20867 for ; Thu, 5 Nov 2020 01:04:44 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="eutTA7ah" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731017AbgKEBEm (ORCPT ); Wed, 4 Nov 2020 20:04:42 -0500 Received: from sonic313-16.consmr.mail.ne1.yahoo.com ([66.163.185.39]:44916 "EHLO sonic313-16.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728066AbgKEBEk (ORCPT ); Wed, 4 Nov 2020 20:04:40 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604538277; bh=NjD1+KtwElZe56/UGI6PApTnqSE+EEj9ZLVXzNuLfBA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=eutTA7ahF6JicqoHKXQhVfMxCeGBAJlnGti253jQQowJaVYINUQ7e1gF2yeycSEu80Tqm+TkpG84AcJs16oClgJMoI3PKzoh+ONqvuC/xOjAvpsxtppkpAJolnYSLHFpq4tn6fcB2TsPcFxJ26gCxFatlky/TukZhazmVvGX4uAYIcQDwJIsrAmu7EDTl7JIK/gc37bexnF2qGzSip9JO75PpstJ7HAnQEqhlR5dQanO8Og5s/4tXGvplkywmWGdQ95D53v0RqIIs6tDlQYSM/XUS0aqqYlvyKuYMJ8P0e/W4hCwBduxBqnTdka8pX36K2O9AJh+EhCmXj+4W8hqsQ== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604538277; bh=zJnjHW+YcVQXANrM8fww5EsB+kytvSDSGD2Z/KAfBOy=; h=From:To:Subject:Date; b=ZnPi7aYC9gkT2qwu5aOcdA+jcGlsxEbZUH4rMhFhSVTBljOJ1Qz4McypD2+WDM3jpAfO+USLYmdx2buXsCzn6+MxdtoMAu/J5M9o1XwA0NWGcC5UN/1bsoaKFFevT129kIyMbDQN3JdojuQTXnQ2XHSJ7ifp2giSJOcxIPRUV8MaFRFy0YQYLoyKcsfhbjhaOMjVSiSaMElM7bpXfn+bbRPKutsa1vF6q14kdzeqf30TlE41fcts4CRVxcAkYIZglaDFImv9P8an22vYGqfNLsFHH8voGVMd/hNKCbfoAn57QbNlZxygJtp+2drZzCQiIFV57sDFwt2r3N2De3wuyA== X-YMail-OSG: uH4Th8MVM1nbZKPy7QtCJwT_7nZQ4.U1nR2cSg8dMXL_jwyxsG0v8bdpgc6B8NS g7UGeaBLkbQ8c5.3dfq06_7x5CdSWIyyTdgat9Agqb7l8jXk8b8Nkk1H7BJWk3plU8XtRv.Gjrmp APtUAyps4J5fhXAxN0kqddbk2VeE92qBgVE7L7YPY1rOWFMJAqryYUsgJSHmBwUWQfmQu0DqKjo3 GLmx68VTJehMI0fCjTut9mPaK3B0IimpzzlGN3iNuOGxVVo1MjyFrAUl1sxB9h6dMRtEaoGfHzjr yl1BFy96G.JUvtJXWg2gcvvv61H3WjNRKzxj9C0SFZRAiXM6vu6IKMUt0Z75.73_CucICecHORjr 8e_8mBzqjz1L3_v2Rb7WhyG_6aX2akOxk70S0vvfevG47OwfFb_s652q7CBBkI4s4vom3.bdWWh3 ZFkpR4e1p.eIi5R1Phh9VRiUYYjXfhCWYHDJ_J64jZIi.BB4D2Sx27bLuVM2Rv08Nno9eg5tP5sK WuJF7AMacV9LYW.JYO.LFw8lR0H9l60qUszCvzdbD0K3RZf7bdAMndDMEnpYmE3emrupBmlJesY4 h0ClUjdAt6Aeq0dVJK3kycm20QROLBOsfdriPIaI7BDUlMFc0X.HPMnQ9itUSl1TdN4wQZD2Eo_G vMVl.ZRMLuV4sOpCUHM9sq.7kuOfK0gbFAO.aO7ufxAKirHWHy_tEWa8tuGdxwRjxijyiwhrZGLy srUktoLdy7ssKQQ.YERa1qLuRLl9KEK0ygLxOj4jtDt57ht9X7LzHQbJ5Izv8Y6edRYJMzaBlXD6 7PC1Ur8B4nrCnzAEjucIl_2rl4mX_q3Zs5WPuldwnY1h5_R9b.59PFGErm.I3USp39WbGV1RYPby LpR_QsGKiQ_2GIpug5yOZqSeNM386ObVw19dgCKC5qBg4uxnkt3TQ.Jpo3xeh9qDMJqqySF4p3Of OqBDupJiKHSe6iD955hzKyvf3DLCnHbFVyQAciPTslZJhdSSuaDAgYoA8HwAo_NR6i_hnws_2HNl 4aI_QLh.oubX91WxbN82P7qhEjGjyZdNt2aw777258MCsCxADMrREi8r8gLlQTaRD1FtarUZENZA emB5V44.idEQhgqwzLUTCczCYANJgy0F2alsbIFDTBHNi1jBxtlZCEsi.f05avZXoZ7AAXkU_6k4 qkR_GAzaSyLjF_CQrg.0dYxb_7IB0ffENRdtfbhrH6nHvU9.pxJjCgwvCwVcUBxT3FIOmz4iq0Tt Myu3u0dpPSsGL7Su_FKPZQAHcJsVJw2BUakciKAz8PbvCqwuYxtMB2Q0p3Fh.g6sJ1nUWt6j1kPY soS3Zarb0M6uO5V_dKwIfkXaqyIQPsnxkl8YuJvhkvnh6TcjlDDwwFDixZbWSfrSS9VQTqMi07zr wk_myVvCp9K97wD1qP6wamaNZOed0yMHkh2e3TATgllzXCykzxXrL_U92_JnQWwgje1xWfGVCrBp 6SjvSF5GZH_yznW8WhWH_feW.8hFcgErXMh.vTz2dQjMA84vZhtPhjsv6Z0xbpsXlNDLSudoaR.z Sg1Q32ucQZqqslNANycP1eDYC9fbij9cfBA-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic313.consmr.mail.ne1.yahoo.com with HTTP; Thu, 5 Nov 2020 01:04:37 +0000 Received: by smtp406.mail.ne1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 9732deb89ce3ad442102010a7f8bc296; Thu, 05 Nov 2020 01:04:33 +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 16:49:14 -0800 Message-Id: <20201105004924.11651-14-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201105004924.11651-1-casey@schaufler-ca.com> References: <20201105004924.11651-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 Thu Nov 5 00:49:15 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11882903 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 B7C9CC388F7 for ; Thu, 5 Nov 2020 01:05:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4AC74208C7 for ; Thu, 5 Nov 2020 01:05:50 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="tR1M2ves" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388065AbgKEBFr (ORCPT ); Wed, 4 Nov 2020 20:05:47 -0500 Received: from sonic301-36.consmr.mail.ne1.yahoo.com ([66.163.184.205]:37275 "EHLO sonic301-36.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388043AbgKEBFq (ORCPT ); Wed, 4 Nov 2020 20:05:46 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604538344; bh=RhDyTRIUUvKNSYKelEuTITA9CN5VF/9jr5GLz/2ip2o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=tR1M2vespoEs2pHc21LYSe0JHsrOYq+rheO7zlUxyRB3IH3YSMI1oivJ72iFC2A+8Tt18GmkO/9Qu5y/KtMJd6ckz0pa9C0TLicaMA3AWEJhxefkn60zQ5QMV5OcSplFw2I8a+vwpbSw85TI6M41FBbUhm5XDpVttJ/dQTZy0/2gIHZV+tsckun1i8ChWB7JL5jE/6Yc5XByhNok+b87pDf76+oUm1Tn1sCqiE+mBDH1ZdufTB/So8xJ47lA2nL5lE6hO/2zvTcHFIUZPbREJcVESllFprVpnX3KDRva8XE4SdvyTv0xCka5Pjwxs0WtWhr/E0Jl0EeiMWsVWErUaQ== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604538344; bh=23ZHddgEpQEb0JeWZQaKaLay5UUDoqB1PLWETjtjWUU=; h=From:To:Subject:Date; b=ZwR7W0Y7sW/P6P8SaCY4/w/hI7m9cH+JDodPQwYDQD2QGNn4evzbjlCek+nhJEUCJRzhX1zSlALSqyeWtF+MYizM6rrFanK84exLzyHemMNNYsi7sIiEpys57lk9RHmHhaZU3bAPtj/skvEl0u2OPPHVj14g2cmGxTABMOwt5u+gfPGqwVc1igiRU1X+anbnYhblJTmoPtrBSAAmONl/kG0Q6GLc4rJ47tXshPoxFeai9bieURZ/PDNcvfAcA5zTsI2Y0idJ3Q3n2eEM4capheyT2eX/Ozu+pLnPM3tUgbgGSK7rRWCRvORKhTmdAyCIT2Oqt1iLB9LXn8aQJw5Q9A== X-YMail-OSG: kUGqNbsVM1nuUyEFXsUXffXVXr5oBvKVGCszW.OVtBNDqJNLIwQolw7FZG.NRh8 hopjQUMqIlP3.kqNvx5PlSZk8ShTbUrEyy.AYF.HEE6YGybMxz4CV6U4twkT4T.E8daIhLFdNHGa uT2hBQ6w7bc0SkhPEhZehu9UDSeTI2beVNs.F.ehceEwEWqtZx2RLJZRRP8JpdkvUB0u2Pddfxhd XsSAMGDHEjgU4gpRBZZ9WdFXpDKepNQ7WFrh04dxxIzcYZT5Ag6cMxbw5hItQDeMRza1OT1RyCXZ UxyzxzpiEem.eA5TCp_WBXIK884tF9_8LraEsy3TJiRWN2D4ifOENADBZ.Bq_VdyvMOk6Y6Lie.b 2M_qm5_YoMDd8KArLh8rDEEKo.lyHlIHSgId1JMKsFAijsZgCP5Hin4J71b77OKOMyJuUIw7AQcz WFBAIirOGBRUy.L6tEQqK6jZ4WKaJCLVefR_oPPen4s8CHw.JMGhyOsKG.NpUNziK6OFPMLR5gQ4 9_Wt0dozFIDsURn_YnKJQoLX2xQBNGPQAcK_oNIwd8ML6pXZvo.ZRGdy8xjt0BNt.FOC9iWs1XsS 9mM4Z1oHORLexf5TzNEYC.OvawI1jUAz74L5z6Ui3MzVK.X7daDqp.OXJH64y0FlgAd2X6QEfs4X myjdEAnsKDG80y9nhezGgsSRBSXXis_vrP2YNaEy..Mw5fnhMVfe6mAR3urycndMKTeAMoZw26vV vDC2EaT2OcFMFCy7cP.cofgyfaU5a0xN4j9CiW62yNo4BgfrhKt5NbvfCoTyFxp0Oc_57MhiJDul ispQ7XVPNAlWYBsS3fslTIcVb83CMVUHBuzPWyeV3v_28LaOENxnzPgVWNIv4yKDbDLHkmERYcyV ZqxT0fCDjCQE_k1kc6BSe6HYpYCRSOC1z58_wcSEfYeilMopxDyeiQN9mhTbbYpvF2XfSPMFgvcn EqZyO7RSppdMFcM4t0XxtYqveJ1FoAVWQ58IeLM04sUcrBohRWN6Cdt3uqFeyg7YrTOyvkj5_WgI b.oDV0nJkqW7BozunNsNG0kvLG8OAzDCISDVo5gC0GzqDwoSXPDO9PMkIFR6RJ4VfRrWpuQpdmrR s1uT2Ww3LwxFxlmgBNKGpa.EpLQIZl2Hyyt9ErrF2C6FXzFujm9entnl2I1MxdfS.G_IcxEG8xKA zkbo8MMze9Vr1mYxd724fiBUdWTpoDrqDYagYnvEFYvdQQKcZptf_Gn.16_c2Z4_Inc_S9_g_y21 hi7yKO2lyumS.wqbMulzqpa3QkDGN0Owp5qmUQ7_yiOl2Sdm7MAj8kjaC5Q8wIwluTGw25_cZQK5 8loevKmIsGtTABHtoECdSPLFQ9s1zNS4Y7AgOK1ibhX8lDdcZkzkzBXuS_xPIYsCeCQtNWaNud0F JfDGvcUXpidB8ELFg0dYkQ9J_d0HelStxi6OlfINvr07UggcCDTSu9qGtLE9rv9F5sO5hb_aHvUy _GtcDlE5G9UCDui1lJ5jA718NCG6rEkpqY9U0kLHC1zEAeEpQGjKik_kVNoVRdjvOKQa1GgSzyUY TG9_1uvewVkvbx3KtQBPXPZTHOhQLHATo2RY0xVbhdMpR4le7qff4rAk7gCimp.KDzzdb4F9isG0 sIq7A2aL_xvp6TAS7Mk2p8pDMmyt2IzHxItOarZkVFGaHDouAH41bbPv0LioehQJeXO0H9Wl1i5n 6TZbBwM4HAlvtcRWioiBZuMb7LprEra9EdmzBq_6ZDmUOWrfyg1QnZS6M03sRQnDwuuwCMDediND Cn4xcxOMvPpl2d3KKDppElK7eTtwLkvuS1o9gf7VA0.RKWKaA_5ebfhRPazYH6_pG8qg9lgn8kHh ujNIrL4maJodUWqyRXsHvgbr5jFl9gfsivFGw_hPwq3shpN3eUavTWXnkAULEIwRg_htyW_eAvZA lfyr7xaCvFPO3_4HHf1YLN68g8_P1SM57Dl5Zasofgts1gTjnfNzMsdQupK8OsQA_Me.FFshutnl 4KMEsm9SBEs0U_EGv2g2Rsf7mC8Z9ub3zVuU_lh_5kMRlXCLyTBvN3.oqW4Ck9r5t5RyuxVMtaKx PVU0c7wTdwRiychMNHSsbwjk_uHf3C7AVJFIpZgu2kbE4kT24sXYqgCgLiG5wIOYtAZ6PmYniUgX VI79yamO8nMpcEfqfSTQcZFwu3.zaHG78l1k9mrKWPrmMnEb.rJMdlTaa3wOFlGshKYyrhMX5pMR lqeVQOvs4MIt1abEv4d_2tO1fXoqo3RefBsET3ktoifGd.YJgSg1XvNoOeg_KsBiOG5qN7yvmhbM 5VynPAnFKwmRemda_PVjijrkErB0HQCTdpn6LNEBIeFQtP6hzo2YbQgB6QtzivIXsQr0slnDQ3Xn A0kjlgL5Guz5Q5clRP7symInL7z_q4X4DhMiu6p3Lfdsz97wB7UGTqck1LSL96P89ToalM7T3dHn 1IfdWHLkU.KmqdJAfp5hDqtA5S5jIU_86S3Z7F62lt.8EiJaCMh0REwJdWkLBnV.b_wvm3C7HkVs gz57CHABLqvG4cTK2xvoq1KorNPvNfVBa8dCFqIB3uz.PxGnXpaGxGH9vyL6v1YDBsnUkp6jEujj AARTNBfpBNGUlCP_2__M812UUiFVzrJv7tTlp.b4pRdWAtVNdsu4kCxi0KtF.K5kSvUSvgYKLXWc rF4S67VAWFsf7an70zkMV38KDaVrOF82rqLmacp60losvqpNI8qEe2T.NZFtQrBGUu1qxcukOILT BzxWGeYR6Mk79feQlUpaajJYvNYhm3cwG1Xb8_Lbm7JsLo9KDVkGaxSCnAQC7n2JRRM_XAVW_v3i 7h2CucrjiqZwmokovlHrehyUtTUf0uhKZJC.qcfwi3wynUUAQTGOF0rnVV5UYvwkbQ95_i5fom7u IdW_3pO2JW7Y9jMs4D3AA.0P0O9oD.Ikhbu8Bej5AFwUSvPqOadBxPWQybsraEDKchRhehCDSkIr KVuvgy6MQMv3dbZ1GA96v1TU19Hu2_ACBW7.cEx2_rICHEkr6XlrPtIjssAbjOaCIKWfLkaLsV5M ocoGZfSoW7GlysetKI8ndbwwOAI754NPxnfDYy0kH79W4RC_01wKODJnHbSNEWD6Tzx05fEJnCGZ 3QOAoH0BmTAcek8eO4dZH2CYkNr5luaBRlHkxNcN8xF3Gv0qFbzvSAuemnBrRjAtwsSOf0jSIOjU 5hAh1GV7IuBvNoSrSi3MhsVmdASTHhMfXr4mauj693gYQqL..jxOjhkgURQPt3Jd.LAy0QcGsoNt NextR76u.Yd9_cCUTR5XRUqSR.VyKGIfX2rjlA11eyh3Fu.XjwrTgHd42kSVGjX4HpjKwXAJ4MJQ a.AeV__jfPSGUw3tEoejqCxIIzbTtr_uTVmfcAXALy0j5Z0Jf_JaWU8p9EJok Received: from sonic.gate.mail.ne1.yahoo.com by sonic301.consmr.mail.ne1.yahoo.com with HTTP; Thu, 5 Nov 2020 01:05:44 +0000 Received: by smtp422.mail.ne1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 24df8e7de125f43047aba718b8097292; Thu, 05 Nov 2020 01:05:42 +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 16:49:15 -0800 Message-Id: <20201105004924.11651-15-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201105004924.11651-1-casey@schaufler-ca.com> References: <20201105004924.11651-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); From patchwork Thu Nov 5 00:49:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11882911 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 E4BD5C388F7 for ; Thu, 5 Nov 2020 01:08:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 772E5208C7 for ; Thu, 5 Nov 2020 01:08:09 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="sqdaqU22" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731554AbgKEBIH (ORCPT ); Wed, 4 Nov 2020 20:08:07 -0500 Received: from sonic313-16.consmr.mail.ne1.yahoo.com ([66.163.185.39]:38308 "EHLO sonic313-16.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728607AbgKEBIG (ORCPT ); Wed, 4 Nov 2020 20:08:06 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604538484; bh=AfU4tEGic6KQi2q/KY4oQA7M/bMh1AWYHAZwfip3Ww4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=sqdaqU22Y2RAi5ra8vUvmAY/HdxaU4v4j98qdohN2tvNfQN7U6MiI5C9MmwCas1iT26feU/Rzf1/PohmseHDDO6kKz8aCNBSB9in/e+3UznFgNO+JxyMok8MugHoA7sNaVFoxvv1Mk0SHtn0QADiIwN2Xy3LVTeB5HqZPqGyBQEW8GQcXGU7GkAfw7bywX9wO3gBR+zI/VADFD6Y+DoMF4w3fkKs7YqxXTOaml2TSqKmdmTD8tyomW0WVlvxum/UsG95TsMh3dcOqLQh6hW4Yf8XGaX50zSMNzoe46xXqhvAo6E+PP2JTkGlOyqhyH5EYkQLXl7eViooG64RhTuqyg== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604538484; bh=I6tkeKvUbtujRYyF/jmQY59V4N3p32wBHszLiGwJrbQ=; h=From:To:Subject:Date; b=YIbCeTFE2pKuhOG/haPD5fPo2DVky62k9TYz3IAMAJxzEsHgeLk0WXbRugaTlUvW6jiMYyWYzBbe3Ciba/rPokoNTFYQ/vnlDCfUMzp+8opXJEk70YeL+tifyR/IlMlX6lBZUKahGUPMHwKfC4oF8LpRHKVNDn7v+Zohy28iNtBeo3vWrWy/x4GKUMJKm4YV3woK3SRR1hKk7Ig61lfwQo54svsnOzBk3llKKBJjMFbBMFzBJ4B3b+DUQnL8YgQjn3ceVvOzfcUtVEtbDMuopmWfCkPJVg9CQ22DrT0ZjQv7/8z8KNIrBSMQCOpdKjDU6C+0OV6G6PD9u5fZXspHZQ== X-YMail-OSG: nb7DKFIVM1l7ArLanzxsJpsE.et8OcBqSD029Z8SYnafHoj2wyUeAPg_oG6EvBu 84GplfVxmJM_ArsOUZsVZoPhBzLIGByAoys1h03mH79xs2UdslDZ7aaUPyN6i1AcJQKg9.qH2.g5 Z0tWpUlsf.2emIM.M18nDHddhmy7rIBieslZXfm7Foly2dQvtVkoLRI9j5lgDLZI24hVF8m3rAlw vXoxI3ziP77S1Eax3QqjwIOQzqOOPWJJ9CzS2NaR6BkWvvmMpUTDMbE4GUN7VXaTb4VmerVPAEcg kEJkwpSHfCC6bKsEkFu7vPDF6WYyhtA1KZ8L_EC7dQ4RhMAoDm3IdWaPKQjTh86I78aSGHnfcm8Q R_MlFKfwXt02f5BbkUTStiJiBWhs2LUz1ydVp4KkFwwMZ_M9oW.xGLuodtYe_s.BtID6WUl3Jw72 OKu.47ajDG2PqcwC.ri8RT7z1Z2MS6OnVdxi47WM4dETlC2s85SUNj99529jOSmrTBkBJlgTPjso g2BCc4y7oxIPpAS82YMY5c5wTrfglgviFQt.GZp_ppcwjVThHFGu418mUiWNU_EIeCzCTqeGtqig qddhsLQz0Fh7aMz2W8ozJ1xb0wzMdbRRG99cZP4p8xbFzAHUzWuvdi3vMOU.LeDkcZ89ZZycr8EK EzQKEbMZIdBkVtOT8VKVJplKe8LS5r6DgScG5cB226uPtJByyAAuoHDehWbLvHtQoput0.Ik1lFi AmdIv9ULkVWdbuXcuYPqdixr1VFSFO31CKbiklk_41TOc_s6yx47TYyHMdus0lMxiQnu491o6JTI .5g8o1cDrAcNJz5L6gQMHtYYXO5Q7i8OY8ytO4EFb4y5S3FwPOFm0bAif8JltlHz4fr9DlTll4Uw 1kn8HBStNJxTli5Rko3xYvFQfPYlzE5o2syFtDC8oXk7agYPkCt.04vkA2nmtQW25A9zHYYAH54d vnltX_NKty5Ru8bFNUND51S0fYckTFOP3zShgKaXuESc0_g7c90cJhjMXdzvkMuX6_iSW6KqZM8g jAbBmYD0ACvoCEqGKQqWIRBTF5guYLrrOsY4Yi8idTt0hBAc301h6YUMTy5.NVmKcmlwBM3d3vlx _5wRXrSCatwAuYFvxwWww7BGUy5GLH5P9H3OYwM1baLmll9PjNsqqVal9PeteiLhqagBILE3UdnU PNhzDY4tVSJzG_yJx4oKXv9DOIgjmsjAG3OR6bvov5TbQAXZoUIU25wAC6GBaZ6xyAUMAPWH5T0f dKFgWe3s6FFNyxPj0cE4kSkj1yOALqHgzJtIqRb4Z9MVtEPrSzkot5D5rjAC_8L8qBduyot07n_a dU2O_J2DR6MoNxdUIoiqrTjskQuvVz9Hd2GtvlH8DS66p7eNz6MBSF6gp7.aBtgczMsIYxDfp9fR pP0D12iTELhXwwRWkRcXxeu3.KzNWjbCHSS0Q9r8oLxEWnky1RrBd6wLkgC1GRsix948N.VVcl1b n4jX9DpMtx4a.RZhK9dhOXPC66v63n4E3_2X_XLCRMqrZwztGaUSpzabjOnp4XsyxN8JLMCwkH5D MJedtr2gAyrNaa9me3563_KcN5CKIa_y_4TkZ9.Lqu2kCbPyhmXbZVUNxoK_cdqxxljIgafxLku2 uL7ZsMakCIsyrazDluBOr3tdUWfNObnRGvtPUf8StdGt_aCP8opyF6Jkji47auk1CqIOo1Ljh82n .LDC6F2vEJN.u6eEQRpilynR01zEIdU7CEztmptj5dUPrm.f9knry7SbQmqUOYkp72WcJd2bMn3E XAfRSFVBawWrIBu.RxdE8yDazoPtUtRwMQqeZ4Ug7rO75rRPXRUJF_fzl4R5lgqd6GUMLCIgLYW2 ugewk4s7f8Et6.r_jR5Vvwgf59scehbMmDB87EudDnSaCpg7bCngmAf8fZINrWYokjLljF.Arxmd LsJhEPH7.3.8B2kurtmVow.FyElTdmOJsnGTo0p.EqQrgxu3cCOi.UbIkWsMGx2eH7mOnF4v0JgJ DyG72qI5t63t5Jp1ZEMgA3S74_00B4C0yb2Vb6x2_XaV7ppzZcqQUoRrbskvL0xUd3gy5kYrYH32 xPzHki_.FsDN_pCqCMqhZgwBYVGvMTuWkuYhrTrsaOLF8Z8orS4lY8J3znm4g_C0pViGDiYrkcmr CiGXAsRrTV17LQgs.q2hfsYapKQdn1TPgwlXRwvsbELkRc9il.a9XA8fc2GugsZPopoGCWUMroPb 43f7EFylULIfz37AxNx0GZIWNd6i1tu1DMobugRppIiZoISy89ktDzu8CoF6qk9jm5vK2ihlYri5 n6mxwXV27QFSUQ2sYj8YLAhyEQFYsh0u15Wo7hzWlVLJxGM9ld1gHg2gAV3Bg7eL_MXcQBAyfBUN E4Th3TLTRc6Qo3l.pMoPoMxVqHlv2EPxmQw6nlAfj0nV6GOg0UQeTOaImyciDcwxztxToRg0omrY aNQ3NSEZY430S7yxCXMxeKqgqitrzgS1ec.emUyTpju4g1v804byYTs8OGSIbNlm0sfbgFs4dPem bvnZtbt1SlThBN.F0f1HMgnWRnLDQ7Ge0HVk65szNMjHq_LFIEXft81gzSgFLrNfe_C3rR4AMr.m 6EtBWA58xy68aLMPlcOVJNRATozyGxq7AbzVUgGf9U_9GLiNtqIdzvGiMbsXQH8lnw3mYcvPQxpD vbVEshZWKaUPG4GdZZi8ZhNlcpR5v5vrDVDm6gQLk2CU53VBDiEoVzu_G05LM2EcI0Z.aNxIbNAJ sUwl3Vz5QfE68vIfPppqpvSpsSINDCEHSCsojGPlu6xYAlhHJYw3fBmB94icSgel.FCj8Ms6M4Dh VZRl32wz5ksuhcxbM.MQzti51qbtpJaCoS_DxEnaa9MRLTUO9PLKdBr2PQGLvbWTDMNaN.sFrQYM RTUSs808DKxQ6SmceLb6KGmFDv.xZI0wRM1ZMxT2a1ANIspINYj44hbNVCiQFJWr0qxNJ9IgqHBk A6aP2ftLVOJj6hVpkBd4e4HLCEE_tumNNVWcnmHtM04tcZzvU7hMyPAJ5eZgeRdnOpm2mWLslt7C 13JCGS94f5nl5DBVxvwlFirISrCLpfmWNmdwhgYsjeB6EThWTrU6iWQvxDN364o_pqpFNfZbiaIZ dSnQE1NvdizW7V5afRODfQRvA51QI05hQRpftnz6ntnW.20CNLr8MuJxxYAz0T9XboWDVudqYVLP _oRNcWNCBeESnF4y1aWVQnxlkp7_3uWDVrZDReADgqgKPFd14ObVxsZCDX.n0D5hSSsoOcw1p_0x ps2gidtVFctgDihyNvbxgAvB.odMQNpqUddjYv2Ak1O9EPTAnLKy92WMjWS.7zuWlVETJ4mSctfh oRrL.ihq0svYetvCBbFCbVYudg84Ve9cPI49rYdU2WkPguYrTHO48vBwqZLc9JQEB_bymWs3KCC_ 5FcD4BxFtyX09Xq9kixeM67ILhppDVFnDJf.UGcDdBVNOXqLKXAQ5el1FhxhFOUWpBnQR78f2R2S VXiLdOtqRA86roDZ1WqW_4_m5jcwv2C8d9g-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic313.consmr.mail.ne1.yahoo.com with HTTP; Thu, 5 Nov 2020 01:08:04 +0000 Received: by smtp423.mail.bf1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID ae77dbe93dcaccc5cab788397ea5d33e; Thu, 05 Nov 2020 01:08:02 +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, netfilter-devel@vger.kernel.org Subject: [PATCH v22 16/23] LSM: security_secid_to_secctx in netlink netfilter Date: Wed, 4 Nov 2020 16:49:17 -0800 Message-Id: <20201105004924.11651-17-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201105004924.11651-1-casey@schaufler-ca.com> References: <20201105004924.11651-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 netlink netfilter interfaces to use lsmcontext pointers, and remove scaffolding. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley Signed-off-by: Casey Schaufler Cc: netdev@vger.kernel.org Cc: netfilter-devel@vger.kernel.org Acked-by: Pablo Neira Ayuso --- net/netfilter/nfnetlink_queue.c | 37 +++++++++++++-------------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 84be5a49a157..0d8b83d84422 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -301,15 +301,13 @@ static int nfqnl_put_sk_uidgid(struct sk_buff *skb, struct sock *sk) return -1; } -static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata) +static void nfqnl_get_sk_secctx(struct sk_buff *skb, struct lsmcontext *context) { - u32 seclen = 0; #if IS_ENABLED(CONFIG_NETWORK_SECMARK) struct lsmblob blob; - struct lsmcontext context = { }; if (!skb || !sk_fullsock(skb->sk)) - return 0; + return; read_lock_bh(&skb->sk->sk_callback_lock); @@ -318,14 +316,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, &context); - *secdata = context.context; + security_secid_to_secctx(&blob, context); } read_unlock_bh(&skb->sk->sk_callback_lock); - seclen = context.len; #endif - return seclen; + return; } static u32 nfqnl_get_bridge_size(struct nf_queue_entry *entry) @@ -398,12 +394,10 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, struct net_device *indev; struct net_device *outdev; struct nf_conn *ct = NULL; + struct lsmcontext context = { }; enum ip_conntrack_info ctinfo; struct nfnl_ct_hook *nfnl_ct; bool csum_verify; - struct lsmcontext scaff; /* scaffolding */ - char *secdata = NULL; - u32 seclen = 0; size = nlmsg_total_size(sizeof(struct nfgenmsg)) + nla_total_size(sizeof(struct nfqnl_msg_packet_hdr)) @@ -469,9 +463,9 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, } if ((queue->flags & NFQA_CFG_F_SECCTX) && entskb->sk) { - seclen = nfqnl_get_sk_secctx(entskb, &secdata); - if (seclen) - size += nla_total_size(seclen); + nfqnl_get_sk_secctx(entskb, &context); + if (context.len) + size += nla_total_size(context.len); } skb = alloc_skb(size, GFP_ATOMIC); @@ -604,7 +598,8 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, nfqnl_put_sk_uidgid(skb, entskb->sk) < 0) goto nla_put_failure; - if (seclen && nla_put(skb, NFQA_SECCTX, seclen, secdata)) + if (context.len && + nla_put(skb, NFQA_SECCTX, context.len, context.context)) goto nla_put_failure; if (ct && nfnl_ct->build(skb, ct, ctinfo, NFQA_CT, NFQA_CT_INFO) < 0) @@ -632,10 +627,8 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, } nlh->nlmsg_len = skb->len; - if (seclen) { - lsmcontext_init(&scaff, secdata, seclen, 0); - security_release_secctx(&scaff); - } + if (context.len) + security_release_secctx(&context); return skb; nla_put_failure: @@ -643,10 +636,8 @@ 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) { - lsmcontext_init(&scaff, secdata, seclen, 0); - security_release_secctx(&scaff); - } + if (context.len) + security_release_secctx(&context); return NULL; } From patchwork Thu Nov 5 00:49:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11882931 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=ham 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 257E1C388F7 for ; Thu, 5 Nov 2020 01:11:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B531D2067C for ; Thu, 5 Nov 2020 01:11:18 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="HBI8s639" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388135AbgKEBLR (ORCPT ); Wed, 4 Nov 2020 20:11:17 -0500 Received: from sonic317-2.consmr.mail.ne1.yahoo.com ([66.163.184.229]:46139 "EHLO sonic317-2.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387478AbgKEBLQ (ORCPT ); Wed, 4 Nov 2020 20:11:16 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604538674; bh=bdpGWa3BjUKLK7zbMe4ZSkMOEIhlhIbP70XkpyqjTvM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=HBI8s639ysRWwgbp5++pSjNEbmu+cSreDqRg1AtQOmr+9EmdeHLGsjsUAESfDdhLCmSM5hISD6uMSciN4P4uICGbNxbcKidQHT5bt4pKxZoDtcHHQwn1WJxiRVVracdA8mi6kViUlBlQSLNdJLTJe+xysiBmJRWFkLdWW5kMQ9tCCYrRhjRymBCzUwq/vbkB/LwhjAEpY+xk0qEaiM8CrBRIgJpwwWAJghzbCbSjRtsaEXrlnz6iHtpSLtFl4kXoNc+Wg5huKQRZF+bub2RiVfvJYfF1ScoF8ESnRCWjCdxgArLTpzKJTe/9sbcpQPVQrPOkmKvvMzQ5penQ+2601A== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604538674; bh=Q6Mn91RYW0trTaMZjrWT8ficbBL7p2xsiaPpk80jowD=; h=From:To:Subject:Date; b=KOUyIBJVAfD2d35YesVykR3+hV3I/JVKYvM/3rK093fBJtiRXxgdNYnbRZeO0J1MCxbQdirgUOGF9KttNnjYrXhBs/CFuijexwnvJgGq4zwJAgikpNqkiHDexhEIETH5kPx8KY0yxHiW6VxiTxZrDQvQkp8sQQJ+yiEkw6eHvMw/bmtXA2K+Sa5AT+iCmoL3eQcZB4lJIVEDoP4vjax/fhiOdkZYiT4cd9tlzRuXrmUSV2xATSs9ncvmCgdkUfijlCIbzLNHLgSUZ+Uls8hj35v9yQTAD8EQmt4e7bW5du/6ExsTMxRQiZopR3rXrdZkru6jxBQDU7XlC3uH9YLOKA== X-YMail-OSG: N_6BpMEVRDvd.miR6A7lED5GPdAEx7ojsA-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic317.consmr.mail.ne1.yahoo.com with HTTP; Thu, 5 Nov 2020 01:11:14 +0000 Received: by smtp409.mail.bf1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 68b230e25e678c88b80b8696cd4322b6; Thu, 05 Nov 2020 01:09:12 +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 17/23] NET: Store LSM netlabel data in a lsmblob Date: Wed, 4 Nov 2020 16:49:18 -0800 Message-Id: <20201105004924.11651-18-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201105004924.11651-1-casey@schaufler-ca.com> References: <20201105004924.11651-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 Netlabel uses LSM interfaces requiring an lsmblob and the internal storage is used to pass information between these interfaces, so change the internal data from a secid to a lsmblob. Update the netlabel interfaces and their callers to accommodate the change. This requires that the modules using netlabel use the lsm_id.slot to access the correct secid when using netlabel. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley Acked-by: Paul Moore Signed-off-by: Casey Schaufler Cc: netdev@vger.kernel.org --- include/net/netlabel.h | 8 +-- net/ipv4/cipso_ipv4.c | 26 ++++++---- net/netlabel/netlabel_kapi.c | 6 +-- net/netlabel/netlabel_unlabeled.c | 79 +++++++++-------------------- net/netlabel/netlabel_unlabeled.h | 2 +- security/selinux/hooks.c | 2 +- security/selinux/include/security.h | 1 + security/selinux/netlabel.c | 2 +- security/selinux/ss/services.c | 4 +- security/smack/smack.h | 1 + security/smack/smack_access.c | 2 +- security/smack/smack_lsm.c | 11 ++-- security/smack/smackfs.c | 10 ++-- 13 files changed, 68 insertions(+), 86 deletions(-) diff --git a/include/net/netlabel.h b/include/net/netlabel.h index 43ae50337685..73fc25b4042b 100644 --- a/include/net/netlabel.h +++ b/include/net/netlabel.h @@ -166,7 +166,7 @@ struct netlbl_lsm_catmap { * @attr.mls: MLS sensitivity label * @attr.mls.cat: MLS category bitmap * @attr.mls.lvl: MLS sensitivity level - * @attr.secid: LSM specific secid token + * @attr.lsmblob: LSM specific data * * Description: * This structure is used to pass security attributes between NetLabel and the @@ -201,7 +201,7 @@ struct netlbl_lsm_secattr { struct netlbl_lsm_catmap *cat; u32 lvl; } mls; - u32 secid; + struct lsmblob lsmblob; } attr; }; @@ -415,7 +415,7 @@ int netlbl_cfg_unlbl_static_add(struct net *net, const void *addr, const void *mask, u16 family, - u32 secid, + struct lsmblob *lsmblob, struct netlbl_audit *audit_info); int netlbl_cfg_unlbl_static_del(struct net *net, const char *dev_name, @@ -523,7 +523,7 @@ static inline int netlbl_cfg_unlbl_static_add(struct net *net, const void *addr, const void *mask, u16 family, - u32 secid, + struct lsmblob *lsmblob, struct netlbl_audit *audit_info) { return -ENOSYS; diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index 471d33a0d095..1ac343d02b58 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c @@ -106,15 +106,17 @@ int cipso_v4_rbm_strictvalid = 1; /* Base length of the local tag (non-standard tag). * Tag definition (may change between kernel versions) * - * 0 8 16 24 32 - * +----------+----------+----------+----------+ - * | 10000000 | 00000110 | 32-bit secid value | - * +----------+----------+----------+----------+ - * | in (host byte order)| - * +----------+----------+ - * + * 0 8 16 16 + sizeof(struct lsmblob) + * +----------+----------+---------------------+ + * | 10000000 | 00000110 | LSM blob data | + * +----------+----------+---------------------+ + * + * All secid and flag fields are in host byte order. + * The lsmblob structure size varies depending on which + * Linux security modules are built in the kernel. + * The data is opaque. */ -#define CIPSO_V4_TAG_LOC_BLEN 6 +#define CIPSO_V4_TAG_LOC_BLEN (2 + sizeof(struct lsmblob)) /* * Helper Functions @@ -1469,7 +1471,11 @@ static int cipso_v4_gentag_loc(const struct cipso_v4_doi *doi_def, buffer[0] = CIPSO_V4_TAG_LOCAL; buffer[1] = CIPSO_V4_TAG_LOC_BLEN; - *(u32 *)&buffer[2] = secattr->attr.secid; + /* Ensure that there is sufficient space in the CIPSO header + * for the LSM data. */ + BUILD_BUG_ON(CIPSO_V4_TAG_LOC_BLEN > CIPSO_V4_OPT_LEN_MAX); + memcpy(&buffer[2], &secattr->attr.lsmblob, + sizeof(secattr->attr.lsmblob)); return CIPSO_V4_TAG_LOC_BLEN; } @@ -1489,7 +1495,7 @@ static int cipso_v4_parsetag_loc(const struct cipso_v4_doi *doi_def, const unsigned char *tag, struct netlbl_lsm_secattr *secattr) { - secattr->attr.secid = *(u32 *)&tag[2]; + memcpy(&secattr->attr.lsmblob, &tag[2], sizeof(secattr->attr.lsmblob)); secattr->flags |= NETLBL_SECATTR_SECID; return 0; diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c index 5e1239cef000..bbfaff539416 100644 --- a/net/netlabel/netlabel_kapi.c +++ b/net/netlabel/netlabel_kapi.c @@ -196,7 +196,7 @@ int netlbl_cfg_unlbl_map_add(const char *domain, * @addr: IP address in network byte order (struct in[6]_addr) * @mask: address mask in network byte order (struct in[6]_addr) * @family: address family - * @secid: LSM secid value for the entry + * @lsmblob: LSM data value for the entry * @audit_info: NetLabel audit information * * Description: @@ -210,7 +210,7 @@ int netlbl_cfg_unlbl_static_add(struct net *net, const void *addr, const void *mask, u16 family, - u32 secid, + struct lsmblob *lsmblob, struct netlbl_audit *audit_info) { u32 addr_len; @@ -230,7 +230,7 @@ int netlbl_cfg_unlbl_static_add(struct net *net, return netlbl_unlhsh_add(net, dev_name, addr, mask, addr_len, - secid, audit_info); + lsmblob, audit_info); } /** diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 7d426ca1aff6..a84a265635c9 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -66,7 +66,7 @@ struct netlbl_unlhsh_tbl { #define netlbl_unlhsh_addr4_entry(iter) \ container_of(iter, struct netlbl_unlhsh_addr4, list) struct netlbl_unlhsh_addr4 { - u32 secid; + struct lsmblob lsmblob; struct netlbl_af4list list; struct rcu_head rcu; @@ -74,7 +74,7 @@ struct netlbl_unlhsh_addr4 { #define netlbl_unlhsh_addr6_entry(iter) \ container_of(iter, struct netlbl_unlhsh_addr6, list) struct netlbl_unlhsh_addr6 { - u32 secid; + struct lsmblob lsmblob; struct netlbl_af6list list; struct rcu_head rcu; @@ -220,7 +220,7 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex) * @iface: the associated interface entry * @addr: IPv4 address in network byte order * @mask: IPv4 address mask in network byte order - * @secid: LSM secid value for entry + * @lsmblob: LSM data value for entry * * Description: * Add a new address entry into the unlabeled connection hash table using the @@ -231,7 +231,7 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex) static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface, const struct in_addr *addr, const struct in_addr *mask, - u32 secid) + struct lsmblob *lsmblob) { int ret_val; struct netlbl_unlhsh_addr4 *entry; @@ -243,7 +243,7 @@ static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface, entry->list.addr = addr->s_addr & mask->s_addr; entry->list.mask = mask->s_addr; entry->list.valid = 1; - entry->secid = secid; + entry->lsmblob = *lsmblob; spin_lock(&netlbl_unlhsh_lock); ret_val = netlbl_af4list_add(&entry->list, &iface->addr4_list); @@ -260,7 +260,7 @@ static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface, * @iface: the associated interface entry * @addr: IPv6 address in network byte order * @mask: IPv6 address mask in network byte order - * @secid: LSM secid value for entry + * @lsmblob: LSM data value for entry * * Description: * Add a new address entry into the unlabeled connection hash table using the @@ -271,7 +271,7 @@ static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface, static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface, const struct in6_addr *addr, const struct in6_addr *mask, - u32 secid) + struct lsmblob *lsmblob) { int ret_val; struct netlbl_unlhsh_addr6 *entry; @@ -287,7 +287,7 @@ static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface, entry->list.addr.s6_addr32[3] &= mask->s6_addr32[3]; entry->list.mask = *mask; entry->list.valid = 1; - entry->secid = secid; + entry->lsmblob = *lsmblob; spin_lock(&netlbl_unlhsh_lock); ret_val = netlbl_af6list_add(&entry->list, &iface->addr6_list); @@ -366,7 +366,7 @@ int netlbl_unlhsh_add(struct net *net, const void *addr, const void *mask, u32 addr_len, - u32 secid, + struct lsmblob *lsmblob, struct netlbl_audit *audit_info) { int ret_val; @@ -375,7 +375,6 @@ int netlbl_unlhsh_add(struct net *net, struct netlbl_unlhsh_iface *iface; struct audit_buffer *audit_buf = NULL; struct lsmcontext context; - struct lsmblob blob; if (addr_len != sizeof(struct in_addr) && addr_len != sizeof(struct in6_addr)) @@ -408,7 +407,7 @@ int netlbl_unlhsh_add(struct net *net, const struct in_addr *addr4 = addr; const struct in_addr *mask4 = mask; - ret_val = netlbl_unlhsh_add_addr4(iface, addr4, mask4, secid); + ret_val = netlbl_unlhsh_add_addr4(iface, addr4, mask4, lsmblob); if (audit_buf != NULL) netlbl_af4list_audit_addr(audit_buf, 1, dev_name, @@ -421,7 +420,7 @@ int netlbl_unlhsh_add(struct net *net, const struct in6_addr *addr6 = addr; const struct in6_addr *mask6 = mask; - ret_val = netlbl_unlhsh_add_addr6(iface, addr6, mask6, secid); + ret_val = netlbl_unlhsh_add_addr6(iface, addr6, mask6, lsmblob); if (audit_buf != NULL) netlbl_af6list_audit_addr(audit_buf, 1, dev_name, @@ -438,11 +437,7 @@ int netlbl_unlhsh_add(struct net *net, unlhsh_add_return: rcu_read_unlock(); if (audit_buf != NULL) { - /* lsmblob_init() puts secid 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, secid); - if (security_secid_to_secctx(&blob, &context) == 0) { + if (security_secid_to_secctx(lsmblob, &context) == 0) { audit_log_format(audit_buf, " sec_obj=%s", context.context); security_release_secctx(&context); @@ -477,7 +472,6 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, struct audit_buffer *audit_buf; struct net_device *dev; struct lsmcontext context; - struct lsmblob blob; spin_lock(&netlbl_unlhsh_lock); list_entry = netlbl_af4list_remove(addr->s_addr, mask->s_addr, @@ -497,13 +491,8 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, addr->s_addr, mask->s_addr); if (dev != NULL) dev_put(dev); - /* lsmblob_init() puts entry->secid into all of the secids - * in blob. security_secid_to_secctx() will know which - * security module to use to create the secctx. */ - if (entry != NULL) - lsmblob_init(&blob, entry->secid); if (entry != NULL && - security_secid_to_secctx(&blob, &context) == 0) { + security_secid_to_secctx(&entry->lsmblob, &context) == 0) { audit_log_format(audit_buf, " sec_obj=%s", context.context); security_release_secctx(&context); @@ -544,7 +533,6 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, struct audit_buffer *audit_buf; struct net_device *dev; struct lsmcontext context; - struct lsmblob blob; spin_lock(&netlbl_unlhsh_lock); list_entry = netlbl_af6list_remove(addr, mask, &iface->addr6_list); @@ -563,13 +551,8 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, addr, mask); if (dev != NULL) dev_put(dev); - /* lsmblob_init() puts entry->secid into all of the secids - * in blob. security_secid_to_secctx() will know which - * security module to use to create the secctx. */ - if (entry != NULL) - lsmblob_init(&blob, entry->secid); if (entry != NULL && - security_secid_to_secctx(&blob, &context) == 0) { + security_secid_to_secctx(&entry->lsmblob, &context) == 0) { audit_log_format(audit_buf, " sec_obj=%s", context.context); security_release_secctx(&context); @@ -923,14 +906,8 @@ static int netlbl_unlabel_staticadd(struct sk_buff *skb, 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, - lsmblob_value(&blob), &audit_info); + return netlbl_unlhsh_add(&init_net, dev_name, addr, mask, addr_len, + &blob, &audit_info); } /** @@ -977,11 +954,8 @@ static int netlbl_unlabel_staticadddef(struct sk_buff *skb, 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, - lsmblob_value(&blob), &audit_info); + return netlbl_unlhsh_add(&init_net, NULL, addr, mask, addr_len, &blob, + &audit_info); } /** @@ -1093,8 +1067,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, struct net_device *dev; struct lsmcontext context; void *data; - u32 secid; - struct lsmblob blob; + struct lsmblob *lsmb; data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).portid, cb_arg->seq, &netlbl_unlabel_gnl_family, @@ -1132,7 +1105,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, if (ret_val != 0) goto list_cb_failure; - secid = addr4->secid; + lsmb = (struct lsmblob *)&addr4->lsmblob; } else { ret_val = nla_put_in6_addr(cb_arg->skb, NLBL_UNLABEL_A_IPV6ADDR, @@ -1146,14 +1119,10 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, if (ret_val != 0) goto list_cb_failure; - secid = addr6->secid; + lsmb = (struct lsmblob *)&addr6->lsmblob; } - /* lsmblob_init() secid 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, secid); - ret_val = security_secid_to_secctx(&blob, &context); + ret_val = security_secid_to_secctx(lsmb, &context); if (ret_val != 0) goto list_cb_failure; ret_val = nla_put(cb_arg->skb, @@ -1505,7 +1474,7 @@ int netlbl_unlabel_getattr(const struct sk_buff *skb, &iface->addr4_list); if (addr4 == NULL) goto unlabel_getattr_nolabel; - secattr->attr.secid = netlbl_unlhsh_addr4_entry(addr4)->secid; + secattr->attr.lsmblob = netlbl_unlhsh_addr4_entry(addr4)->lsmblob; break; } #if IS_ENABLED(CONFIG_IPV6) @@ -1518,7 +1487,7 @@ int netlbl_unlabel_getattr(const struct sk_buff *skb, &iface->addr6_list); if (addr6 == NULL) goto unlabel_getattr_nolabel; - secattr->attr.secid = netlbl_unlhsh_addr6_entry(addr6)->secid; + secattr->attr.lsmblob = netlbl_unlhsh_addr6_entry(addr6)->lsmblob; break; } #endif /* IPv6 */ diff --git a/net/netlabel/netlabel_unlabeled.h b/net/netlabel/netlabel_unlabeled.h index 058e3a285d56..168920780994 100644 --- a/net/netlabel/netlabel_unlabeled.h +++ b/net/netlabel/netlabel_unlabeled.h @@ -211,7 +211,7 @@ int netlbl_unlhsh_add(struct net *net, const void *addr, const void *mask, u32 addr_len, - u32 secid, + struct lsmblob *lsmblob, struct netlbl_audit *audit_info); int netlbl_unlhsh_remove(struct net *net, const char *dev_name, diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 9bfc1eea02de..cb124671c15a 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -6944,7 +6944,7 @@ static int selinux_perf_event_write(struct perf_event *event) } #endif -static struct lsm_id selinux_lsmid __lsm_ro_after_init = { +struct lsm_id selinux_lsmid __lsm_ro_after_init = { .lsm = "selinux", .slot = LSMBLOB_NEEDED }; diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 3cc8bab31ea8..6a40b47307ca 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -73,6 +73,7 @@ struct netlbl_lsm_secattr; extern int selinux_enabled_boot; +extern struct lsm_id selinux_lsmid; /* * type_datum properties diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c index 6a94b31b5472..d8d7603ab14e 100644 --- a/security/selinux/netlabel.c +++ b/security/selinux/netlabel.c @@ -108,7 +108,7 @@ static struct netlbl_lsm_secattr *selinux_netlbl_sock_getattr( return NULL; if ((secattr->flags & NETLBL_SECATTR_SECID) && - (secattr->attr.secid == sid)) + (secattr->attr.lsmblob.secid[selinux_lsmid.slot] == sid)) return secattr; return NULL; diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 9704c8a32303..cdaff603153f 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -3789,7 +3789,7 @@ int security_netlbl_secattr_to_sid(struct selinux_state *state, if (secattr->flags & NETLBL_SECATTR_CACHE) *sid = *(u32 *)secattr->cache->data; else if (secattr->flags & NETLBL_SECATTR_SECID) - *sid = secattr->attr.secid; + *sid = secattr->attr.lsmblob.secid[selinux_lsmid.slot]; else if (secattr->flags & NETLBL_SECATTR_MLS_LVL) { rc = -EIDRM; ctx = sidtab_search(sidtab, SECINITSID_NETMSG); @@ -3865,7 +3865,7 @@ int security_netlbl_sid_to_secattr(struct selinux_state *state, if (secattr->domain == NULL) goto out; - secattr->attr.secid = sid; + secattr->attr.lsmblob.secid[selinux_lsmid.slot] = sid; secattr->flags |= NETLBL_SECATTR_DOMAIN_CPY | NETLBL_SECATTR_SECID; mls_export_netlbl_lvl(policydb, ctx, secattr); rc = mls_export_netlbl_cat(policydb, ctx, secattr); diff --git a/security/smack/smack.h b/security/smack/smack.h index 0f8d0feb89a4..b06fc332a1f9 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h @@ -303,6 +303,7 @@ int smack_populate_secattr(struct smack_known *skp); * Shared data. */ extern int smack_enabled; +extern struct lsm_id smack_lsmid; extern int smack_cipso_direct; extern int smack_cipso_mapped; extern struct smack_known *smack_net_ambient; diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c index efe2406a3960..9acb83ce12a8 100644 --- a/security/smack/smack_access.c +++ b/security/smack/smack_access.c @@ -522,7 +522,7 @@ int smack_populate_secattr(struct smack_known *skp) { int slen; - skp->smk_netlabel.attr.secid = skp->smk_secid; + skp->smk_netlabel.attr.lsmblob.secid[smack_lsmid.slot] = skp->smk_secid; skp->smk_netlabel.domain = skp->smk_known; skp->smk_netlabel.cache = netlbl_secattr_cache_alloc(GFP_ATOMIC); if (skp->smk_netlabel.cache != NULL) { diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index bd03020b3cad..913d41b4b96a 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -3721,11 +3721,12 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap, if ((sap->flags & NETLBL_SECATTR_CACHE) != 0) return (struct smack_known *)sap->cache->data; + /* + * Looks like a fallback, which gives us a secid. + */ if ((sap->flags & NETLBL_SECATTR_SECID) != 0) - /* - * Looks like a fallback, which gives us a secid. - */ - return smack_from_secid(sap->attr.secid); + return smack_from_secid( + sap->attr.lsmblob.secid[smack_lsmid.slot]); if ((sap->flags & NETLBL_SECATTR_MLS_LVL) != 0) { /* @@ -4700,7 +4701,7 @@ 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 = { +struct lsm_id smack_lsmid __lsm_ro_after_init = { .lsm = "smack", .slot = LSMBLOB_NEEDED }; diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index e567b4baf3a0..139768a13d11 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c @@ -1140,6 +1140,7 @@ static void smk_net4addr_insert(struct smk_net4addr *new) static ssize_t smk_write_net4addr(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { + struct lsmblob lsmblob; struct smk_net4addr *snp; struct sockaddr_in newname; char *smack; @@ -1271,10 +1272,13 @@ static ssize_t smk_write_net4addr(struct file *file, const char __user *buf, * this host so that incoming packets get labeled. * but only if we didn't get the special CIPSO option */ - if (rc == 0 && skp != NULL) + if (rc == 0 && skp != NULL) { + lsmblob_init(&lsmblob, 0); + lsmblob.secid[smack_lsmid.slot] = snp->smk_label->smk_secid; rc = netlbl_cfg_unlbl_static_add(&init_net, NULL, - &snp->smk_host, &snp->smk_mask, PF_INET, - snp->smk_label->smk_secid, &audit_info); + &snp->smk_host, &snp->smk_mask, PF_INET, &lsmblob, + &audit_info); + } if (rc == 0) rc = count; From patchwork Thu Nov 5 00:49:21 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11882945 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 63542C4741F for ; Thu, 5 Nov 2020 01:12:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 092C32075E for ; Thu, 5 Nov 2020 01:12:53 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="YhgTw8fz" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388221AbgKEBMx (ORCPT ); Wed, 4 Nov 2020 20:12:53 -0500 Received: from sonic313-16.consmr.mail.ne1.yahoo.com ([66.163.185.39]:42295 "EHLO sonic313-16.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732114AbgKEBMu (ORCPT ); Wed, 4 Nov 2020 20:12:50 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604538766; bh=bVGH0BStUAAFmhVu8AKOg45afRJpVBV+saUzjNPSgwM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=YhgTw8fzqpEF4dHLFic3ED4zMWaR2DAC3AhzktVAoSWeMmOGL73lcTmNEg0QPoF8ZwAEl1bvpp8dd9RHLXPmqa3RBeFXQ4asUkblDSo8YIdFzS7wUPj22AvNrQWd4JyHrVa0eJ/zQdwl6rOKq9aBvMrIv/6Pj4VlErnT0IYbmxaNYGgdn4cSFYDEk4k/VPKC1C7LxODVxQ5nIPNJfC0pB+celS3j3LWUMbbhE6aBvU29He4xdmoAyUQnoIY+WCx73qOC4LVPU1PVWCIfX2uPBaHD+4YzZF/62xjPZKeja0iTPcZxfFfhp9Pr2zjuIt26eUIDgp4Yg2s2vINAcn2BCw== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604538766; bh=DIbbIcrj9pUgd3r1j9nsSnd9xBQfJczr1U2b3Gp6jC8=; h=From:To:Subject:Date; b=L8xvM+gXY7smqpW7mrmFZ6TTUzAiiMZr5S6xz/pNRc7KduFrxWPZB0JBnY+fsAhJVRBg5Br281PExmyBpYAwGAdoKFdjf/oa0hCANbnzoD5+CXyzqW4o11kblkYiWfSw3XjDhRMzl1PDjDVp8q9/RsPC7wZ9z4irYOG2NxVXNKJznqf3GJ2WPBNmtxE+hHW5fN81kRHoYjbzsJFej4HszHxiaUG7cSN0DTzd+oXoX/JYWie+cq9B/pGRJUf9JGCDKT6sxXHmPlaYtn6LMF5ZA7IKylwhMDU80zj3iw8hn2ys85rNBlApYYiOIXrpLkXRfuDlFnErcGqg0Dap9eL+HA== X-YMail-OSG: q4Q6JiEVM1nwUg2l25LnQqt_cOyZFkay9_6ZMsJ.YICsD7ZbvmecZoYmr8hd6jr Jv1v8FY1GHoUYo_CRQ_p12zespBOoTOCIvTzjbvf0s7hFAoX0em_HunnQP2A2bISXfyhV17JTWd6 34wa9AYbBxL7eSWgjY4TfeFQ.SVCVDyCDzPe_H5tG9GRqxs5c.ygKiDa6V6k34ogGzeoFzy7qY4M bz26GurK5LB_zE1_ThrntBm3rlati8GWAD0D.XxywK0chsJsedVqfFWC_MMIsXz9uHNNuKSrEBmY LGJHjeq9LBqiG4kxx1K43hXnuxeEIGoGM2GSwsEt1AOFMnBe6ANrz.xgWxxs4PIC3.qBMIP8Uufv h8r4ok8fV_BkOgjq0xuYhguJllfuLADFaqYmO6CBunvW3eIMfuR9aCb4e8uiHVlqoqrdlHt1Su4d vamLpBmf1y.JcWGg9uMOiO2ovBiWVz7A3rGpe_rbMUGURD..epyxzKE7jLcdOwDz3sn8l3B_qUKG DDrWrWO_Z1yJ8tuL7La16FTWkQJAAVuJzCmhuocFTwlkk4On1Q2ZWdM0AIoZyvr4ZD0hLDRb6K6k uqSOq78haq3hGJ0D5yvk3tBQnuDKa2r5m7lxCPfn4orzVvRUSfCpayGEco9gOL7lfxtgzHqShp1N V9CSLWpT_bIldacqAI4fsg.yddR9AlasmnMMi2zKJf765S0B5Zyvgxi75_SQUypnfv1.fHo9qfyc jatjyDryWL2Ekm1jpaHfNUXm8gvyleNtmjCb7q67AH8MxacMAYtKIed5BZKAF91U0jVA6P94KiNf FsnxckUSizwLlbgdC8G9Akecd_nh9aQI3fxFHHI5yTSy4IyE5CCt04VQR6ieSSEhOTnVHKY8.zwn Fiwrq58XCT70DqAyKLymPwapb.3CLrCVe7sTheQCedIvhuelsWwj.LiB.OZbmz4znBILlXjf4ZDM jfENVK0bVSYXrcElFQBIg1VVN2qZ3pMWx8wIpyXN0iBWenycSVAlG4P2AixsDjitJCJTs6DNMZaz eywZQfe82z3PzgLjvNzn_RMgUtymPZT196KVUv_us5h_M4Im6ILgqVco3sYzlebhEfC4VCxLvIDp 7Tv.kAkbOcNpRZ6SzWv7cejnVM9Hzix2v8N7wnQ0gt1Jc7x04niI0pkXnsKt.bzvsZS2OUunIchK .HGFLLmlNUG9X0ChdNO6vIxqF.W5h_IsU5b5OY2mDeaQCkg.f6gnhz4nqWOjIuV4xo06ehJl7wXf TEc95Mb6Xy7oRKaHLGHSxnQhLyXgl.80srLUQmzuOwORGLgUEMzONEfmB7bxkTthqlgJ_AQcS3wZ uSY1hQxD1YezrsOoUorCgnNR.WOfoO_wQavLaSoUd1b7dAvv_YFwy9YFYlExEyy4B.noFi9KrOL4 yD3wPzp7fmfwOKADBKiJ9raDUWO2rDvCdK0y0vqR7fUu_SwHBdlTztP8u.lLeXnSTsB6g.ka2mqu bfRgUAlu0hN1GsoBalAkMHaa.bjoH_.w0jADcXMG3PaKZMyV6XxAIAUxOePeUwXK19Bjj6ekqnKl 0m9BlL5cvmuKBe4Sm5qwHEPj_42kIN8lgT2.iFEkKCurmpJjP7onY1wx248p9q5diVgW5gVmuFVM 1e.p4xgcIvIouRT3_uik6lmaBc3eW0fLe_dQdgLowou4aL3eB3kvrrEVpuJI24c2IbMueZG8Btbw I4w0.5iGvRmWNRqB.Z2E7Fb9DkPD.pivfbLIjSPmVVGjEdDHenaoYnCW.JsGG2msSISHQSWPCXpL BVTqsc0B90DGz4b5P8wf.AOCVbd1yCUliUhBAGCcSC1sXEWDgW6DuO8PUnMocSUY7FlxJEUsZHpn bIUway57rpS089jqnnScGkCHCpw0tRP4.k6NhLFgWq01igcGk1VE4JEXPM_e9mDbr9n_mS3oljK3 usAHcRi.4rMPhePG9zGNZPsr8rx04DtZJ8g7.9xnRS92onc6hzaSt3jkCVuXhaBp47j6ti5bORdD REYOxTSpxLqBoXr6iP9MaP7Fiky3hhqJ_Zo2PmUqvLa5A8399D0hCH02TyckrDx_EJmMO_ZLtC1W Y2ZU7sO97Eucgc0L.8DW6lA9TmP0aT94CXzSyIzzQX5QOv2KZ1.N9f7HqvcI8wAGk0EjS.xbTord a4cAlnjpjuRdyNAWtOJ0Q5S552SzQMPEkCpCqpbC4y_pG4LJkl45dqaAab3Wp2SgHKhwsvMYfC3S 94ogPpkx95U5Jn5HzX62OCSAwHACQgExVlq7FXuyhUh6UZNrn7uX3lFNSseR_L4.sgETJ8IwyocJ Xm0Gt..uX0acVCiKcemi1AGPC05l_33yIGsOhaLK5K3oasEM8z2Tpa0jXxJC9ye6HUim41chlJvp d99aOs42RyocNe4Odp8B523buGKoqkKfi.3l71_GyNL3EhapIEbh5G8HI8u.d.oc5Mnq6S3F3PKO MEVl6u.bOaAIyerp7Fr.0pKrFOkEdN_vAQKZ0qfD1Z96ORv2NN3VBPbtUT2U9tA_j6P5OcNAIWP2 ZoMycY1ANXm_ukdHDN1vrX6yyYDDK0g7OBDtvAiQcWizX9k7tSzx6aUuQcnkl2kBZO87VPUOXWm1 Pp8p6dch90olBm2isx6JaTjElVaFoNoYwlA5SV1sH3XkypNyrZcb.fnP69Q60FD9o5_qXGuObfq5 08atMUMKyW4FtqLoVz3ul0uarDJ6Q4UBCfyBecNNCW1eVfZhCNlCdPnzRjN2V0l.jy3hTz7uTXPC CUnxxNs_VemME0aeBp5ob8gN5LZpPgScSSzN7VoKh1clUFcbko.ONsEyyDwtQwYpGiFkMR0JIEdS gXwLbob5w..PGhzAQ0oAkfrVxQb3P1psZXxF54Unb0oJhScUZdrwzRVcIOVclsxFH1mMcfJlr0cC 2jxGlL1yn7RY6BlbhvU8FjBJxNcQzS65Zvo.T1VS_xaDv2z1NJmvyi00Yg1Q0YKMrtF.4oNQT8JO Ocl3plzWAQB22VOy0mLNq4IoU5Ev6luK0IaZyrMamu63mkCHhcQKT4oU1JlHkMr6cKrYhm_uhf5Q AQ_Gk5KJnF5smnBCirrfblF56_kRZhNxNULJcgXxFFvbTXRKEn8YvKRj95OHQXI.fbOMNTt1XRVm 3KvjPatl1qUcty9lkQFOCDsqIwpb8KG723fV2ZCMenEDEdZ2nfaLBnWnSVx9jPV5NxzFdk8NRFXy 0_DsKDLXYdAaOLLvbpys12vOx0Dxur5cKScOsirIJ7KYDCyrmMjw6fpdHUCi8XFgkNq7rXHjgvqf o.E4ePdN8KJJKiM.WhwQYi7.HFkKOBpOeK8peirb6udIr4oywU5Rk0KA5ZAzryM0yjiYdo2lxgHh u74xbIZo.nFYGE.rjQk96Jc8Oh91ZNyvT4Hb2f7klyuwtpXbsr37TtfBCmcBUs.YBPLMaaiikaM. 6PnOCRnMmTBx1ih1f2pn3yY_aDId40p.xnK3oEpaY_jkq Received: from sonic.gate.mail.ne1.yahoo.com by sonic313.consmr.mail.ne1.yahoo.com with HTTP; Thu, 5 Nov 2020 01:12:46 +0000 Received: by smtp425.mail.ne1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 0681413164917f5811eb5c547cbd5fa4; Thu, 05 Nov 2020 01:12:42 +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, rgb@redhat.com, netdev@vger.kernel.org Subject: [PATCH v22 20/23] Audit: Add new record for multiple process LSM attributes Date: Wed, 4 Nov 2020 16:49:21 -0800 Message-Id: <20201105004924.11651-21-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201105004924.11651-1-casey@schaufler-ca.com> References: <20201105004924.11651-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 Create a new audit record type to contain the subject information when there are multiple security modules that require such data. This record is linked with the same timestamp and serial number using the audit_alloc_local() mechanism. The record is produced only in cases where there is more than one security module with a process "context". In cases where this record is produced the subj= fields of other records in the audit event will be set to "subj=?". An example of the MAC_TASK_CONTEXTS (1420) record is: type=UNKNOWN[1420] msg=audit(1600880931.832:113) subj_apparmor==unconfined subj_smack=_ There will be a subj_$LSM= entry for each security module LSM that supports the secid_to_secctx and secctx_to_secid hooks. The BPF security module implements secid/secctx translation hooks, so it has to be considered to provide a secctx even though it may not actually do so. Signed-off-by: Casey Schaufler Cc: linux-audit@redhat.com Cc: paul@paul-moore.com Cc: rgb@redhat.com Cc: netdev@vger.kernel.org --- drivers/android/binder.c | 2 +- include/linux/audit.h | 24 ++++++++ include/linux/security.h | 18 +++++- include/net/netlabel.h | 3 +- include/net/scm.h | 2 +- include/net/xfrm.h | 13 ++++- include/uapi/linux/audit.h | 1 + kernel/audit.c | 61 +++++++++++++++------ kernel/audit.h | 2 + kernel/auditfilter.c | 6 +- kernel/auditsc.c | 70 +++++++++++++++++++++--- net/ipv4/ip_sockglue.c | 2 +- net/netfilter/nf_conntrack_netlink.c | 4 +- net/netfilter/nf_conntrack_standalone.c | 2 +- net/netfilter/nfnetlink_queue.c | 2 +- net/netlabel/netlabel_domainhash.c | 4 +- net/netlabel/netlabel_unlabeled.c | 24 ++++---- net/netlabel/netlabel_user.c | 16 ++++-- net/netlabel/netlabel_user.h | 6 +- net/xfrm/xfrm_policy.c | 10 ++-- net/xfrm/xfrm_state.c | 20 ++++--- security/integrity/ima/ima_api.c | 7 ++- security/integrity/integrity_audit.c | 6 +- security/security.c | 73 +++++++++++++++++++------ security/smack/smackfs.c | 3 +- 25 files changed, 281 insertions(+), 100 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index a75ffcd0270a..a4f0cd140612 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -3090,7 +3090,7 @@ static void binder_transaction(struct binder_proc *proc, size_t added_size; security_task_getsecid(proc->tsk, &blob); - ret = security_secid_to_secctx(&blob, &lsmctx); + ret = security_secid_to_secctx(&blob, &lsmctx, LSMBLOB_DISPLAY); if (ret) { return_error = BR_FAILED_REPLY; return_error_param = ret; diff --git a/include/linux/audit.h b/include/linux/audit.h index 786d065a64ef..ad1eda37166f 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -164,6 +164,8 @@ extern struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp extern __printf(2, 3) void audit_log_format(struct audit_buffer *ab, const char *fmt, ...); extern void audit_log_end(struct audit_buffer *ab); +extern void audit_log_end_local(struct audit_buffer *ab, + struct audit_context *context); extern bool audit_string_contains_control(const char *string, size_t len); extern void audit_log_n_hex(struct audit_buffer *ab, @@ -188,6 +190,7 @@ extern void audit_log_lost(const char *message); extern int audit_log_task_context(struct audit_buffer *ab); extern void audit_log_task_info(struct audit_buffer *ab); +extern void audit_log_lsm(struct audit_context *context); extern int audit_update_lsm_rules(void); @@ -226,6 +229,9 @@ void audit_log_format(struct audit_buffer *ab, const char *fmt, ...) { } static inline void audit_log_end(struct audit_buffer *ab) { } +static inline void audit_log_end_local(struct audit_buffer *ab, + struct audit_context *context) +{ } static inline void audit_log_n_hex(struct audit_buffer *ab, const unsigned char *buf, size_t len) { } @@ -252,6 +258,8 @@ static inline int audit_log_task_context(struct audit_buffer *ab) } static inline void audit_log_task_info(struct audit_buffer *ab) { } +static void audit_log_lsm(struct audit_context *context) +{ } static inline kuid_t audit_get_loginuid(struct task_struct *tsk) { @@ -291,6 +299,7 @@ extern int audit_alloc(struct task_struct *task); extern void __audit_free(struct task_struct *task); extern struct audit_context *audit_alloc_local(gfp_t gfpflags); extern void audit_free_context(struct audit_context *context); +extern void audit_free_local(struct audit_context *context); extern void __audit_syscall_entry(int major, unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3); extern void __audit_syscall_exit(int ret_success, long ret_value); @@ -392,6 +401,19 @@ static inline void audit_ptrace(struct task_struct *t) __audit_ptrace(t); } +static inline struct audit_context *audit_alloc_for_lsm(gfp_t gfp) +{ + struct audit_context *context = audit_context(); + + if (context) + return context; + + if (lsm_multiple_contexts()) + return audit_alloc_local(gfp); + + return NULL; +} + /* Private API (for audit.c only) */ extern void __audit_ipc_obj(struct kern_ipc_perm *ipcp); extern void __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, umode_t mode); @@ -566,6 +588,8 @@ extern int audit_signals; } static inline void audit_free_context(struct audit_context *context) { } +static inline void audit_free_local(struct audit_context *context) +{ } static inline int audit_alloc(struct task_struct *task) { return 0; diff --git a/include/linux/security.h b/include/linux/security.h index 20486380c176..3335991e99cb 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -181,6 +181,8 @@ struct lsmblob { #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 */ +#define LSMBLOB_DISPLAY -4 /* Use the "display" slot */ +#define LSMBLOB_FIRST -5 /* Use the default "display" slot */ /** * lsmblob_init - initialize an lsmblob structure. @@ -243,6 +245,17 @@ static inline u32 lsmblob_value(const struct lsmblob *blob) return 0; } +const char *security_lsm_slot_name(int slot); + +static inline bool lsm_multiple_contexts(void) +{ +#ifdef CONFIG_SECURITY + return security_lsm_slot_name(1) != NULL; +#else + return false; +#endif +} + /* These functions are in security/commoncap.c */ extern int cap_capable(const struct cred *cred, struct user_namespace *ns, int cap, unsigned int opts); @@ -559,7 +572,8 @@ 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, struct lsmcontext *cp); +int security_secid_to_secctx(struct lsmblob *blob, struct lsmcontext *cp, + int display); int security_secctx_to_secid(const char *secdata, u32 seclen, struct lsmblob *blob); void security_release_secctx(struct lsmcontext *cp); @@ -1385,7 +1399,7 @@ static inline int security_ismaclabel(const char *name) } static inline int security_secid_to_secctx(struct lsmblob *blob, - struct lsmcontext *cp) + struct lsmcontext *cp, int display) { return -EOPNOTSUPP; } diff --git a/include/net/netlabel.h b/include/net/netlabel.h index 73fc25b4042b..9bc1f969a25d 100644 --- a/include/net/netlabel.h +++ b/include/net/netlabel.h @@ -97,7 +97,8 @@ struct calipso_doi; /* NetLabel audit information */ struct netlbl_audit { - u32 secid; + struct audit_context *localcontext; + struct lsmblob lsmdata; kuid_t loginuid; unsigned int sessionid; }; diff --git a/include/net/scm.h b/include/net/scm.h index b77a52f93389..f4d567d4885e 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -101,7 +101,7 @@ 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, &context); + err = security_secid_to_secctx(&lb, &context, LSMBLOB_DISPLAY); if (!err) { put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, context.len, diff --git a/include/net/xfrm.h b/include/net/xfrm.h index b2a06f10b62c..bfe3ba2a5233 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -669,13 +669,22 @@ struct xfrm_spi_skb_cb { #define XFRM_SPI_SKB_CB(__skb) ((struct xfrm_spi_skb_cb *)&((__skb)->cb[0])) #ifdef CONFIG_AUDITSYSCALL -static inline struct audit_buffer *xfrm_audit_start(const char *op) +static inline struct audit_buffer *xfrm_audit_start(const char *op, + struct audit_context **lac) { + struct audit_context *context; struct audit_buffer *audit_buf = NULL; if (audit_enabled == AUDIT_OFF) return NULL; - audit_buf = audit_log_start(audit_context(), GFP_ATOMIC, + context = audit_context(); + if (lac != NULL) { + if (lsm_multiple_contexts() && context == NULL) + context = audit_alloc_local(GFP_ATOMIC); + *lac = context; + } + + audit_buf = audit_log_start(context, GFP_ATOMIC, AUDIT_MAC_IPSEC_EVENT); if (audit_buf == NULL) return NULL; diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h index cd2d8279a5e4..2a63720e56f6 100644 --- a/include/uapi/linux/audit.h +++ b/include/uapi/linux/audit.h @@ -139,6 +139,7 @@ #define AUDIT_MAC_UNLBL_STCDEL 1417 /* NetLabel: del a static label */ #define AUDIT_MAC_CALIPSO_ADD 1418 /* NetLabel: add CALIPSO DOI entry */ #define AUDIT_MAC_CALIPSO_DEL 1419 /* NetLabel: del CALIPSO DOI entry */ +#define AUDIT_MAC_TASK_CONTEXTS 1420 /* Multiple LSM contexts */ #define AUDIT_FIRST_KERN_ANOM_MSG 1700 #define AUDIT_LAST_KERN_ANOM_MSG 1799 diff --git a/kernel/audit.c b/kernel/audit.c index 4e219d1c1781..554279cb1e20 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -386,10 +386,12 @@ void audit_log_lost(const char *message) static int audit_log_config_change(char *function_name, u32 new, u32 old, int allow_changes) { + struct audit_context *context; struct audit_buffer *ab; int rc = 0; - ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_CONFIG_CHANGE); + context = audit_alloc_for_lsm(GFP_KERNEL); + ab = audit_log_start(context, GFP_KERNEL, AUDIT_CONFIG_CHANGE); if (unlikely(!ab)) return rc; audit_log_format(ab, "op=set %s=%u old=%u ", function_name, new, old); @@ -398,7 +400,7 @@ static int audit_log_config_change(char *function_name, u32 new, u32 old, if (rc) allow_changes = 0; /* Something weird, deny request */ audit_log_format(ab, " res=%d", allow_changes); - audit_log_end(ab); + audit_log_end_local(ab, context); return rc; } @@ -1072,12 +1074,6 @@ static void audit_log_common_recv_msg(struct audit_context *context, audit_log_task_context(*ab); } -static inline void audit_log_user_recv_msg(struct audit_buffer **ab, - u16 msg_type) -{ - audit_log_common_recv_msg(NULL, ab, msg_type); -} - int is_audit_feature_set(int i) { return af.features & AUDIT_FEATURE_TO_MASK(i); @@ -1349,6 +1345,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) err = audit_filter(msg_type, AUDIT_FILTER_USER); if (err == 1) { /* match or error */ + struct audit_context *lcontext; char *str = data; err = 0; @@ -1357,7 +1354,8 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) if (err) break; } - audit_log_user_recv_msg(&ab, msg_type); + lcontext = audit_alloc_for_lsm(GFP_KERNEL); + audit_log_common_recv_msg(lcontext, &ab, msg_type); if (msg_type != AUDIT_USER_TTY) { /* ensure NULL termination */ str[data_len - 1] = '\0'; @@ -1370,7 +1368,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) data_len--; audit_log_n_untrustedstring(ab, str, data_len); } - audit_log_end(ab); + audit_log_end_local(ab, lcontext); } break; case AUDIT_ADD_RULE: @@ -1443,7 +1441,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) if (lsmblob_is_set(&audit_sig_lsm)) { err = security_secid_to_secctx(&audit_sig_lsm, - &context); + &context, LSMBLOB_FIRST); if (err) return err; } @@ -1550,6 +1548,7 @@ static void audit_receive(struct sk_buff *skb) /* Log information about who is connecting to the audit multicast socket */ static void audit_log_multicast(int group, const char *op, int err) { + struct audit_context *context; const struct cred *cred; struct tty_struct *tty; char comm[sizeof(current->comm)]; @@ -1558,7 +1557,8 @@ static void audit_log_multicast(int group, const char *op, int err) if (!audit_enabled) return; - ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_EVENT_LISTENER); + context = audit_alloc_for_lsm(GFP_KERNEL); + ab = audit_log_start(context, GFP_KERNEL, AUDIT_EVENT_LISTENER); if (!ab) return; @@ -1576,7 +1576,7 @@ static void audit_log_multicast(int group, const char *op, int err) audit_log_untrustedstring(ab, get_task_comm(comm, current)); audit_log_d_path_exe(ab, current->mm); /* exe= */ audit_log_format(ab, " nl-mcgrp=%d op=%s res=%d", group, op, !err); - audit_log_end(ab); + audit_log_end_local(ab, context); } /* Run custom bind function on netlink socket group connect or bind requests. */ @@ -2135,7 +2135,19 @@ int audit_log_task_context(struct audit_buffer *ab) if (!lsmblob_is_set(&blob)) return 0; - error = security_secid_to_secctx(&blob, &context); + /* + * If there is more than one security module that has a + * subject "context" it's necessary to put the subject data + * into a separate record to maintain compatibility. + */ + if (lsm_multiple_contexts()) { + if (ab->ctx) + ab->ctx->lsm = blob; + audit_log_format(ab, " subj=?"); + return 0; + } + + error = security_secid_to_secctx(&blob, &context, LSMBLOB_FIRST); if (error) { if (error != -EINVAL) goto error_path; @@ -2271,6 +2283,7 @@ static void audit_log_set_loginuid(kuid_t koldloginuid, kuid_t kloginuid, unsigned int oldsessionid, unsigned int sessionid, int rc) { + struct audit_context *context; struct audit_buffer *ab; uid_t uid, oldloginuid, loginuid; struct tty_struct *tty; @@ -2278,7 +2291,8 @@ static void audit_log_set_loginuid(kuid_t koldloginuid, kuid_t kloginuid, if (!audit_enabled) return; - ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_LOGIN); + context = audit_alloc_for_lsm(GFP_KERNEL); + ab = audit_log_start(context, GFP_KERNEL, AUDIT_LOGIN); if (!ab) return; @@ -2293,7 +2307,7 @@ static void audit_log_set_loginuid(kuid_t koldloginuid, kuid_t kloginuid, oldloginuid, loginuid, tty ? tty_name(tty) : "(none)", oldsessionid, sessionid, !rc); audit_put_tty(tty); - audit_log_end(ab); + audit_log_end_local(ab, context); } /** @@ -2393,6 +2407,21 @@ void audit_log_end(struct audit_buffer *ab) audit_buffer_free(ab); } +/** + * audit_log_end_local - end one audit record with local context + * @ab: the audit_buffer + * @context: the local context + * + * End an audit event in the usual way, then emit an LSM context + * record if approprite. + */ +void audit_log_end_local(struct audit_buffer *ab, struct audit_context *context) +{ + audit_log_end(ab); + audit_log_lsm(context); + audit_free_local(context); +} + /** * audit_log - Log an audit record * @ctx: audit context diff --git a/kernel/audit.h b/kernel/audit.h index 3f2285e1c6e0..624828a9a7e4 100644 --- a/kernel/audit.h +++ b/kernel/audit.h @@ -131,6 +131,7 @@ struct audit_context { kgid_t gid, egid, sgid, fsgid; unsigned long personality; int arch; + struct lsmblob lsm; pid_t target_pid; kuid_t target_auid; @@ -201,6 +202,7 @@ struct audit_context { extern bool audit_ever_enabled; extern void audit_log_session_info(struct audit_buffer *ab); +extern void audit_log_lsm(struct audit_context *context); extern int auditd_test_task(struct task_struct *task); diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 9e73a7961665..2b0a6fda767d 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -1098,12 +1098,14 @@ static void audit_list_rules(int seq, struct sk_buff_head *q) /* Log rule additions and removals */ static void audit_log_rule_change(char *action, struct audit_krule *rule, int res) { + struct audit_context *context; struct audit_buffer *ab; if (!audit_enabled) return; - ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_CONFIG_CHANGE); + context = audit_alloc_for_lsm(GFP_KERNEL); + ab = audit_log_start(context, GFP_KERNEL, AUDIT_CONFIG_CHANGE); if (!ab) return; audit_log_session_info(ab); @@ -1111,7 +1113,7 @@ static void audit_log_rule_change(char *action, struct audit_krule *rule, int re audit_log_format(ab, " op=%s", action); audit_log_key(ab, rule->filterkey); audit_log_format(ab, " list=%d res=%d", rule->listnr, res); - audit_log_end(ab); + audit_log_end_local(ab, context); } /** diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 5bfee5d0812d..44b150432147 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -989,12 +989,11 @@ struct audit_context *audit_alloc_local(gfp_t gfpflags) context = audit_alloc_context(AUDIT_RECORD_CONTEXT, gfpflags); if (!context) { audit_log_lost("out of memory in audit_alloc_local"); - goto out; + return NULL; } context->serial = audit_serial(); ktime_get_coarse_real_ts64(&context->ctime); context->local = true; -out: return context; } EXPORT_SYMBOL(audit_alloc_local); @@ -1015,6 +1014,13 @@ void audit_free_context(struct audit_context *context) } EXPORT_SYMBOL(audit_free_context); +void audit_free_local(struct audit_context *context) +{ + if (context && context->local) + audit_free_context(context); +} +EXPORT_SYMBOL(audit_free_local); + static int audit_log_pid_context(struct audit_context *context, pid_t pid, kuid_t auid, kuid_t uid, unsigned int sessionid, @@ -1032,7 +1038,7 @@ 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, &lsmctx)) { + if (security_secid_to_secctx(blob, &lsmctx, LSMBLOB_FIRST)) { audit_log_format(ab, " obj=(none)"); rc = 1; } else { @@ -1277,7 +1283,8 @@ static void show_special(struct audit_context *context, int *call_panic) struct lsmblob blob; lsmblob_init(&blob, osid); - if (security_secid_to_secctx(&blob, &lsmcxt)) { + if (security_secid_to_secctx(&blob, &lsmcxt, + LSMBLOB_FIRST)) { audit_log_format(ab, " osid=%u", osid); *call_panic = 1; } else { @@ -1429,7 +1436,7 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n, struct lsmcontext lsmctx; lsmblob_init(&blob, n->osid); - if (security_secid_to_secctx(&blob, &lsmctx)) { + if (security_secid_to_secctx(&blob, &lsmctx, LSMBLOB_FIRST)) { audit_log_format(ab, " osid=%u", n->osid); if (call_panic) *call_panic = 2; @@ -1506,6 +1513,45 @@ static void audit_log_proctitle(void) audit_log_end(ab); } +void audit_log_lsm(struct audit_context *context) +{ + struct audit_buffer *ab; + struct lsmcontext lsmdata; + bool sep = false; + int error; + int i; + + if (!lsm_multiple_contexts()) + return; + + if (context == NULL) + return; + + if (!lsmblob_is_set(&context->lsm)) + return; + + ab = audit_log_start(context, GFP_ATOMIC, AUDIT_MAC_TASK_CONTEXTS); + if (!ab) + return; /* audit_panic or being filtered */ + + for (i = 0; i < LSMBLOB_ENTRIES; i++) { + if (context->lsm.secid[i] == 0) + continue; + error = security_secid_to_secctx(&context->lsm, &lsmdata, i); + if (error && error != -EINVAL) { + audit_panic("error in audit_log_lsm"); + return; + } + + audit_log_format(ab, "%ssubj_%s=%s", sep ? " " : "", + security_lsm_slot_name(i), lsmdata.context); + sep = true; + + security_release_secctx(&lsmdata); + } + audit_log_end(ab); +} + static void audit_log_exit(void) { int i, call_panic = 0; @@ -1630,6 +1676,8 @@ static void audit_log_exit(void) audit_log_proctitle(); + audit_log_lsm(context); + /* Send end of event record to help user space know we are finished */ ab = audit_log_start(context, GFP_KERNEL, AUDIT_EOE); if (ab) @@ -2635,10 +2683,12 @@ void __audit_ntp_log(const struct audit_ntp_data *ad) void __audit_log_nfcfg(const char *name, u8 af, unsigned int nentries, enum audit_nfcfgop op, gfp_t gfp) { + struct audit_context *context; struct audit_buffer *ab; char comm[sizeof(current->comm)]; - ab = audit_log_start(audit_context(), gfp, AUDIT_NETFILTER_CFG); + context = audit_alloc_for_lsm(GFP_KERNEL); + ab = audit_log_start(context, gfp, AUDIT_NETFILTER_CFG); if (!ab) return; audit_log_format(ab, "table=%s family=%u entries=%u op=%s", @@ -2648,7 +2698,7 @@ void __audit_log_nfcfg(const char *name, u8 af, unsigned int nentries, audit_log_task_context(ab); /* subj= */ audit_log_format(ab, " comm="); audit_log_untrustedstring(ab, get_task_comm(comm, current)); - audit_log_end(ab); + audit_log_end_local(ab, context); } EXPORT_SYMBOL_GPL(__audit_log_nfcfg); @@ -2683,6 +2733,7 @@ static void audit_log_task(struct audit_buffer *ab) */ void audit_core_dumps(long signr) { + struct audit_context *context; struct audit_buffer *ab; if (!audit_enabled) @@ -2691,12 +2742,13 @@ void audit_core_dumps(long signr) if (signr == SIGQUIT) /* don't care for those */ return; - ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_ANOM_ABEND); + context = audit_alloc_for_lsm(GFP_KERNEL); + ab = audit_log_start(context, GFP_KERNEL, AUDIT_ANOM_ABEND); if (unlikely(!ab)) return; audit_log_task(ab); audit_log_format(ab, " sig=%ld res=1", signr); - audit_log_end(ab); + audit_log_end_local(ab, context); } /** diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index ae073b642fa7..5c0029a3a595 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -140,7 +140,7 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) return; lsmblob_init(&lb, secid); - err = security_secid_to_secctx(&lb, &context); + err = security_secid_to_secctx(&lb, &context, LSMBLOB_DISPLAY); if (err) return; diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index e6fdcd87ab3e..b63ecc7185fc 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -339,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, &context); + ret = security_secid_to_secctx(&blob, &context, LSMBLOB_DISPLAY); if (ret) return 0; @@ -655,7 +655,7 @@ static inline int ctnetlink_secctx_size(const struct nf_conn *ct) struct lsmblob blob; struct lsmcontext context; - ret = security_secid_to_secctx(&blob, &context); + ret = security_secid_to_secctx(&blob, &context, LSMBLOB_DISPLAY); if (ret) return 0; diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index c6112960fc73..2cb3a8df7932 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -177,7 +177,7 @@ static void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) struct lsmcontext context; lsmblob_init(&blob, ct->secmark); - ret = security_secid_to_secctx(&blob, &context); + ret = security_secid_to_secctx(&blob, &context, LSMBLOB_DISPLAY); if (ret) return; diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 0d8b83d84422..f2dffeed4789 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -316,7 +316,7 @@ static void nfqnl_get_sk_secctx(struct sk_buff *skb, struct lsmcontext *context) * 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, context); + security_secid_to_secctx(&blob, context, LSMBLOB_DISPLAY); } read_unlock_bh(&skb->sk->sk_callback_lock); diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c index dc8c39f51f7d..2690a528d262 100644 --- a/net/netlabel/netlabel_domainhash.c +++ b/net/netlabel/netlabel_domainhash.c @@ -259,7 +259,7 @@ static void netlbl_domhsh_audit_add(struct netlbl_dom_map *entry, break; } audit_log_format(audit_buf, " res=%u", result == 0 ? 1 : 0); - audit_log_end(audit_buf); + audit_log_end_local(audit_buf, audit_info->localcontext); } } @@ -614,7 +614,7 @@ int netlbl_domhsh_remove_entry(struct netlbl_dom_map *entry, audit_log_format(audit_buf, " nlbl_domain=%s res=1", entry->domain ? entry->domain : "(default)"); - audit_log_end(audit_buf); + audit_log_end_local(audit_buf, audit_info->localcontext); } switch (entry->def.type) { diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index a84a265635c9..853b989da239 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -437,13 +437,14 @@ int netlbl_unlhsh_add(struct net *net, unlhsh_add_return: rcu_read_unlock(); if (audit_buf != NULL) { - if (security_secid_to_secctx(lsmblob, &context) == 0) { + if (security_secid_to_secctx(lsmblob, &context, + LSMBLOB_FIRST) == 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); - audit_log_end(audit_buf); + audit_log_end_local(audit_buf, audit_info->localcontext); } return ret_val; } @@ -492,13 +493,14 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, if (dev != NULL) dev_put(dev); if (entry != NULL && - security_secid_to_secctx(&entry->lsmblob, &context) == 0) { + security_secid_to_secctx(&entry->lsmblob, &context, + LSMBLOB_FIRST) == 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); - audit_log_end(audit_buf); + audit_log_end_local(audit_buf, audit_info->localcontext); } if (entry == NULL) @@ -552,13 +554,14 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, if (dev != NULL) dev_put(dev); if (entry != NULL && - security_secid_to_secctx(&entry->lsmblob, &context) == 0) { + security_secid_to_secctx(&entry->lsmblob, &context, + LSMBLOB_FIRST) == 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); - audit_log_end(audit_buf); + audit_log_end_local(audit_buf, audit_info->localcontext); } if (entry == NULL) @@ -741,7 +744,7 @@ static void netlbl_unlabel_acceptflg_set(u8 value, if (audit_buf != NULL) { audit_log_format(audit_buf, " unlbl_accept=%u old=%u", value, old_val); - audit_log_end(audit_buf); + audit_log_end_local(audit_buf, audit_info->localcontext); } } @@ -1122,7 +1125,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, lsmb = (struct lsmblob *)&addr6->lsmblob; } - ret_val = security_secid_to_secctx(lsmb, &context); + ret_val = security_secid_to_secctx(lsmb, &context, LSMBLOB_FIRST); if (ret_val != 0) goto list_cb_failure; ret_val = nla_put(cb_arg->skb, @@ -1521,14 +1524,11 @@ 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, &blob); - /* scaffolding until audit_info.secid is converted */ - audit_info.secid = blob.secid[0]; + security_task_getsecid(current, &audit_info.lsmdata); audit_info.loginuid = GLOBAL_ROOT_UID; audit_info.sessionid = 0; diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c index 951ba0639d20..4fb4c37cc4a7 100644 --- a/net/netlabel/netlabel_user.c +++ b/net/netlabel/netlabel_user.c @@ -83,14 +83,17 @@ int __init netlbl_netlink_init(void) struct audit_buffer *netlbl_audit_start_common(int type, struct netlbl_audit *audit_info) { + struct audit_context *audit_ctx; struct audit_buffer *audit_buf; struct lsmcontext context; - struct lsmblob blob; if (audit_enabled == AUDIT_OFF) return NULL; - audit_buf = audit_log_start(audit_context(), GFP_ATOMIC, type); + audit_ctx = audit_alloc_for_lsm(GFP_ATOMIC); + audit_info->localcontext = audit_ctx; + + audit_buf = audit_log_start(audit_ctx, GFP_ATOMIC, type); if (audit_buf == NULL) return NULL; @@ -98,12 +101,13 @@ struct audit_buffer *netlbl_audit_start_common(int type, from_kuid(&init_user_ns, audit_info->loginuid), audit_info->sessionid); - lsmblob_init(&blob, audit_info->secid); - if (audit_info->secid != 0 && - security_secid_to_secctx(&blob, &context) == 0) { + if (!lsm_multiple_contexts() && lsmblob_is_set(&audit_info->lsmdata) && + security_secid_to_secctx(&audit_info->lsmdata, &context, + LSMBLOB_FIRST) == 0) { audit_log_format(audit_buf, " subj=%s", context.context); security_release_secctx(&context); - } + } else + audit_log_format(audit_buf, " subj=?"); return audit_buf; } diff --git a/net/netlabel/netlabel_user.h b/net/netlabel/netlabel_user.h index 438b5db6c714..bd4335443b87 100644 --- a/net/netlabel/netlabel_user.h +++ b/net/netlabel/netlabel_user.h @@ -34,11 +34,7 @@ static inline void netlbl_netlink_auditinfo(struct sk_buff *skb, struct netlbl_audit *audit_info) { - struct lsmblob blob; - - security_task_getsecid(current, &blob); - /* scaffolding until secid is converted */ - audit_info->secid = blob.secid[0]; + security_task_getsecid(current, &audit_info->lsmdata); audit_info->loginuid = audit_get_loginuid(current); audit_info->sessionid = audit_get_sessionid(current); } diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index d622c2548d22..6aa4bcc08848 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -4205,30 +4205,32 @@ static void xfrm_audit_common_policyinfo(struct xfrm_policy *xp, void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, bool task_valid) { + struct audit_context *context; struct audit_buffer *audit_buf; - audit_buf = xfrm_audit_start("SPD-add"); + audit_buf = xfrm_audit_start("SPD-add", &context); if (audit_buf == NULL) return; xfrm_audit_helper_usrinfo(task_valid, audit_buf); audit_log_format(audit_buf, " res=%u", result); xfrm_audit_common_policyinfo(xp, audit_buf); - audit_log_end(audit_buf); + audit_log_end_local(audit_buf, context); } EXPORT_SYMBOL_GPL(xfrm_audit_policy_add); void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, bool task_valid) { + struct audit_context *context; struct audit_buffer *audit_buf; - audit_buf = xfrm_audit_start("SPD-delete"); + audit_buf = xfrm_audit_start("SPD-delete", &context); if (audit_buf == NULL) return; xfrm_audit_helper_usrinfo(task_valid, audit_buf); audit_log_format(audit_buf, " res=%u", result); xfrm_audit_common_policyinfo(xp, audit_buf); - audit_log_end(audit_buf); + audit_log_end_local(audit_buf, context); } EXPORT_SYMBOL_GPL(xfrm_audit_policy_delete); #endif diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index bbd4643d7e82..ffb75b23f261 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -2740,29 +2740,31 @@ static void xfrm_audit_helper_pktinfo(struct sk_buff *skb, u16 family, void xfrm_audit_state_add(struct xfrm_state *x, int result, bool task_valid) { + struct audit_context *context; struct audit_buffer *audit_buf; - audit_buf = xfrm_audit_start("SAD-add"); + audit_buf = xfrm_audit_start("SAD-add", &context); if (audit_buf == NULL) return; xfrm_audit_helper_usrinfo(task_valid, audit_buf); xfrm_audit_helper_sainfo(x, audit_buf); audit_log_format(audit_buf, " res=%u", result); - audit_log_end(audit_buf); + audit_log_end_local(audit_buf, context); } EXPORT_SYMBOL_GPL(xfrm_audit_state_add); void xfrm_audit_state_delete(struct xfrm_state *x, int result, bool task_valid) { + struct audit_context *context; struct audit_buffer *audit_buf; - audit_buf = xfrm_audit_start("SAD-delete"); + audit_buf = xfrm_audit_start("SAD-delete", &context); if (audit_buf == NULL) return; xfrm_audit_helper_usrinfo(task_valid, audit_buf); xfrm_audit_helper_sainfo(x, audit_buf); audit_log_format(audit_buf, " res=%u", result); - audit_log_end(audit_buf); + audit_log_end_local(audit_buf, context); } EXPORT_SYMBOL_GPL(xfrm_audit_state_delete); @@ -2772,7 +2774,7 @@ void xfrm_audit_state_replay_overflow(struct xfrm_state *x, struct audit_buffer *audit_buf; u32 spi; - audit_buf = xfrm_audit_start("SA-replay-overflow"); + audit_buf = xfrm_audit_start("SA-replay-overflow", NULL); if (audit_buf == NULL) return; xfrm_audit_helper_pktinfo(skb, x->props.family, audit_buf); @@ -2790,7 +2792,7 @@ void xfrm_audit_state_replay(struct xfrm_state *x, struct audit_buffer *audit_buf; u32 spi; - audit_buf = xfrm_audit_start("SA-replayed-pkt"); + audit_buf = xfrm_audit_start("SA-replayed-pkt", NULL); if (audit_buf == NULL) return; xfrm_audit_helper_pktinfo(skb, x->props.family, audit_buf); @@ -2805,7 +2807,7 @@ void xfrm_audit_state_notfound_simple(struct sk_buff *skb, u16 family) { struct audit_buffer *audit_buf; - audit_buf = xfrm_audit_start("SA-notfound"); + audit_buf = xfrm_audit_start("SA-notfound", NULL); if (audit_buf == NULL) return; xfrm_audit_helper_pktinfo(skb, family, audit_buf); @@ -2819,7 +2821,7 @@ void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family, struct audit_buffer *audit_buf; u32 spi; - audit_buf = xfrm_audit_start("SA-notfound"); + audit_buf = xfrm_audit_start("SA-notfound", NULL); if (audit_buf == NULL) return; xfrm_audit_helper_pktinfo(skb, family, audit_buf); @@ -2837,7 +2839,7 @@ void xfrm_audit_state_icvfail(struct xfrm_state *x, __be32 net_spi; __be32 net_seq; - audit_buf = xfrm_audit_start("SA-icv-failure"); + audit_buf = xfrm_audit_start("SA-icv-failure", NULL); if (audit_buf == NULL) return; xfrm_audit_helper_pktinfo(skb, x->props.family, audit_buf); diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c index e83fa1c32843..8b6f8402703d 100644 --- a/security/integrity/ima/ima_api.c +++ b/security/integrity/ima/ima_api.c @@ -340,6 +340,7 @@ void ima_store_measurement(struct integrity_iint_cache *iint, void ima_audit_measurement(struct integrity_iint_cache *iint, const unsigned char *filename) { + struct audit_context *context; struct audit_buffer *ab; char *hash; const char *algo_name = hash_algo_name[iint->ima_hash->algo]; @@ -356,8 +357,8 @@ void ima_audit_measurement(struct integrity_iint_cache *iint, hex_byte_pack(hash + (i * 2), iint->ima_hash->digest[i]); hash[i * 2] = '\0'; - ab = audit_log_start(audit_context(), GFP_KERNEL, - AUDIT_INTEGRITY_RULE); + context = audit_alloc_for_lsm(GFP_KERNEL); + ab = audit_log_start(context, GFP_KERNEL, AUDIT_INTEGRITY_RULE); if (!ab) goto out; @@ -366,7 +367,7 @@ void ima_audit_measurement(struct integrity_iint_cache *iint, audit_log_format(ab, " hash=\"%s:%s\"", algo_name, hash); audit_log_task_info(ab); - audit_log_end(ab); + audit_log_end_local(ab, context); iint->flags |= IMA_AUDITED; out: diff --git a/security/integrity/integrity_audit.c b/security/integrity/integrity_audit.c index 29220056207f..b38163c43659 100644 --- a/security/integrity/integrity_audit.c +++ b/security/integrity/integrity_audit.c @@ -38,13 +38,15 @@ void integrity_audit_message(int audit_msgno, struct inode *inode, const char *cause, int result, int audit_info, int errno) { + struct audit_context *context; struct audit_buffer *ab; char name[TASK_COMM_LEN]; if (!integrity_audit_info && audit_info == 1) /* Skip info messages */ return; - ab = audit_log_start(audit_context(), GFP_KERNEL, audit_msgno); + context = audit_alloc_for_lsm(GFP_KERNEL); + ab = audit_log_start(context, GFP_KERNEL, audit_msgno); audit_log_format(ab, "pid=%d uid=%u auid=%u ses=%u", task_pid_nr(current), from_kuid(&init_user_ns, current_uid()), @@ -63,5 +65,5 @@ void integrity_audit_message(int audit_msgno, struct inode *inode, audit_log_format(ab, " ino=%lu", inode->i_ino); } audit_log_format(ab, " res=%d errno=%d", !result, errno); - audit_log_end(ab); + audit_log_end_local(ab, context); } diff --git a/security/security.c b/security/security.c index c6b0f854c4a3..1a78f7bb808b 100644 --- a/security/security.c +++ b/security/security.c @@ -483,7 +483,31 @@ static int lsm_append(const char *new, char **result) * Pointers to the LSM id structures for local use. */ static int lsm_slot __lsm_ro_after_init; -static struct lsm_id *lsm_slotlist[LSMBLOB_ENTRIES]; +static struct lsm_id *lsm_slotlist[LSMBLOB_ENTRIES] __lsm_ro_after_init; + +/** + * security_lsm_slot_name - Get the name of the security module in a slot + * @slot: index into the "display" slot list. + * + * Provide the name of the security module associated with + * a display slot. + * + * If @slot is LSMBLOB_INVALID return the value + * for slot 0 if it has been set, otherwise NULL. + * + * Returns a pointer to the name string or NULL. + */ +const char *security_lsm_slot_name(int slot) +{ + if (slot == LSMBLOB_INVALID) + slot = 0; + else if (slot >= LSMBLOB_ENTRIES || slot < 0) + return NULL; + + if (lsm_slotlist[slot] == NULL) + return NULL; + return lsm_slotlist[slot]->lsm; +} /** * security_add_hooks - Add a modules hooks to the hook lists. @@ -2193,7 +2217,7 @@ int security_setprocattr(const char *lsm, const char *name, void *value, hlist_for_each_entry(hp, &security_hook_heads.setprocattr, list) { rc = hp->hook.setprocattr(name, value, size); - if (rc < 0) + if (rc < 0 && rc != -EINVAL) return rc; } @@ -2238,13 +2262,32 @@ int security_ismaclabel(const char *name) } EXPORT_SYMBOL(security_ismaclabel); -int security_secid_to_secctx(struct lsmblob *blob, struct lsmcontext *cp) +int security_secid_to_secctx(struct lsmblob *blob, struct lsmcontext *cp, + int display) { struct security_hook_list *hp; - int display = lsm_task_display(current); memset(cp, 0, sizeof(*cp)); + /* + * display either is the slot number use for formatting + * or an instruction on which relative slot to use. + */ + if (display == LSMBLOB_DISPLAY) + display = lsm_task_display(current); + else if (display == LSMBLOB_FIRST) + display = LSMBLOB_INVALID; + else if (display < 0) { + WARN_ONCE(true, + "LSM: %s unknown display\n", __func__); + display = LSMBLOB_INVALID; + } else if (display >= lsm_slot) { + WARN_ONCE(true, + "LSM: %s invalid display\n", __func__); + display = LSMBLOB_INVALID; + } + + 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; @@ -2274,7 +2317,7 @@ int security_secctx_to_secid(const char *secdata, u32 seclen, return hp->hook.secctx_to_secid(secdata, seclen, &blob->secid[hp->lsmid->slot]); } - return 0; + return -EOPNOTSUPP; } EXPORT_SYMBOL(security_secctx_to_secid); @@ -2767,23 +2810,17 @@ int security_key_getsecurity(struct key *key, char **_buffer) int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule) { struct security_hook_list *hp; - bool one_is_good = false; - int rc = 0; - int trc; + int display = lsm_task_display(current); 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 (display != LSMBLOB_INVALID && display != hp->lsmid->slot) + continue; + return hp->hook.audit_rule_init(field, op, rulestr, + &lsmrule[hp->lsmid->slot]); } - if (one_is_good) - return 0; - return rc; + return 0; } int security_audit_rule_known(struct audit_krule *krule) @@ -2815,6 +2852,8 @@ int security_audit_rule_match(struct lsmblob *blob, u32 field, u32 op, continue; if (lsmrule[hp->lsmid->slot] == NULL) continue; + if (lsmrule[hp->lsmid->slot] == NULL) + continue; rc = hp->hook.audit_rule_match(blob->secid[hp->lsmid->slot], field, op, &lsmrule[hp->lsmid->slot]); diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index 139768a13d11..17391258e896 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c @@ -185,7 +185,8 @@ static void smk_netlabel_audit_set(struct netlbl_audit *nap) nap->loginuid = audit_get_loginuid(current); nap->sessionid = audit_get_sessionid(current); - nap->secid = skp->smk_secid; + lsmblob_init(&nap->lsmdata, 0); + nap->lsmdata.secid[smack_lsmid.slot] = skp->smk_secid; } /*