From patchwork Fri Nov 20 20:14:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11922089 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=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,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 1CFB2C63777 for ; Fri, 20 Nov 2020 20:17:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AF0A424073 for ; Fri, 20 Nov 2020 20:17:34 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="Gp5PENmu" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730112AbgKTURe (ORCPT ); Fri, 20 Nov 2020 15:17:34 -0500 Received: from sonic317-38.consmr.mail.ne1.yahoo.com ([66.163.184.49]:41298 "EHLO sonic317-38.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730074AbgKTURe (ORCPT ); Fri, 20 Nov 2020 15:17:34 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1605903451; bh=ZJTbA2ATr3o7UlQ7868l+5cAPYnxaaFHObbRw6NEuQA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=Gp5PENmu8/Ng32JTeJnjPRLGMlgGsTGHH/ep4pFSAoH4fy5pfpHBYhN+unbkO6DzX4Fm8kEV93eGYbySR7OaiKI4ED7AF+ME+w0Tx6nIgeKMGMPLYC/gsTVeL7UsnWiJ3Fy/0f4cnxScnI1j0W8f+p0Q3X9IcGZb4sxnmaHUTB+UVpxKATLZQqfVvzezyjpKkTEMDflEF91cBCKk/9/vWpI6n35y5rWFfw7RQIeHFKg8qXAjQ95zuU3+RY7sh3d66ZXG46wLLYYT76NAI+Y8m0Lm2O3JpSoulHy3YOeZttWa1ogHDOqbN1tdThzjSf9fbPjbqxpZ0dbHFi8xnjj/ag== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1605903451; bh=cw02Dh17Au0TCo4T8leamFz4VU7WUzEfllatvdIDdoD=; h=From:To:Subject:Date:From:Subject; b=l4pC0vOVWwqH6yRetiKNQ3jQiegChCNe047CJ9J1Ei7Erf1pUrCRDwP5ZgaT7KWZMQZ+pvrxdGWemB7QvgAMRYbdCH7EqFF0zJwSWCI13Kj5o7iuLQh0XzYAvjRG/XxzKxYPwK5cZWqFFbm9rC+Z2H++R6S3hdeOr1Fj2xdhFjkh0gIVDVFb/KHMNp8Yr1Sq+omBWWx7m2RBwcru/HktAvuW/96c+qNnRR2K5UuyDz/p5BZGtfNawYYGAEOqSzerU5i7Ka/7WuyUrmpxrIf+L/OptIU6/XJIFv6uPpoAX88JzQBijnVS17bpCOl8awVyAEbbF5wSNoepqr2BnTcQTg== X-YMail-OSG: tMu0wBsVM1n6CE.s6lGw.f.HgZE19PZI5.sF.dQV1NWpn4EN7DKP69UdWtcb8o1 mJB3sLY9_KC7uSJihUfDV1dn1zpMkf7jRtptT6V4cNOQJMFaiQw9l1VHj1XI2AYp20Mmojw8A6EK 5LET0BW2vxAQz9Phja0mCVLZhOsXztckNrldh_DTgqIXVfnKsp4U4v3laU3cX4OdPHh_KvaFd5F4 Hmer_Vq2dop2heC4QfrzRpcXM0Ojo3IgkXNjs8evy.fNPiC0grclLiKaxtawc.X9G67bFhQkXnQU hKCiK2Qd_JfmzpDDhtSe6x2wE_hotIEelznIU3n7pOi3zVmBgUV2J.8Xzs9Y6SpGmWTWGOT9O4KH Lt9SqYsB0GpkwAV6X6vD9Oa2C01xYctfqStg39zXHcYf2dufRC1LjWD3qYrnLdF8mS940QzKa2tm WO313DQ.NrKfaV304AsFAIodi3rfnKoLMXIoq39J_NhlMcAghaNNA8hqcFsr.ivaF0pHO3TzwMy7 sTqqFrD0bZKoev6pY5NtPLDR6p52gsM4.NDnfuKvdbINVa5Qh8dSoz_3acb7Jydu4RvBGREH4w8v 3_ThGm5Z59DkFhOh_JoulgaYFcd6tcgeglz4_e0XW8sdiWNq2je2suqj0mTylPZud1Z4sCyZdLQY I85_1bmB9h4Kh1TXyXdlVM84Al2kuRnEOsAQBk846NwAANuyrp.C87XYrUT8ZnZhuVoEbUMyx7LL GMP8XOdAUEcaErNtonCr_OHe02ociXLAJ5_lbt4GXL89JsZivyEf8IuUwyMF4.3yhStuIjUvo1F5 8r0WzW8ubMYJ.H4bIirZHgoOIlv_9_7Lkdbptub_QFJ6IPl5jgNg7C4L7AHz8fhDGhrTZIlpwk7P G8EcEWxJSDHTp1SbVpOW_AUugRqjJkHcY5Un1J22WqBDClr5iWK8sHfon41LwqqN6SnBAvgXjrkk w3m.u6wrrWumuFd1bqaa6Bx5pKlMYXFBqMQUrsooJIqGFCKubZImHwoeDX60TEDNzjf2Vvt4XKk8 ZmJjyZ3kyW09FRPpd.nLpstedzpGpvsxKxIe4Hr13yRHRfSH2YB4JAQOOhBmfbwhhvOIW4swU2Bx PQSvbSWu6iaS1r81b.J8Q79f9X.Q8WZ8e.KUNuKAl8p2Yjl0ezsLM3aPVcsOV9ESslrD6VfxL9nI ypDDJvd8Zh4FbNJPJ5uGo5tXvGS5z8L72Q.ZHub2MZjffPaw35rLNTD4bytPRtjytLChtbx3vsWO oytF5n4dSs6a6efz3teRnW2Y6HQr7bqqW0eu3Ebha4DX6BgsCOOz7QH1zAcXn.wjpCvOBH69JWUj 0pEnLyKo3kelOYjWmW5NGJFWa5Bo271IuyDcLU_WnzwPF5gGMy0awG6r_vo9Z8Z4kSPTv8fLg9.N 3lWPMHZ2Q0IwuF8fVX5CfbRMkM1JXQy7.Cbh89M6RXr.Mr7PRnH5xS9cT9_1QOBIOZneTHaV7ViM CFmHAjNlhUhA1O.gtAjSF4PZyZPtuBS5kqTTpiToAmi5Zg1_QDDvpUIBJr.LZ1OabTUl3twmRbiN 284dphHlDfzM2hVNi.WukeJ2crKMR0uOAcWkwSBr.Icp8xI3.YwIDHA7HhU34KuTfJNX44uRdgOe BqmSZPRCkloiolmyVXcNV3BGwclqaJJJZyprWAjB04Cxh7MAuHFmnxAelcQQkqcAkzxyEeTQQyUy H9p.cWomTbogozrMMFAfA0.YD9SUSp38fOXdQ5gREcnb842L0BcHDj7wtHqpznIemv0xDsgE1E4t j4O7ROjMnx2wjuwP5GTup.GfIO26TJ5dhrpesgbUyewDy8Ksl98P96TpseewHUl4A74.UoKsUmn0 wWYUU3vhR7UWAjstN8XMFByOx5PD8agK43MNim6tpJnS96zHygP4hEvMsER8ztHy4sKdkxtw2fSU ellaN_g_bl2ftgNAJvXhnAGHVZpYyjCZiuZREcPltrtWt7XCIW.xEN002T.Is20fy4M29nBaA561 8I43bBLvNlM1Z7kvus0XIup8_0PXiXVsP.vSHArA3SMgV82ZoXxlTg1rvgmDZbSrDnsluy.vkdG0 KzoZ9Fw8ve2spjph7fIsjaETlTGCAxr96KraE0xjfOYiq_yRz52YBbEHGCKj_3bOmSySaoMFlz_R xi6UIW1khTHNkUs2_ukpNUEEMjuKcCX3AAzW5KIGmGAGaM6w160Axs2DtP3JPHYqnz44tWR34IvC TqbHFBz.A.jSBmtAtbKgFc8R_LpiNb.cihOZVBWGb4.vukxt.QLJwB042aQ33Pk1VcBtVgEMEiXb YKSmmG2yK.jpmnmwlGewepwjj3jpkFn7UczLJ_Glyq7M90FigqUGruNSAjPx50vHDvw8D4okhA29 adVMemSrr.UQ_schygaDKcgJXQN59dRCv2lcGjjDJ7TBv3SzlztL6DfI4909aKGa_2D8ykTF9q5m YiO5jD2uqF7MeWrk7mvisjtr5Zk1vtZolMFyXEa2ofSMLzvrHB8SdunxVBUyrwYIoq7ZG_gaQzxx eYrbxZWTFchGG9IDJU7Jecw.ZAhLb9Ba9SprkClRw6nTqdCYaXLBra2BPa1SJChT28g4D8a2TjAU kIQGMrZxY8gXK0aqYJfJGAfzf6LIP5aMKqAFGEctm8MuH5FrDngqyjulbVAKXhA2QeeUyUBOEewD JCLVgltAvOO4cwMEDHKaH0.cOvuUx02FegoSzfKHuJY83wmZMoprlWBPsI..1D7omOxlFArNl6JG fNk0mvKAqmMP1fpsVCpdXm_KLCutJn19ErTLRz.2mriZDPlau548BU06Yu2n_WNWwIBtGPFg9D5w v0k4glTvh9jDMF0yabBhDvyahGLVZG7S0ntb81exHBGQnxXUYoKAIiLYOgOD0PyJMLyQq1Jk087W owHHa3Czh5q7Ieuy_vVOAbPWP21qHNVo6tGP5A9Bhlsm46MJDZ6Kzw5BedFI_y3TDy80MsJ6gyEJ rkGYBL0b246dFVZ6KZh_U.9FqcFnlJmilbuIfP8MX_uyq4UES8A9TdHOghI3RHERAU17Mf7owUmR 7mLx.uUlTq5EqMfICBscih8N2WVLUI20tUf6uAkuWyrVvvlDX_U_zNISADfCL_rzt4mwKTyeSv4U F74lYe38VfpCVYxqAa9xgYu8PElZ7_KMWv5NgxF2MG3MeofQaREy7445sGdpgJJF3NRtAMjn.a7o 9G__Vpuh_xMJ0pdKmANuiChB6gunsEpV2fdkFe.PokskYsoRhT1CnqTJrOdVxuVqI5_H05MaVjgT BQrj_Va8vQKgZQCD0o_Xa5dM3gsivbdwG9Lu4v2Ymm2aVgmp2Uqqvv.bTqKvDTQILWZeLwPJSBxT e7Jpu5Uma5pzUoBfqnkOAdUukcy51euHy3W0SsglvnV.ZpD_6CpxtnTH_yOCiovtGc4WzkRXRMaU - Received: from sonic.gate.mail.ne1.yahoo.com by sonic317.consmr.mail.ne1.yahoo.com with HTTP; Fri, 20 Nov 2020 20:17:31 +0000 Received: by smtp419.mail.gq1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID a24adb9f0baf1f5cb0e3f81d114c3341; Fri, 20 Nov 2020 20:17:28 +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 v23 02/23] LSM: Create and manage the lsmblob data structure. Date: Fri, 20 Nov 2020 12:14:46 -0800 Message-Id: <20201120201507.11993-3-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201120201507.11993-1-casey@schaufler-ca.com> References: <20201120201507.11993-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: Cc: linux-audit@redhat.com Cc: linux-security-module@vger.kernel.org Cc: selinux@vger.kernel.org --- 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 Fri Nov 20 20:14:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11922141 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=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,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 BAD90C63798 for ; Fri, 20 Nov 2020 20:21:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7D3F024101 for ; Fri, 20 Nov 2020 20:21:16 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="qrxjVgWA" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730577AbgKTUU5 (ORCPT ); Fri, 20 Nov 2020 15:20:57 -0500 Received: from sonic302-28.consmr.mail.ne1.yahoo.com ([66.163.186.154]:38157 "EHLO sonic302-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729468AbgKTUUy (ORCPT ); Fri, 20 Nov 2020 15:20:54 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1605903652; bh=hdPFlMt1N6KYJ82qhjneXwVGFiiOSNjYsJurXTcc6o0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=qrxjVgWAuUZGo/WztqbzkzRhawd/CvTtvfRolzPkT/CizI2eqjyhXRAnIjYdvyuG/hBIC0p7j0B8MT5bLIKdT9gz0iChs56+RMFnj2jES/j8nRyEcPe6Jf5dvg3sMXEwPsaU4WBwlbkmyAFdSHUWTRBIWAnO4XCcdtLJgt/vI0rZrwJ21IGOuGdFS9suHjPqoTmKFVKmyEWbB73LqD+Mf3mhQ90hJFWxs4T0DIj/Z4HdP7e/sHBYSVI67cHGRyJOMx7QII+7zyQUH8KQv5jygXMPYnFmmMGlotSee66QHXyKwxFJjqyHOXqBm7qBHtXrP79FwGFMwwD+k0z/MY+78g== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1605903652; bh=8jstPlIFnSza0RcoZk+GnjlrXJFwae2QHoJX0Q81QQq=; h=From:To:Subject:Date:From:Subject; b=sAZ4ZyM4SVrN+ASxuFQChzHMweto8uzoS8mxy2J1oPkibA9sQfCiCfMsHGm3y8YMeOYuQZhMH/HbPI5ro94bf2iTGxmIa+hEMCD+2J/chtbUUMWvlItZ+P+bHvklZNTy/i66GORKV7F8JKzidnBKquhc6/uNrJrHnoUSMsnpdDOHkkAeIE0MMZRfnQFll8fqY/dBZnXT5NEFBUznd0vQ32SIkE84kF02rvFLSFssjF0B0tqzYZt2fPKBtOALRH9gbah/alVQg0dSbsU7oN5rkuUi0hrCwaGRhjFJr2zOzxdyZXRmYqzFyoM0hOhX+zyjGE2AtxyucxRrgCAqR1hSCw== X-YMail-OSG: FlhGOYwVM1mkPTuuqhJE1zZ9cdU13t3f.5STFVuVYBUL6tu0zsFmJlpBoU2oN7q wY6ND2AknL.MkG5CIkoOQlbmNL07K5xLHApQc9cbIeMMWEheIu09AEFF3iWOohzRzDhaPmq7vkip iIW831QVi3tJ4R6ZKJXy99GjdQ73H2_RtjnFVUmI0BiyyH8zCGqCt9vM_AT72kkLhXE75Jbo07VB MuxrzHYT8HUhp2qDoPN69QajGXLUoL8Ge8EENcq6h0GENUxk9_XAqd130Et7Fm_zKXGDPaFRUJuO vbLHOZfFLDFnzSo9DoUp2a9W9qgWy8c5gRO3K3uQ4kh87aBuARIJGrtGdXHWiZYn_uIAn4StbtBB ANxV2LyZEfx_rc9PD400ETsQ8rEsFNoH3Gju5BCFIEidcKz8zKMntShm9jezgLzMtK1CYHdXliSD SHDudQEDxEFqes5z84bv0I4.OLljHMcYc5iwUqFlJt5Dfa3YnTIlGEIcnhitfx1WjdrNtto3jcxf QR4M0fx3gbu3LESQ0uA2XSYdJhyQB75AV_eYW05RsvKAXTDcL0QZeAtWy.Ubjqy_czJp87YMkQUD nFiGGNK2742o2fEKt5RISVjuEZcbrFVncoko2ACr3UrZhYykgiczVi4ahezf0V3ziw_9yhYL_hnF z1y2buy6QCn8Ic8BvwXYOlU8KXmgBNqN4CPxz3.tp4DAlLADAUWYGfDtvgdm8uJNE4v_w2RWAWI4 PNy8Nf4TFZZ6THHetddCfpQgLIv9hNiHGgQylydzvAtSZiAJJWFhK0bfxTaBWoopUiTIOkGx8yDF i3u7oR.wCsMVdl0g6iGdbjFg2uFJBF5BbtjKwrF_vI1IGSrrDDLKIj6iR81W7hFOVtZN_yQH3oWI s.ah0cIyPhjAtWTWBl0g80Ao8VO8pmSyK2xbrI_CHEi3qVoaT.iNYty7bgHgIRzYTQqx_0CGrOMy t0Gg.h0HP9vh0zUmuVCEl3O7jAzl.20iMJjrg7LtpZv3GRJqjwwOtQLHgEUhkdHdGfbo67MeVV8l DxV1fOGi65UzXMMRyeEwQmSVB_kDj.idC1TNDa5nnw34FEVyMErl7nQQbUtHXyr92q1go6eUOH5t Rz5bRg.Sz7fxWsI4ku0bbtaXaNcG8_LP6Q90nQVLwaH5hx0qYc8QejVDwTle7fF9wF_m.sSojVaC 6X1B.uDu4kTuxMYHAAWaV.iN57wc9Me9La6oGl3yMLyW1dLFzDPdKSJg5qmE3Oahq1fFCfbeANFy msUjt59401VWdC5FhThpcv62RyYIwZU0opDc641g4a_PElka0bjq3vFL_kFAGXTdAfLs9PS6qTYY Ommbb2BH4fVlDte29RVUJftZomM8VTEJ4vl5y0Aj54DX2hG6bYqiSloFCcZWbU0PAhFlraeWM6Cu hF210BjIZB1lp4.wyEVIDRA0ql8gdKdLelmDxp.OM6urzWeAbZdEg7ty4unLjV.vRYIb1kGdd9wa glm1HW4VpYcUukqzU7a34B4g2ZyLWHd6dwf3ERNilWnoGlnxq9SklG3ctQOypsxOvp6SkLdoiomA ecw6kkx2rOFC.bz8RMJ6UuiE.jw5serjyTbaEAxdO88Yzku4z1nFfWivtRs.L7d0YlowKa3ijSCT xaN8mSlBRWdfgtm6OmUu7OG5yxF81Y1qc_Dv2GXptfEi5X_T8zTZrQ9AjRxTF_.RYgq524gh4og7 2fp2NCof.EA1y..qkBNxYRF1t11QXe4_8Kjo2vZKYLblp6izQA9eBeS_3lHibAB.dPPIfFB4GNhK GDOj1O30SsxowDq9rOrSRcVWT8lAOCMPSHQ6eWMYUV.vi0buKFS4kHPf21_ZRWV31jDH9ke11ZaZ V.IdplsNDDN8ehEm2VA0uG5BxanHlXw1Jblz27.hQNl0KzxXnHXf0CgrMauuxNf4HPfHuR_TNvxL pWGBveXmcirn5GoO0aHgLuJ4i2FzMngOQg585sVt61K5DbYSnwPf1sH0AfccQH.ylUCIDRJv7fRI MHYISMidl1_0dU9r03CT_WnWqFQLbGbyVfhoOiiCJexF8IYF_JbYjIvZHs8tFppXw7ibLwvtwtat doWMcy.9xzDePtiUHEBhRQpmZsLgcXm1IcjPAuKKzazWm2XIW2VOLSZffdi.4RJF4ZkhaJ2Q6c_L GEfbyar_u7vHWAOk0AhxZxqxcePbid7Xo6uHLZS_hm6KYlJMD8RtsZQ5W_F2hU89ozkOsZuBZ0Q6 u77tiIlcmlfCXR34MiLl9qgll8TS6.sUMSvCSGd2pn8DQokptXLrSwR9AofMr97M5PjVjF7nAy24 mfqRGDU2uMI1d5dvoNMLVWb_0h1MkLne.wl0npqdalBmwBvKew4wz5crm0R6pLCQUwpedzwQJe1Z JNm1hp5qdVLlAldIIR7hl.OfNj8qnMMtRyaFbwxmI7sM.BSZYRWGtY6RFTXURRq0KaPUCjOU9ylL JQLyBFcab3_mdnED6rVuD4y.eOLp4IckX6q1WqFoWZPmX7.rOM4pbaMa03MXxzQYhkl8rDb96OP6 qOUM8zzNKX8.zAGlvdvo6KXzy63XOPIZTJcT2Izn4yMv5L76elYcFazQLPV4kxctPE8xX4Mj5D_r wtw9Y4nUb9dsMeNCOIt0JrKXCFmtaCIIYW7.8kdZTMx43Nh6CwsSQ0I2tHu5zIdXgvMpzfxd5TYM AxzTkhqmOIZeyQh9cUgGCxM8HqEPKt7PM8mwnrUdy8h1DwsDX_mCqeI.TikAYTtEGaH5q1jMsbfR OrzxhNvmZABWK6tBDfwo1.TREQa3DHG7.A0Nazsm_EoXLhhllHZ48SSl87BNxvs7o0dkfFNNxPb5 4pHP2nRP6.kOcJUa2KF3ovE1HhvlDZUthYgLgyuQKmUygqgB_tDVZIC_IomG6mr7hmElCXgkpsgz NzbXmbGTtkzgvKLR.cqa1RIp7V8noz90PYCWaME1qU8aUAHWhfMnfUfuEoqaQ5oqvIIywKtf.rQK 68S.NN0_77ef63xqmqj6KyiaF67q2OYCu4fvBg_8_APrTDtl5iIOE6w.uhV_SPNX48.LLRBgSENC ZZPrRECwr3Lv3fO45cuSTNQ9R19a7sYM_U.9HOL08eedUA06I_XK7KF67A3TsKH.nm6B75_HRShV xiqcWayJ.IYjrEc297UX3wAswWm0vouprCcZsBKt5iiKbLug9MxKHi5_QIQjd254xGBG.uAsrS1L eilTkAvvHVAazBiBJcjIaiCuqOgmrfSDDdLyZ7nScPt.wGLyLW8AP4SQ1RZNPL4Dk3Xxymts.T5m CxeD4N_1xPiCL4G6pfUDO8GUGEXedWk1vZ1ZSV5zjaoNi4AbAMLgLR5tQunw8Lr_quXRuxN8g9AG 496DKRjfNp7eq24hxmrBDoLc2kudnEsFA8ghz3DzHrOOlbVfu3BmXW5lo1AxOD8KtBa6b64sjfZT Eq2I69dknpCrsoQEud72SuU6IwBOwHBhjm_BbItR_XgnbZGdSWBmiWn1FJVKuVoFuV5uHjJ3A.4N 9gQ8Jz_fr4hVU82.SdSji Received: from sonic.gate.mail.ne1.yahoo.com by sonic302.consmr.mail.ne1.yahoo.com with HTTP; Fri, 20 Nov 2020 20:20:52 +0000 Received: by smtp417.mail.gq1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 3fea8d9feb3cc20fa2b4afa5206cbedf; Fri, 20 Nov 2020 20:20:46 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, netfilter-devel@vger.kernel.org Subject: [PATCH v23 05/23] LSM: Use lsmblob in security_secctx_to_secid Date: Fri, 20 Nov 2020 12:14:49 -0800 Message-Id: <20201120201507.11993-6-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201120201507.11993-1-casey@schaufler-ca.com> References: <20201120201507.11993-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 Cc: netfilter-devel@vger.kernel.org To: Pablo Neira Ayuso --- 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 fc55c9116da0..3b7a3e0ae8af 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 Fri Nov 20 20:14:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11922143 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=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,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 62E74C2D0E4 for ; Fri, 20 Nov 2020 20:22:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id F12B024124 for ; Fri, 20 Nov 2020 20:22:17 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="RIUMXi0j" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730625AbgKTUV6 (ORCPT ); Fri, 20 Nov 2020 15:21:58 -0500 Received: from sonic302-28.consmr.mail.ne1.yahoo.com ([66.163.186.154]:39257 "EHLO sonic302-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730591AbgKTUV5 (ORCPT ); Fri, 20 Nov 2020 15:21:57 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1605903713; bh=9KYvMBO0f3QJAkGUkYTSB7tT/AsRWsETYIOQ/jkgV7A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=RIUMXi0jtNWgALJlhitgaJOz+UmuyQu2YNN5dM3GmBS6DTCMHMYCMPpTXO6Nar2FhaJoUXGvYGh5N+1+JNKWaaSbc+RhL4X1uP3RpUFa3lY1ApCjI0LIeYrPeM4bNM0NYK2V04Xo0V+F0KooHpYomNjdPwKHOfqxkoKaTBbmIo5kuBCOHBO0UbOgI2wnJ06Xyu5NPoIfHFwOf77f+7Q7Gr4VZVJwPtvIBWaUfcADEaRZgj78s3Pz/TUItvLic1+ITt+j91R0iLZvj7+jouh8Yzx6hD1qfFu8bBh03ym6CESwaIHCNLxaUJA4p72d3kyhTHsaUm0p/aiIgj6FRKuAAA== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1605903713; bh=lFg+SIWAaOvQAbVmA8auJ1GwibrjS679QpVZg5eTeiZ=; h=From:To:Subject:Date:From:Subject; b=lr6mFlbCIxQWgbHcsybwyC0EpgSvJbn7jhLEDI1LyiXK9SGP8RsbKv0mxWQXPO5+oLHmba472cT9oLroHoK76guBqtWYuvukDwf0gydR1aXnffpA9BbMFbzAhzbnFvFn9NLr7VH9kUJVI70F7plOWGZnmD8F5sdBYJ9x0KEa62zjqXdLG0wcFZV6U+oBmeYifdCHT2CnPVA7dKiO5eXQDXUZsSUOZVIxka7wMFKtZx1o7kSP7sOF1RIOJzzuObX1KvS5cUifCNb3Bwb8PMxL8xVP4ZnlsgUA99QAldkiDyBGK+Z+xOGfe9jXHMc5XQrym1cP0LMXwKr817S3losjog== X-YMail-OSG: EadB0l0VM1muBY1RoRD_5Q8zv.8hRIGh_kn51W4eyeNTn20Ro3K4GixmeP3squO eet90UoRVnmwG3VElsa0D8j_Qzt5cWIeldHv9Aa9xlfVdkmuzs8ExOyI1i8FN6KiFdsNBicoVHkv Mg3h8Tza7qTUCAkHz6K6fZehYhA_03JGRgwj2lmQzOr9CWxgPHZbrJqSdXv94L.QhUgLdvRa.LIo T57m6fna3LyfKGkfE9FpNUsyeKFNIEH_hCZSydm5dyPIRojGJHvud5F4OEqb699TRqcwWYAK83gZ Gm3b7EE4qkBifm6bKHFw2uUvGCNDnk2J44kZQp.z4AjPRdn0T1L4tbwGLIw9ZPsugmbpwHUl0CZW n1J1oxkfz5NDGq6fA9fDRlu8P39fC.FX_ju._F4VbZuw5UNJpOhHtGOPzx0By3l2rANgDkvWHL9V UaSZsAsSfmrZy5ng6Gecxy.D_lxKAvcmylG40UlncyvsenVwBfSRBv2_H7ZavqHPKwzVeYisRatK ZQrOGG_n.9FLDfDKvrJzX94U6m0qSQb1zTHvjt4Qw4bXmPJALsLA6d24KOYxB0fFQ1gPGxTV_KZy pFyj2ZXsxd9ltFvOBu4G374FHg.ELSmpWHev0SGgAZASlZgNCI3RDZooxQbsglb08C0wRAf56gd9 XYmpMRoNb2tzdFuv0Wy7iW9yjmR6H29l9p_oaFbxoeGA_7Hqc_SfPgaSs8uJ_jukwcVTq0PUbuLo Lgfc5lyVVm5.utgudJ7uZqiFRcnGnoB864FD2X3tXcsR6ne4insyEj21x5mSZMIxy6dP0YSrY7oN RWQ9UUNmeTsatOU8YKLPH.mBHmtUtLXzhewHqEti5fFGGnr19SS_JS9nj_wkxBkGoEdje9VPpV3q mTBXPPL2CAbH9VJEFCsn4p5essuieUDl8It8KNlRjDL44YkN4MuXN02Dy0lvQMPPy5FJvE9awbeF K9UISZe.vGJFUM4Ru2.9kPZBntLlewfHnuZBm8k0pcEcsYVdUlL3qDE2X_VHbtn2XQzmDtZJFVH. TnxQdPseKE9FZGb9Eg1shBuLE3oha3ECXRBHcUeMfCXcTSGhCibthVxu9SzqEvxjwrqzvHqbQu5q 9pOg8Pe9sfjAeLztQl3fJF30kEzW1mciPcO1dQ9quXfxgddosCai4ctxQSqzQy0ZWJroS36iN2qY ZeIEoVYkZvgMzmbKfhmrWjb1hBf0EJS0s4N1C5FpN910.Uj2fO69br95_K6KtdnyGpsPiaMmiUTQ s_t5NuYnCaSRBNRF2VR6i4C2kG2BT.9VUaZEuYI_smZ8G6d2OyxP6.Ev8RFhyp6AF8TWZDLSHnGB pzfPeqSglIuoW_clthpOvCXJIVVwnh.MfbQ39yZiUWj6F1qiWad6dh8LJ.4wLIHwk8FzTN48MsOv Tt_6BBefRpuspfSZasvFAE0jvp2fR6QvVVbigO66aLXfTEFj_hJODte4cKPLg3G9i_QBt1vbUhNx CnQOqpGpDXO5r5gK_r1YgQjZcClccxoJwu6gKRQcNWSB_YqgRM22SXAUIa4uuCRUEGLGn55J2AGJ UvudaJTGHsNoXsEePcyxJqrYI2ox8.96Z8V5CfjFWZqtqFX5XOnM9FsGvEMArQNC0T7wyFS4vWuc d.pWTjcM2sQ33hgSLfYQrkIutim_R1bpQmDumtosXguJTpvgh_GwsZuim8GyHvT39syLqFGZF.mL NjfRsKX9BJzyjJwASGOwi3FQf.N_xUuOdgCIsTWmqlSoIh.j_pVV6CaaWAMODfh4DQKuZZgQuEUv hNhLqsdF6JylzMo9eUV3bRvvWAFD_FYAyi9a4i8rlSHxUdUzs_54bHd9Ec6h5XPDBLma2QHGIad2 laq7UzH.rxZd1fqGaLWj6mUBbugAw9n81hUj2P46zTki95CocWqKCKlD93TgrtjCaEyVUE1bqUVz XA_wjzBg1WqFG3A6C16UPSVvUEeKWfHvH_bgU9G02oS4kW6Nc2qyplo8qWaqIYsG0zXTTjyu2h8t vExfv4TA_6keahl9cRb5u5v.KUKU6zsaCV6LsP8Ho4jGXeD79RPh0xztPPVaF2_ofRT_9b6G7DAi M6R9gu1b0GiToWj_qKPK3a9Z7yH42iiEFtr_nrIpXdpHxhBWU5XmqQo3ZL69XTWx9H2Fk0MLFTw1 rt0.EBvp2sQG7jdqtR7fs1zGZEZMVVts5r0ZMCadiMsZGOMSy3x_y_QaXXV2HX32w3r3y1JSHFjc WTw15_fvEudfUUseWudrZS9vxkLTqDTTXCPsh2EgaBbf.L2BWnO9xPYYjtnr.GofyA0lS5sElKpj vMR3PiCwHF0xVCybxcDDfpi79TdzQKUbqFaHzZzfFzLq_Wm5f6d10IR8a_97B_gI8rIfKewZfx4N cUN6SkJSPkWSm0Y3_1sWTKQBh1HwGemNP7FUileJACLFTmMjZqlU5hmUmgtf_ig89rPGMFDnLsKm fC3APdjwQFOHQylU4q.2RXoo3ve3UYoWDKE7I1rGg1yvvbROUSo601xiv9ofvmiA9pQDcfwqC8qh oyHP94DeSRMnDLbgXVYwJjWh62Lg9Vk3aj_nrm3gcjsUXC4MZTQXCfHtt6FITRoqgdB9Z4W4YR1p PN2xQ1tBwj7ApqwKc0vR0rDlDkhOOD8pRjXtm8x5lCqCcYOrbJApGwe5PITPXQ2zFIiWW8YQH3Iy xbb84h0bOPkmhmg0g.Yzm6bAciMzwiptCyL9sh9y.06VAzFrZzcRNgywC66mt_aVKBg4uNZLw2w_ K.I8tZiz3aBCymdDJMxIq480tOer0FLwYjyqfBbrDxQ7jMA0Ilv29Yt8z4nfUsrC_1WOjmM634mP _A1gH4YC78ZNIY1LeKqWQibn.7dQJ1CxCZ3_wSQOcuq25kOYgPcbuRUBYTAIy9oXEg.0aFNsIIa8 o5ZdDLoDjSxvrq3Q0sl5YyPg9zaatYHyRsSUSg93ODikYlDJ5iaepYKgf74_jpEW8nuG6kMFKDEr qc.kh8ahj9sqcUn5d4LTBBq1QcTmxhQ6tZE3AoqaVVJXraOq08C7aCvR7fIt3FiDImA77qEVuJe6 snnJ6Zyfgy8_gSJTgVWwcaEFGKdNVQMtLWJGCfOOaw0Qm05Rk53E01yCslaead54YbR93WwKAKwt 1SzxSiLwr71EvcGAuXeb_.jo4Q17PKiYwU4PYq2WSi0WUFRVNfD5Izcej24l1VX6y8T8E7xisAk0 7PdIPrZUIYQz5PVd5qeY0jr25qAWTmMuzBrPdJTCYmnHFw5Jzm5psmrG4QZMpyuylb1WGfTu7WS2 L6SAbg20V20pEPMGQH9a0254UdGc.jmjn966Bex5PCjqb.xhuCuGvmwyA3Acscqj56b.3aeDOzTV ESm6kpsWvbO1aGxpEFGbOxwY_tImikvnmGpd7rno4TsXyKrFpQRXrZUVOLQD0nLQ9j0.4jTyDYcf O0opq5TegelOH2ACvY_5tNOS8sgKJb4i3pNmXiwFbdRAeOh3Q8qOO8PfFiXlZgVnOUioU7Q-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic302.consmr.mail.ne1.yahoo.com with HTTP; Fri, 20 Nov 2020 20:21:53 +0000 Received: by smtp422.mail.gq1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 3798a4b2d2c9f40636660acc6adcaf57; Fri, 20 Nov 2020 20:21:52 +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 v23 06/23] LSM: Use lsmblob in security_secid_to_secctx Date: Fri, 20 Nov 2020 12:14:50 -0800 Message-Id: <20201120201507.11993-7-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201120201507.11993-1-casey@schaufler-ca.com> References: <20201120201507.11993-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 Cc: netfilter-devel@vger.kernel.org To: Pablo Neira Ayuso To: Paul Moore --- 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 3b7a3e0ae8af..18749705a862 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 Fri Nov 20 20:14:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11922145 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=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,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 BB825C2D0E4 for ; Fri, 20 Nov 2020 20:24:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 498C4206FB for ; Fri, 20 Nov 2020 20:24:28 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="q3POIyBx" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730691AbgKTUYH (ORCPT ); Fri, 20 Nov 2020 15:24:07 -0500 Received: from sonic302-28.consmr.mail.ne1.yahoo.com ([66.163.186.154]:44149 "EHLO sonic302-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730505AbgKTUYG (ORCPT ); Fri, 20 Nov 2020 15:24:06 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1605903845; bh=OTCSU/TFUOOnhF4YxVd7UlRaclXtcORtUX6Ijvo1JP4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=q3POIyBx8t1ypaQrXh2FUuyUqGaqw+NsVmNUOVnLZbbo2BdyMPT0WgEBv0OY3xoDiOgCfdiIkpxb3eGFWLM285KCfL+SrZ2Trg+h5hRHM9r0QsZ9yyZelEZ/rukvlU0xMTBfU386sGeDyxV1FZPOJlKW0pk21ChILLBc9QNY0H5v2A8M97OkuC2sd+QE7S4I3zD9kpExgjX7SZsvjg45wRCJrN5RPS6PLTpwFt3Tl7a8aVmcDfH+p7EEYSLSIhMV2kQ8OVZr7HEbTQeoMAkbtXh2+PUaxTfKCN06p6NgQ3UpvZfm0JkP9J+XwaIML5JlCTqIucqls+73CeSVyIiaHA== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1605903845; bh=HF5r2semHTXIu9Qh5U6FCsYVno1vxysDEYQmUXUekRe=; h=From:To:Subject:Date:From:Subject; b=QP7mS43k+GjWJyUy9ellFmzcOKz3z678DpaOSDgoC7o8mMsGYghMEIqUAp+a+zP7dctUd7pwiWu2LkRCr4SSb6PKULIUIp5OM68hkLLCFMYBI1wyP0gySRJQtT3sk+b60eTqSzvHOww2JcXwLCM4zXb442IwamOWhyP+9+uCZqxMoF3nAEz6TCCw8PBmE5bdZgtrblQKm1NGWntEw4f3QHelhLDi6HrWaIla0WJWhTNSsDEqmLi55yrxsAGv9DJoyc4eU56LPV5WqgUiElaBZV0TmGa7s7/tOAt0aBxZpsI8tHmwFBx2SgMye9a+Zr7ZXmVj15ZdzGwfX8z14/F1MQ== X-YMail-OSG: If7R7yoVM1lWlUdez.Ci59Qa2rG81MdDt48q0JYljFUkb0R9cTUV1IF6yUxGIv7 HLpv.YCkDhy2SG_uhNJTPuGfOL.N7MKoHx7yLS5pm.YhSA.ORFdcitRWHk22yEUNTh6kwL3eksy. ulyQ3DJxznO.xhYFvIOVP6QInHUN63RKyN6O6Qy8ygonkH5xD_bqEV354GZAF0OlUssnfn1julsa m07L539woI3MYCclqwxN3uygWTkLxhhcT59DpifjKnj1P50uEpWKSzJt1aZ1yJ4OI.VGPv9uA41i ClHqCNbXK0lVT8XksuDiV4srGH.mpCrB0Lvu.BFk_FFqC6UicITW_bKxpmNLprjYL2jJi4nHsJZi fnJO67_eINZOX8pqyMe514ViDAUaRGPAMq3jN8wtnB_LmRA3_dTd3zHOOa3QXKNeaPc1D0Jb4prK KAIlQc9ZC5JE9rxrhu7bLrhzLofzgxBiTxMkbi1d_5kWpDge9y5S7x8recd.5Bqfad19Bix10Dgv ZItf7AWPBzhvf85PlPBno_OQrq9M89KjjzyznBmZbXJA6xdhGY_5BMtZxO8yQw5lB6Gq2f.RzV55 7Knh.GkPrhqUUWDtxEbAPQLioRtC.SFJjrd4sIPHDOCP2Fo6_6cI8VxuQZG0HMCEstQhnrYfslvf bn8ZdLvxiC73DIWogswdpsZfDsJv6uQNFWde1hX.0XAfCCo1oYUBMXLns4FJD9hHCaqncNHdUeso 71CmEJQaZKrPl6GyqpeAhcPzzEUnS_sYHzrfB40Y8lZFR._5kH_.A366dNnmC6Sq8dLjiTvkUM3p V_PU6poDmPTKreG2alOaVbh63o82BGIdzZGWuVhsAJoYj2yYSYtn.o6NTamMYl8Q6XdZKGZshHVD L2OF6Gwqjj43p0BSrKc6KqqBQisd5jmxNefanFpulA.Fb9qVdASXna0LXWWYm8oTyf1TMuOkjaOe XwqiSZuQjM7fg1c_xd9rJ6BiEbpIqC4HHPyfppzQLtvJ9b7j0fafjHzazwxOjbE2YGzFM8ejaXcT NTKLKRqBu7OV9QHJve8V3VPQcRiuBhSoZlPLNhLAj8w9bVw4RFyPFUVV5wRLxdSoOULJvOSzf3RW k64DGJ4Dne18Y1kXGPzXyMskAW9mbj6H4TCWrSPZpl5E5lCkyLtxFQZGlRtlczUiWPEAwqw4qLHg BSng5AFS33eSTcFGD3rvfKizbYa9sQuMudwBNzh8YpXwJMMJWej7zrC8a4QJwInr4hN9y7oD58VV EOex3Yb_ifFBERNJFhR_RtPL0vsH6EPhXnIxJE59VOmawg1NMDh3fGKQgW2BNfFSFqOkfYsU.hTw 8TfocLAgjxpuoDXNSIX6N6tQcojoIntR87wmOtIvhP5B4LwWFnrosJm1Ze3yIf5UNo9Pc9b5bBCw M1ulHu1rQlUQGjy78sn234hgnq.Xz.atk90MTbKXOzlkUhZamEQRJpDhmRkJ3vFJYqMYHM8ICjd_ otG.fJX8b8PcSTOK7PTnu9HvMyUDHkMyUKWL3LKdbh2JpyQKKjWb6xxYEWkD8lp_LuEwcI4dYW0h ccFej72nCmQXgFbrkwEkJDuMdK3_Z6dj4SkhkpR02GJkrqLrRaFSuTK5QFUIMnqBudy0uv6HfrVh TMxxZ.cis29hc9_F9PZc.fZ41WoLLa_S93PFH8EHa323fDpvbAv7DzTMHrwKLdc.uM9DTOx0tuaE wjwZ1PiV_5veTMWYOD_f9Iip2.aIM8n7zyRgfAATfXAZVe4E0yIvIvWhm7TIo050N1BDtrxKpwBH nf_opzTkL1w9sd17jF_Nuv6WpmjzIoj53tGg7AEKKD3mW3d222aFjzo8tKEh_e3v7cuDQ1avVmoK ioMcbTzVqpTy7ClIe9q9pyFWQgLXv7iYBr.tEkdj6q5cXiWrznoPLeWP.3FrklVdOaxwTSS2rf9G rVWCc.quiQsavaVuynTkwXxVCYqxsC.pGpTUA8wyGqyDL2jXoijcP0SYQ2PUXJUdWJIZgscX2Ij. ptPmrLh2CdFEF3J1OKtiqctlbSnl4hK5wVz3OBjZk6WMsXe.OP3zhr_MfPwlWHTaFuYsgk.9dILy Eg2jKHjwLSmgyZQcYi01bdBibyiqVsjlPxXhWZzVhoJ7wrDljjCGwhQ7b.R57AmJNdRZkNbYTT1y BlJAsVu0Iwi_L8yHcOKSxjPa3n1KHEJeGAzvflXORUCi6TjYkTMXW6Mp3IH5vD_FbPSNOze3UEVH VvQ0FckRRlXJ1DEQWhjo01qHjvNxzTQcAB1rOJi0sxIyqQQqZ7tIuHY3we1BSRE.6sVAowBB.TfG 3PKDNbDhNWIJQc_DGIy.SR.C8N3SWEwPX5VGhgumslFVpjoPU4iqwTd2c5wsq3a8QMzhKSUX1yg3 8iBTVfcqxZaXti3kA3TwhPrtoVc9VpdbDCLdrE5oIWxva3sBR.5S7POJqmkNbW4_EzuMj3_rKORh zDBkUNUl06A21ejgKouZs5JXmXCKvKTzr92byqOk0NYFErzxEucNDhfNwooFb5XMDrGS9FBz5D8n K__XEBKQ4xWt5QiaUvvN3y0xlT.C_iK5q1BBFopLma4iIU0vv7clDh00c1XxrbLyBWFz_A5aTQ8k fbAwCgWZlFmG2Caq04OcU06L2fpMoT_QP35JnT0au8lb2yJleESm0psUUDgicuxVXvlnO1SgTsJa ENjie3ZQp85Yv5BXzNexJtcgNduNpsQSJTK81cYW_r0_nWvOkOE5Gv94K5veAQvs8BlDMdNXs76K xRXj5YSlitAzFQO1Eje6r6DTwm7EA6TYjdruEoIY4S6YbjUaVjp211uIgXYrlVop26mYXXfXHkgQ _8bPZTQWH2w0oyOHJYWiJv.rXY_za6i11f3hFhl4YAEEiRkQkvC3vCB70ihfcrRUvtJk6rHrApeM 0p5rkx8chWEBFAOw65f3aI_xFbfo.KJIKb3clFiT9xmpM0lJUq19_6R6EpSk2vNoCXpBiUxcNLWY vaK73gLZYz2XcBR0RAG2G1ZqTPojXj8CgWorulS.HZjA8eqA5Vfsxiz2gLYlF3BQb8PdmqcXIqCT MwQ3aZtoWuHeabBRDThPZo5hA8yN9iuMYE0aGmoCOxFcQ8gTjjj4OVyS5Gi_PtgEe3NYneDACMV4 cTwjKZNl9DiEBQAE8MNb9x_OJnI.xfVUDabTN5zEw8bmbyuY_.EH5Bqr_WNfRF3Yt4LaDtbI77AX m7WgmG1.mOsPK49YXXua1Pc.1l.JBvzbmHHeAjjiTRWcHIo31N1H7aPan.ZuNJCm1hRysIyA.QbU bTCoX3TKwgZCjytoLJCXfmAmawGCNhCBdKPdr0kT1NJQDhUzZHvYLxN2IIpwlVBoMWDIeq3grPLk a9S.NEGhm34SGWlvn7YlpDSGwaUWn2wlwsEjrt7Ac0jQk8BlvERgDaF.BBjeXJiJXyC8kuV5EpkN 0Ey_sROuEwogQl0SXYnDaNNRVTRb.3jyUgTruZBJUg3bNVKHu3IqB4Yb6QdzZdLV3VI_WtcpX8IV hlA-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic302.consmr.mail.ne1.yahoo.com with HTTP; Fri, 20 Nov 2020 20:24:05 +0000 Received: by smtp403.mail.gq1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 13df31277140d5491dd9fbfc5f79afe2; Fri, 20 Nov 2020 20:24:03 +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 v23 08/23] LSM: Use lsmblob in security_task_getsecid Date: Fri, 20 Nov 2020 12:14:52 -0800 Message-Id: <20201120201507.11993-9-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201120201507.11993-1-casey@schaufler-ca.com> References: <20201120201507.11993-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 18749705a862..cabec85136e1 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -1564,11 +1564,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 Fri Nov 20 20:14:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11922209 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=-13.9 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,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 9D129C6379D for ; Fri, 20 Nov 2020 20:30:04 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 325E322470 for ; Fri, 20 Nov 2020 20:30:04 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="XQCNbbDL" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730946AbgKTU3t (ORCPT ); Fri, 20 Nov 2020 15:29:49 -0500 Received: from sonic317-38.consmr.mail.ne1.yahoo.com ([66.163.184.49]:41135 "EHLO sonic317-38.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730955AbgKTU3t (ORCPT ); Fri, 20 Nov 2020 15:29:49 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1605904187; bh=H7Ri/VHtHrASIh5rh+CWAH+f7yizZE1UTVXdJjukPwQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=XQCNbbDLwcc+M2e7NWSO+Z0i/f/Dnzs1VXDAT4xrDDsPHCFFleDGmGCwsTOFldht2v2PsVutAYGIoXKzTDRWelR8/rRBw86a6tAnqvLILuo4S9DnF2a/skQx/a0jDV+6y8CBHBc85DSQIijY9PcEmvxr8tufq8FrGvf3KvAzutOnqJhavd3nQdVnHuMjfC5xjgCLVhMkXlk4j0WBpJYW1g52GBKjzi4t18AovbAqGWtGuZ/4Ety4yjlQ61sy29X0jxFWwVVcVf+SnJOZ9oBGfVXzRk2vnJNIeRqAiKbo9VYB5bdwF9pnW7YBvFBGAhZA8hTu3UU7fNFqUhWiY/HXqw== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1605904187; bh=z8hyZDD1baUbJI5PJE+uj1fcLiaZZLovwrM5tueFnFr=; h=From:To:Subject:Date:From:Subject; b=Yef/QAHJcAixNkvdK+O8Gh/Enhyus6x59NvG2yBSlqUsDWm+2rIEeRlE3LCVDYaoWHmPx4zSYYIxtwtNz5giHu/602IQgaovxWbsyW9sjHCSbzLABjKCo3KX/sOSiGJAlsUwslvk98G/OOYngHpGHk/CdinW7PMWwVPmIx38Ac+l2BUnDrlt4PHY4hh4yH5s9X3GVO7NFSLH19vIV7uLey0OpFPzdvGhnAx5KezT6m074nS+ZM7LjPL790IFAiA24IGya0KVpF/60RJm6QFYQKgUUfdrzTcHux+fHoHQL9zsuwzh8zmV8E7zCTl3XM96jCOHsohyG0eahIFXL2gz1g== X-YMail-OSG: m7d5C.wVM1lVkOMtOCJJ5ZCDH9QzQBWGEvifAZZso_wufrwRtUosAFMBmykBbyG 8lcMdBsMGenjr53.94Ey2_W66XZ6X7h.GkexKb5GP8k37Kn0gPlcagiYvIuEtRWq_MmugPMqQxLB HP.uu7ppUZxtUyy4.IR38ZbBL7XWlU6LC9fsf1T2AkgBfsSfbi4D9T9wrNPG2iQFFqpmD7XlkQc4 aQzTXNaSToD5Flf0G8ElkArx7inEoDbUqUkEQpAx4BGC6v._RkV5g00yHACisLodUuoJCLfmVxgg wXuzuO6nUj6VhugzFG6XlHUSXJKsB5VY3rNvwWyQLsAnKDqj69eAxyD6fdSdU6kkj4dxrZRBLvlK lwEBQAR4yHOCYJ3mGpiOhAxonNBeILmAQMVk6TJslH5Y0Mv475ScbaF7zoH2Fq2PjmEojTrGQq_Q RXkvK4zWriBoD4FMCXBmIt5SLRVyKHV9AyAiYpgad7DLN9Arap.0zjI6Leyl2w1BlnlY8W54kUcN m1FKxcI4BDmRpQUyN1oY9M3Y46Od8Dv9THZmO9VRlrtIjzgf8JWDLKsenxSmkcqtLYmWBrhzsRCw yjoaXszQD4RXPHmE.wqvxalSk2nmmyy6PwN9LqeaJFAbOv37mHwzaEQp9qM9gpAUJeXQjk3smqBu Gsv47PMx9MOuUcVxDE9pJXUtTEiNaoAi9QDJTmd8GRYmiJJOUOi3.maBQS5X_MsJM2oKZnTrkBL_ KudgM_3U8Q_9rN.Bpgf1q466gctKqC7REKEl.VO9jEDOthZTA0ucyjP2f2XzMbCocio3ESg.tR_i M3ladDGCLf8d39XMIFmLWFVP6jPXg3fazrYFdNnibKfe8nXzfQJCClpk8qndVdnCsRtYVPzxTJHV YmimtEZ8eNPQ8zJWIBQgas5xrQ7dzIokvTwK0KyEbR0lwc_Ht4n66PSuzIPon4ShG3ZSgKyyQiPF t38jPsQUb0kg1uuXiwifBazF5JGxn2GhJ4WsIfVPkeo59.LmgxYL6dq5L90lve87gfH_YhPAykMX vQoqhQppaHsKp_ROjkyPIVxaOQ6tbzsANK3Ac7EyC89WLfdLWiGtXcgqfvJPfni5KSrG2k1TUMIP 2E9wos71q6ztSM5AzGmcglbC1EfbSosmBPP_1K6G9tDuh8Hq5KKcmXwGiT4sHpI_HPWhX42hYYOY .lS749sdmqgvDkfsscN6TnRdf_F2s3715HCsItPTFrUXIpdD6EQOQdeSQ.O42X47yFT4lrmZDrsg jFh2_XMzJ5Gj2hlbtFnlZJgjRq34OQADwWJmvw8rBm3iuMAPtJepST0sIDi5L3nSjXT3AaR4Oh5p r1fwbKNT2okoJun84JLfIOp9NQotLxkLhmY.8y9Wh2JjF1JyXWphD49CAmiMDmjy6yjPToVcFO5X BDxBYi9Y0uMCtiqsnOZu6npwaLRl4td8PCgcWwT4RFMmQdWf4ElF1ThDXthnzPPGVTrWPer6t0u_ zu0VL21B.Yb0KpgLwF_OgD68je_qUFMKq18UXQIQof1ASXz8ajbon_AYBVXWHw9DX7DHy.dHKV6B _qmjA.cMEaktgIUvIqsvZKU6QSfudr8tNWmMDeqtNOvt9vfpHT39d_2_JTyiqt11QGwQ7x.gEoFu 7CHvEk4raQ5J1Y3opGariz2T3ZknZ6RxGa1VTG3SCGIl9b26OkF9zuIXC67UnNCKJq1Ze9wVorj2 4730eOflvhB3AtKqwhqpZSs27ta6gd3OAg63fxBl5XVPgk_8NN.CQnHdhTZg2cjHJCW712c95kOa UVzM1UeaJTdZYwTMYnsQ7gJ60awF3joU1UEnYmt2fz9gPQBwF7IaEn_43A51NJw3BGFqszypfn.5 gf2oZTGC4YwmHthf4q_WImVVfnNMyN8A2OHhVFV5JyepbReRsmb2JEZjTOhL9KcXAFBsI3KcJHG2 v3G_6NpFV8Hrn8P7Zrdke8PESKKq.yONi5AYS7HWagRT8AIwcpImXocmHFiokCRJOzudz5ySpxel X4S8_fPxOShuvxKmWH6hmcGfnlbPILQ.afigzoSP0gL_XQp6coNTOIKs6auQmmTFIWqLHWfSYSx. xDV9iY92ws8B0vkyRWTZKgRSzXgoHs_udV2TebmSwzF.M_DHHM4K7ITRU2CaOHUSfHsAxGcq_vbv cohPGurDhJDE4gHTw.y3buTxKPCRA4Xg3ra_PEGvxUh1JCk5hmWSvj559dSZXNVPOhmssleuWjyF qv.OlQBH6dqbygqFKwWKXOrEhlMmUS9__U3917YSsB5YMKELpV07u1hKOcjY3fiFlQj8nE4nHy_k 3PbHjELiYnq3giuyNbbkCBdwbMcQSD3raVtqsH0WGaKcLPaNb7ick.bFJvSMPoNHc8_H_PpknhE4 ySb7IKVNBV1Yo0abXiJNbgGwW8U1EVLJigbYne.A0R6zXJHwvhOndqXp.4nU.Iew38DoQRLKKCw_ BE0mg5BWKIHOhoUgjk23VrMlPu4BYuAVE4xgg9dYpc4Gqkry2IhFqnHkAajcDPVOu1GSO1nsVX9t MzQ6qq.1jM2UeJsqQEUiFYMSM.J8nrxPnIG40PBHjHekAERqS0XXl9vATnkB1hkWRXex7iw2xnzY hWhB.SpAcxEGpLd9skwQ7J61uV8Iokyu6CgSi35QPtj8YEK3NxcRAWb75TvN4kCEBPt2r.uK0a3f R6Mx0qUyL3BAsCah2X42d.s0ypABt0PXT2fyTA88qJH5bXS.C8Ke_EaasVLUqXl8FWjSSWwCSxZb 4RtPBWQDSizs7XfBF4SRI9N4fo6LAcfTNdIF9uxmf2s.0VBw_tST5yWa1fcb1hrF75qxmmCt7QHe ciCcu5xiEFKYRyBMJr1dLC_KFbGR9cZGR8xy4ODNOSu2BGO1GIz3iuLa8bzUY5A2X4MJMVof1lQd LQnq_AJSzZCYKR2az6ogTcV1jTvPBUBhfsgnuwjImuS5OH9oylzPeEtozQXWiefy_l5qWf97OW92 RcgDJ7KMgQEwwesR6.qEsYOUOeph28n6pffIsE3Me.k.zqOZI9WXvhUFiGAu37gPzZ53pvtjG.p3 lplk9sVh8IMPa1T3.kVbUpXdnkexuJsDoprdUWNpqxjLIuQY4egwDNSYwt_8ulKMLGIao7pJx2_Z lJ5PcAc6YNA7Bhzw_5cNRMAlWkCmIFx0AoyyNJMKi_w36iNYPkSWT085nZECMOij44.ryR.OiBm2 jgmZFCv64NKyQbVf3aHIqCnFmh_6zX0.POObOlU4PCe3csmhZr8eyghx2z9Z4I7S9SkZX4PqUi8N ijR37hKPSOThEFPz7ULp4MS77Fz1xIWieP0ARZzbtMwH0QnNQKlyfk95khV9foEQMaAXSzQ-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic317.consmr.mail.ne1.yahoo.com with HTTP; Fri, 20 Nov 2020 20:29:47 +0000 Received: by smtp401.mail.bf1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 62e1877e1887933df0f6b34e459fde17; Fri, 20 Nov 2020 20:29: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, linux-integrity@vger.kernel.org, netdev@vger.kernel.org, netfilter-devel@vger.kernel.org, linux-nfs@vger.kernel.org Subject: [PATCH v23 13/23] LSM: Ensure the correct LSM context releaser Date: Fri, 20 Nov 2020 12:14:57 -0800 Message-Id: <20201120201507.11993-14-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201120201507.11993-1-casey@schaufler-ca.com> References: <20201120201507.11993-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 Cc: netfilter-devel@vger.kernel.org To: Pablo Neira Ayuso Cc: linux-nfs@vger.kernel.org --- 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 cabec85136e1..5b83967e3f27 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 543d9b707fe5..352c9eb98425 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 ilsm = lsm_task_ilsm(current); hlist_for_each_entry(hp, &security_hook_heads.release_secctx, list) - if (ilsm == LSMBLOB_INVALID || ilsm == 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 Fri Nov 20 20:14:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11922211 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=-13.9 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,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 35F3FC56202 for ; Fri, 20 Nov 2020 20:31:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D15B122464 for ; Fri, 20 Nov 2020 20:31:24 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="PNnxJX1E" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731237AbgKTUa4 (ORCPT ); Fri, 20 Nov 2020 15:30:56 -0500 Received: from sonic317-38.consmr.mail.ne1.yahoo.com ([66.163.184.49]:38814 "EHLO sonic317-38.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730741AbgKTUaz (ORCPT ); Fri, 20 Nov 2020 15:30:55 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1605904253; bh=4RRzO0paPwyehaIJU/rSn0qfpMiu/liXc47W7zqXUbI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=PNnxJX1E0a0nSxQYapsBEeREo53A0l0I/0554SNnHFbTYtwuzCyKQwY82ZfyUkq3uoN2pFWBJcmti3dhOAAVs6m3pXIkkGj+59Yuv5Ch0TS/ne2R841rFntn8nHkUoytSMl7ODPi6w8jr/XQ+YvHVfcvnLvbum86gEi1XxPk9GslHocN24KqbwGYA91GG7+nngVZlv+TbocX9EZE66qw9lLXV2RASlHR0k0VwhQIcy6IjgnxO0hH+/Y0rd2DHc97I8oE4xdfUBsy3MgokCEliekiJCm/p6C025RY1YWVxK8Izum4cCangLyyZfMWaH/fZOUnpy9q223w9HxZRoCljw== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1605904253; bh=XFIks0hweHxrYJ3Wr3w4271Lk52T32xSa9GCbJ/19n/=; h=From:To:Subject:Date:From:Subject; b=qKc1hYFFtGKDDTC/BoVOffX2OpU/oWr2yvh5paj35A2n3xyFZxN2VSsPP1pXKZjDb0YIQIHrYj+zAO5uUH/c7UkRJDRH5nHphS0VRk0Sa30XBSswjGbuWQauZgh/WfNNc4Or3oL/Bm7TKkBLy4ACvkoNIOHS6lVs8QRTxVRIXG2rWYt9PKHxHmfd01oT2/GA7eZVLPdtPZz0TqLgqD9MOuB3cfyTHxbuMPWH8ZhfmOEjrsGoa3qV6a4asrO1TNxPrqY2WaPfxlDoKQiVLawkzGxdmBx5Cu3vlJLTbWJMnJDZ9Xwz5AErRCx1dv99jifYkwV3cxwjQHJ7Wt1dkrov4w== X-YMail-OSG: GGluitgVM1nh6AdNYNpJhGY1uVCpJVHqkPvEt_RRzJbbQKeY83WmGPF3QR3YGM2 hosqc032fdocyRva_vxHze6O5eSlWRzdQwqhVYEelOGpfnMjdyEjhOGSzx_O5t0aIaUfFugqxZXU hDCkAn.5ziPTTml6aPlMd1GELTdcMgoOC.GW81fW1iBbnNs9g25WYRqA94r6inlPGTvVyCfD_Lp5 G9h9DjKirRXW108L69RSa8crvy2wo_JjhdJyjKVDy2XJf4nyPQeOGJ7vR9ttSMOLYxhcs8Fybk9e du3Ahz2QkXbwvfar67qtnuGgWidAvTIw_L0hxSJkVv5LjQc.3Q67q4ynMOca3KYismdZMiGTVzeV UpRBQ.pR41KEAJU6I_a2BV4tdGwL0Osiz9JpjauIi1j2j95QMqSVay2dcuMn_f4XpwkyXQSHsQKr XKxc0.rRg9HEP3HG716f8hcfpWrdtLyDQIZfF7Rxbi_X3tKHC1VprjGnpa_kE5wRmBKX.CvHm2Lf 5Uc1DaTLz3vE5OTSNs09rtXDF3a4ZrQ.sIvWR3HpwAFAZbMfXtBFKNjTLC7dcr_tekxE6B2gvT2u NBe4Q24HDzVNkQJL.pbk7LiVNIrgYkFpFKI2WwP0LpmbO33gKflk8KNbO8wwOk4qheG_rPfHDLcn 2GN5YrUvtdvhCSqp7cemYhKkDuKdo9C4Te40IpecPhVZ5GVIHeqewogXkHUIZY0Jj3zvMspucfBV P_mFILcehmT91TI73HHOhsKqBTFhQPvgqF63PY_Q2Q7RPUA2FJzJ.VYga_0tTvxuLBLKcrphbTcd 6o82spBc5ovAyYtNmIUdYgcWwNd6TTizhg.o3bZQwaKOVyYtZPkuJ3B3wrBZ.2nIAclNk3aVs4cE NtWE66VNIZQOBH6A2QN0CyQsn2.NZaRR05Mj3cB.zhsq9cGhvxZmDL62KdxP7Y.7_nusdSi_D.04 7waBN28KcWpdwoc_8PnhqL75MRIXCOWFfYnK7TvSJ5yPSNNahF6fJ33.OWhuRxXDoNPJt.oz42YE Dw1UXC1ZzdXLp.8igOWAjaGkORBxPw3pqw2apWmvv5GzNNhEKSjqwSDeSIAH2QLpo3pk2mk3ck1r cTWDOum8iR9cwh1Je5gSWcO7YMvheZCkDGfB2llfll3lkQ.HomV8rGsqvpd3t9OvPt89lIkLA0sk m7JPy7C99b6iDuA0OaLdK29HHdSHd11TmPGePrR5fPimDf1CgUgeqaKoHPxCedMHz03Cd8.s67X. JDR0WhSnp8OIQ5OHKyNhKg6REym2.myEVdVkFGslbdBVChlDOtP.nCHo4sdCHpkX.qjaAMk5Uk6M FHaIHM3_s0PJI44l1v5q2HJhMRBJLRYLUq42H.CE.DMGKbb_UlbeGsesHS2xsgLcmli5Ihbrb14i DY9FwznB9y8VJooj3EAtuA21O.9537dDMEUqcPgnmg.8JwFGqOIi1k.4NjwerZqYhLobUpNZTpPF IjBj5ga0nEW_Cp20LLruFGtKu4VUqJT58N69MswltvEpOvjAEKcusy_QyT8N0bI2ZQO.sEC4cxEl KvMIkjJotv8nmvNGeNsAhpqZMCLFvxw9uoNH.TVgTr4ZBm_kbBmKMRBiNTftnm.zkEZSG3KI6zEx bdMNsu367DusuhEUKWz4I9LnblyPQGyjHbi4ddAjLYI2YNbx1GI3Bl2o3uYM0wTpIcoSKTkXHxuY TCP1ybtReBkfIOu2DzTj7UB8XbLSl1VYv3uzudescuG2rtk4G2rNwyAWI2E9Oi1gmGGs4iFqELEG thtqYRXiYNNjzXj9GOSQT3qDiqUM_unEj94jV1T571kYKX6HpU0AkozbDD5fQH0rMLLonEkgqTd8 8DVaNvryCjIFAQQSD5BPaWxDs5nkU8Kkp33MVO1pqi8ki74rEVa33aKxOPVTn7pmo4lBHXQaLwve EmZR0wJsN6N86cb7m3qZ0nZGpipXwqV_IRR2CWRZBmaE3D7ozzEsKHnueoRvPCyuU3mZEGryWAgJ V_P7vfo8Af71LCqN65FGb4b9mFTSjna2U9MXHuKkPKfHO4chVaZD0vtpsoUfqBfRibyPkN3BVuNb moZPHdmjSPXa2g8zxr3nWeVB3ltdt7f.LS85kmXHophAhlYwUwrV3c1zZpJFPiu44o7cdGJvFqzl 3K8t_zckc3t7XIDH7gcwSxX1ivrhryf9xIeXfo_0xkjINYct7ooq2hebdOCnyQ_tBt.kw04svS.N Jn7HXvH1J9Ti.i1n_2wA40c66TFCa93yoLnxfuV3pOdJRjd.EfukOqKv38f1SoT0xHj1kV00G0rC 5zOdl3V84FCfkhVjtmygxJIayKYfgxlJUZbEg.z2VZyjjx62a_lHX4bGPvvK2AqY2E0yIRFq2dj9 tSGhKjAXECohD6m5UR2pxVWg1TkOFvF7n2z6Cz1ths_.aJEuz1CpuEWDPDRQNqkkgqZfaBj.MpFP 4.g8xR0VC42aidbMdTosLbFHp_MPDLUJp8wt2ygMB5EnYsTEsRtqoAVXjVjUAAkVgpIyROxJ8ZmJ WKExGH8zzA6Ztxm1z97q9.AF0as13QDt1BiSChsYOFoE9HAFdEM3ZCIUjckVpP8cEKA_51VwsWQN HVEJF4lRRYms3wTLoh0Gc3pstcwTLCVIRzk2t9Nn63ibfZr8.1pgXlivLJXrBSXC5nBWLYNOdREt ueZpgnixc5hb.8Zf4JPYMJHAWHGxyAElZPUe5rYImHv6p6zxRg1iBC2LdEB55FagLIUxojhwdpSa IJzdhZbtzBB5MTr_YL9MCIlwzNKEb2_hSye8Il_k7I78SKZnHDf_mIlChbb57__a1ekRFYv_tUl7 Uh9CuBMkTs916XMLxpgFRXw2x..a4EQvEQ2JQVNpoQ_xMDtxFMe3EpMWfh.TL4YNJ.EzIcFkzy0w AXbuuLcJ1jTAWysXhLLROPaTdWticKIVseJXhlDIMiwwKwo_k9f_002dZTXXS8oDKiJ_wW5dh63c Rk.MJkGjT61wFMWeAgaY3NpF9EU7LqcfBt4X_S19FE4bPSYuy_iNjFUQ1kpDdTbxHeexUa6hhlQT k_485AWl5JvvVqqWehz.sKFOXCbGh9WXbrO_btLHWPx8FJNDhygoTrb5azlm4tK.5j7DgrLQ_nD4 drOB.9qZpt10JT9HWGx0FEAmbaauKZgoSXnU7eryK0G5Pfndp29nSC4BlZycQiX0sw3TL9hAW2Q- - Received: from sonic.gate.mail.ne1.yahoo.com by sonic317.consmr.mail.ne1.yahoo.com with HTTP; Fri, 20 Nov 2020 20:30:53 +0000 Received: by smtp408.mail.gq1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 8c6eb17d31118d62bc7b134126c0c400; Fri, 20 Nov 2020 20:30:48 +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 v23 14/23] LSM: Use lsmcontext in security_secid_to_secctx Date: Fri, 20 Nov 2020 12:14:58 -0800 Message-Id: <20201120201507.11993-15-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201120201507.11993-1-casey@schaufler-ca.com> References: <20201120201507.11993-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 Cc: netfilter-devel@vger.kernel.org --- 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 5b83967e3f27..c423c7cdd095 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 352c9eb98425..ab5d2c9770f1 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 ilsm = lsm_task_ilsm(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 (ilsm == LSMBLOB_INVALID || ilsm == hp->lsmid->slot) + if (ilsm == LSMBLOB_INVALID || ilsm == 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 Fri Nov 20 20:15:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11922323 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=-13.9 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,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 A0966C56202 for ; Fri, 20 Nov 2020 20:33:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 308F92223F for ; Fri, 20 Nov 2020 20:33:27 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="F+I6Sh7d" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731241AbgKTUdG (ORCPT ); Fri, 20 Nov 2020 15:33:06 -0500 Received: from sonic317-38.consmr.mail.ne1.yahoo.com ([66.163.184.49]:43571 "EHLO sonic317-38.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730937AbgKTUdF (ORCPT ); Fri, 20 Nov 2020 15:33:05 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1605904384; bh=p1YuVBPZn7hPysARDQWvRpJ3a5rIGoVi+47szzIkwO0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=F+I6Sh7d2h6vGrIanUav0m4hVWb2xdGgaspur+nEjVmtS3aqZTnCVM2w9bUJixXRzArClYVxWZq1JJ8286hq/DPuFNQ7ImAttkj5QW+LSOF/r3s0BoKT+YnPNvDnMnjM+Uf7DPVdG+1XjGlqM0AHnxB41mVWPizv3M9bFvWQtvwhBg4RxXNe+kF9EsIihfswPDzng8PZe/9KlR1r19jHYa3Yckp0tg3jNRbGhwSSECjYkXrTY9II1grWURIWBreE7dMthR7mnecZcbgeYroegg/NeckuDh95iI+f0bhp+tPBAB98dKqz3DwuSqMqsxGhPrwMn4JetLBGiN99iStitQ== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1605904384; bh=i/sIO63Ulfk83/Oc09fol4Q0rsuVBvLzpPZfWEzITJ/=; h=From:To:Subject:Date:From:Subject; b=niHWB/iEgXKj1vczruLuEq8rfA/VBWCB9ULj1eXRLxAEns54jS2MT/i0W7wWn9R58CJ8Ks93/YpWu5mNFnJSbV0eYJPaLl66YD3qCnvdwWsMAogXVq2kUGBYW9D4iR3SZbHkFbOiiAqmxJhd6koXok2ZJrQoQRaIlrrAigejyv7dPicskD+duG+aqaZyJsghngrxAIewm+bKZFJEuMQIAtqKV//XYp7ujk+YiQK65hCVjveNczbvsq/Jgja9sA8nbzqtLLzDAx2MWZDLlQxToVhF63Nk+TxpoOk5Hyqs7a5jMg28xlWNrrFrufqkYD879ImGRxRhHVUza8edgKazZw== X-YMail-OSG: 8eLaW1EVM1mKsLIVlBJZdxQ7KyzuMKjKxFH4OsKeG7wxCRhDLhgWAPxmjoJPIu6 OKchM9GBNxRGMvABQXm8WzduzB1EpjpLzBRWXasn5eM0fPvnkKY2RDBHZR7maMqQ7DmAn.8YSLsj ighoK842dgwRTcwLTPdleM3B_T29dXeZea1Nn2rQtZgi2XEXOB5cAnrY54erQo0266IcNr101lck dA09BONqVAZBBhx7sKV.yI_94rd9aM5Au_YxXUvzeKljsXROMddA4OvyXZCbDHC502PO4Q1v3htu 7lp.VXzqPmk0csggA2rJrsrgVuRpPfxqtWiukRryaVtGLyRzYqcwFGbHu7yQqBxJ.k8j4AQnFumU 1myCog_sck.Y9QYz_fSMk5HCT3.hYhVJDGDZ8iEaJl2WlHY4lV.JXAXuegWsO_U3fVtknEjnp7xB rwQPW57OiCiWYqOPwYolVLKaynkjFlSNaZrjbBTa1x4Gb4hsII9mZ.FB9DGIKr96q5x10r.sj7it NK_YKUbO8cNR2hAeXhp6OV.V7lqHWqUYaDAQbVE2Q3b6zIJ.8YXbSs5_Y1S1fmpzynEb0XfgBJwe 2Twxd4CVc4N9wIK20.PZ193mkzVY_ZtCabeUvtSHfRJbIVydVPurXvRf.CUOdsDKRhSE4iV.5ffd nSpBzjnFUbXLXTcZueVMWqzUuGR0C_zc8X6.VYf2OTB5Fknm9Z5zw2ixwnNC1uOY1bwkyhcWRHL6 jraHzVis_vbOhPwqzdPuu0k.ptbuW_LI7.ef3okIhW9XkeMJaNQpMEaeaXlUhELfje.lkkKsYulk 09a290G_GiGNw8Oam7SphaRwfDGsAGV68UsnwgX6hn9GC5ykT93IWKjgHw4iprNS3WRoEzFWmfQv ys36DdMdBCX8Ofh3uTsyjc8QRES_6_UP_OkF9NzbAKH.TE61RPepvlZUmXIRWKbY5aYgDvGx8Tcr yVpnVTuCQe_Atvau.ExCLiEDyyyVMb9IljgEYzMOzBF.MlTM.LwIOJeiQLTMHJOTBHpg88NzkPC6 ucjnY5wDSOtnjNAB562L.0KnkSw80gb8xunv04F1vruKGzC8eWaOM3j_mj1NI01T8rKctjsgE867 1JrYgbkNdI2OOYMBlzqIPTKXZLfTXU_GzVSx7havFEwht9e5XvCHfHpW4hNil8qzR5GAlBTuRuj7 MF_Cw4HveaAauOfGcXtNkzZnjSYMkPrXINWNMWn3ZVlYgg6u_6djtJg9KAgNqMo2wSEke2MGQSvs PYSU7DLlb_hn5NW7XmfO2uwUFcNbKD073c3JYSdh8U7N46yB6_dxcGSXqVGN4bEh5N9z.Twa3gs4 13dzihOGfOPmqLDYI4BHco2AkhAbCoWFFEDremQzim9hUigAYV0FA0fWwpSAcRJe7jaijUjS07tB BsvcbiH04T_t3_0AVWHozuWwYbKvuEav6e5EoJ33392WkGOta2fhkdDrX2I4Ozhx.dAqtwkrGDDa NV1myVpDK31zXufgHGyYGrzkqkmqZEJfNVTc7QQrZL5FyO_MXZ937IMqmkXMvKOcz8jYDueorQsA Kg0XQMb2QpeOtXktrx8tYoi4dpWrrjBhxexFQ9rxEKbvq_YPbWM5OPB8qljTi6e1Hrg_2QAEC.vS yuLeB7A9qTm.c1ljh96A00p5hpTlsVPApRBKipep.FVhlNDT1N.1QyGHqvhv33yDLN6tD6HUOqGs 1q.xU8U5FkHR.NbvNVySBlE44_ozTGXos0ptcSR5Lvl3lRP_38bglhbLKd7vFOVRXjbjcouFZqrK Tb3QJKeNsRLSaTnoR4hSF1qMbqFVzrzhnQVuthqZw48lXsoU9nNhwYnO9o2elf7pf1BiaqEvePd1 3anNXYbsLIx5.svMYmAlHelqsbG5iFAe7WMKNk6xZSYLAusHDj8pIQziCl_ulXTbdqN7DU27di5_ jrzESMozi_.ySvvUaBitgITsqdrHyAhODB0r7AGwG29tLEmKzI3pRU_zjFF_5mjLFSX8L.mBX1ku iYAWO9PFZMO8Vu9G4_suHa.a9mh4ljtAmV7ZBpm27c.7tshVubVNrwYPlFJjp1iikEUSPFTFUrdE gQWIb9isCvZhtAmzL.ajzuxUXDRmUkppTBpEUnOmfECBsYv9ugsIUhOTvenjjPu4RaNd_bQIX8UQ Q1fkdvK5CLk4LV9u5a1XeDOUjHjK5cKfvjWiDruCAfZVh0FSehuWndvesIycBgScqpYqG8P_BxuH E5w_lhyGtw0bPGcBz9dPgmUXwEGgCykEYOsiIorfvXfgLGJh.eT84Si9ZI1UgUwh8W8UXmkF2Lu0 jWHOsZw9go3kQjfc4wiyY.vu8_DUAKsBvb_HTAFHxfPV_8obOt854H48g3Je_vFYxppBjl7RkeWr TEiEFJHO.cJeMxcTdPf2wy3obiqsWw7JxX6Xp_PlJYRlTdnxvaADMmq7eFi2.RrihZBNEXC7Z0ml FtUk9hOF7MUDH2aYrY.S8QzB0bGWHUzCM2bJzgJhBlYHi2qXCLif1Rr8hKwWikE6b2kJYk7Zq92b 54xBDvir3xzjCkCT4iEEysMrnvVS68y_0ZipLH8UgEXqCJQ_5RJGR0FNmNr.2A_zdMNo3PT0qYwr SYw5b.aAZkcZp2rbsCYm0keXOvitsek.GVyJUY3IXXOOZ9YYR_tIBN95s43RMSVkGbwnRf.qPH08 OmG95nWLHcAQOZO.zY5t3BSdYEd_EL8zVKD6GMVFPdLATphReucIBkZAfY8g0mZ5D14VE89bVkcb 0ee73gSzTN_8Hkc8MsD2C1loJePnbbtLuBYMQQRgf4E3k36dYS.pfLrVv0DqTCjur6pGD5LO3yL6 20wyaKZMjyyTPJjXIn_Rx9BJd5vnJLPT7eGOS2zYJIDgL6EwJgmHuG7cTTyHicFfaQF_OVn.FFEA GdkZ1f8VfHG6oAe96ENLaFDib6hLM4BBQDoTJPfc23uQqlmn4lGCNpldC8SbAjcoJnElo8REX1Ej VhKLIosu7lEcJeupNKYqRF1YCk9.66FsW_CTr2_46uvEalqUwOCQIy4JCO27aPix_lL.tfwhOLbx Dwzc_lBjNDozNavWLs7fvWECnELMBGllFem2nQrkP2lBx.1o3yhVz2RIASFnqQuTrBcQ8bQi7bnR LAUlsvyrMEBbQalqo.M6WlxVnqVsD._oN0IITQMAXxF5c6G20CXv7S6e06Ja6P6h.0DCc95uJHdt r3prgh7mV4vdn7s8BtKFVKKEqbGOF38nyS4ZrTiAy2z5BfaASuQXwwFMF1z2qx3JtDTKU4UKTQiE - Received: from sonic.gate.mail.ne1.yahoo.com by sonic317.consmr.mail.ne1.yahoo.com with HTTP; Fri, 20 Nov 2020 20:33:04 +0000 Received: by smtp401.mail.gq1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 359628cbfcbaed5b6afc835050250cb1; Fri, 20 Nov 2020 20:33:00 +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, Pablo Neira Ayuso , netdev@vger.kernel.org, netfilter-devel@vger.kernel.org Subject: [PATCH v23 16/23] LSM: security_secid_to_secctx in netlink netfilter Date: Fri, 20 Nov 2020 12:15:00 -0800 Message-Id: <20201120201507.11993-17-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201120201507.11993-1-casey@schaufler-ca.com> References: <20201120201507.11993-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 Acked-by: Pablo Neira Ayuso Signed-off-by: Casey Schaufler Cc: netdev@vger.kernel.org Cc: netfilter-devel@vger.kernel.org --- 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 Fri Nov 20 20:15:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11922325 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=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,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 C84E7C56202 for ; Fri, 20 Nov 2020 20:34:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 71D2D22470 for ; Fri, 20 Nov 2020 20:34:35 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="O72GbikY" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731356AbgKTUeO (ORCPT ); Fri, 20 Nov 2020 15:34:14 -0500 Received: from sonic317-38.consmr.mail.ne1.yahoo.com ([66.163.184.49]:38561 "EHLO sonic317-38.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731087AbgKTUeN (ORCPT ); Fri, 20 Nov 2020 15:34:13 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1605904451; bh=crIqKrBUbHMKdYYxrt77bD80SLwg23JaX4cbNu2P99A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=O72GbikYBYcS3HmtC5K+vXBBceFCGF0mbWv40hSqM3WtGxh5O/iSlYPBOcXSTnEw6sKJUsGTE9HcYny/eKX/6uxBFFbl9o4snxe7yOdpStKJug36Yds5/plWHr9gJO0bVl8ihJeP5DOQ+r1iZ2d3pARd/E5eHX7j0P1zv0l+fr4xwyVdHmI3d+9ha3r8YS+7dHyDOEjSaKTpoB9ACZ+6B2cqaH0XomWk/MuZO8c8aWBD7x3TwuDWnlUbElnerru4Q3nqYchY2JxBkc6VyZvA4kFLC/xigTW5isQmHj8zp6d1lMlpSdq3lRP/7dQLc2hkqS//lqc4aXVyS5qbmlgatw== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1605904451; bh=qi4h2KvpvCLtvMIdMLsAAG2aIC7HvjbX/iwMdzH/fi/=; h=From:To:Subject:Date:From:Subject; b=BBgP8/qWGJCjNEBXeupytKUdTNbOt6Ci0MseZhXTGN2YwxzSa+iL7OlwuDtZKFOuHkGIRAPJ4dERf6+jgM5lirBk6eMNLxw7C/V2cg3OmfP+gk3a5PMuBZGIzhecr+YArkIB9ey1TXt10LCGgGiabvHO4/EG13EQLfmMIDMbegf9aDd3GUnnmmd14JLE+JD+Sjpa6LbCOr16v4+aUJvXt7R+nN16Bg1vFyusjdyr6T+Thv7Sra2Rvkb2VKw4NvYCaTvrVLhbo6FpiGC8E1y5mykXpe7C6EUB9odUqfSNuJ54bcSoA96izmHVmbFEFsQFaLtgf/GVOlyxQ6Ek+jABJQ== X-YMail-OSG: 9MdtufsVM1lfd_ldlLtz_yhQ7rMqQmpbYh8VLShll2PcsrG6j0HCZezhgcXGwaL h03rBCzYNOgnFawGuoRZlZkWI5ICagJQxHtx3L0C82HX8sz.x.ShR4oE.jCxqB8hRdxp817MYg.F iqcykI9LQ_.c8z2CHWpn3LivNmJ4khvK5wDLex8PMjLUryRjXtQJwHv_z1LSHbOqLmDhgCOwQHwA Jve05K6vkICrY5gMaI2FpVghpRlpmgPcGXdBNvYgkhyDEsHHqbMrzu6.s7LXmThaNh8cpmzLs57b rHjn9402aN.2Y3SrlG.hCgdhVLSROpy2u60KCy748Z3owceHGZtUKE.hfX1qUFEJGqkMv_CxUXfM 3nLTIuAqjF4PwsbCfvJO_Yyfq9HjiqZuN4fj7Ye7_W30l.lrkHtEvKGIoRdQePmD6onwt9uJJybV hpXGZgu4nFMiPm1Hixu5R1uviCALv_rDnH8Rh3_LQVk9h6UdmIqO8fj6R6ue2UP46n1xGtYQaV.y ssbJRy1pIOhCPxAWWc1BrIC.FeJlCVCI_9Jmyp3ygKQjgVPRj8BlORJuh2Lquttdx4OFqJd4IcMC uXitWw.KONOiM.JhUA9khQroGOkCm51l5fW2NHuPYnLx9zcBS6PwrerORszaqxhRNuW9wuHHAtDt C2HB19xl6BwnhDiXuKkQjnfEZUxXYUdp.s_P6il_KuEmjcrwdHZ3p.Ru3iXOhjuooQsVQdkzqVVi vb.X3YlMTOEtvPNziArSFYul6Fvvv4NQ.YxubTRTm.RgNA1U5APmJbwioHtlKEo82UGasZiR0DwK R45ucyZv4cI5kYk5EXwqKGZ6lwjqVl3ijvbwVsWkpmh9pkCq2ckf1LY1sOX8R_gmHaYHdyjVSu9C Ii6B5FhB6PZ6OoUodNkiiG1FaMiuAL327TL9cSucbAYu.53KO51cYh4As27ekWmKEhGqEr8YsbOj Uls4ovaao2WinM7Sxb5QPDtjtf90Z6cnrjQhLfM6GJ2nIgA6Ws0xanqo0CQCMSz9QqZZX71xvd5M P3wJlCiEcp_Dt__eHAzPrD5Mz0oIKuJG5I7EbqjQ.ASXluXI4bBbH.0lYToKMmJrffzsyKy8759L veXW_0QgQFulgt43vuL51btSO3fYLmokdWzwBIZhj3PklsCxJN.UL8Txl.57jlZZach_JsI1Y_OM 86IFktU4MpCyKpqX7Uxzx3a4cAYJzzK7Dr97VDHeh26dZbTXcNEGw821SBxU0pNh9DpjTm4JsPpJ F7ldq_Cq6iFzDS8BP73ITwXlfSc8G_PnalOZ.g5jX7AcsEbufGB_36t6hz.6T34IxjtejWAHdUfY NjModikOiuWn1pktuYqWdwsOuAfikR0Ao3JK4f9EnRimRmitGTocutq7.gbYKEC.yHWH845iNgCw opOvXO0qXC6Y6Qel3ucG36jG3OajXslZOMfTNK9T84HRzq23koa0liUTejeTVJ4hBqJc0JtAdBPD jWqbgK9kIEtEre5MsmvkADqztUAw5yU_uDAbqFCuNK93YCGFtonAdFw1Z_Wq_LacwYyMm.irNJBB OnQzSZ1_7pH0G2VonWBU6qtaeKuhEprgG58DTYBRnNF3AaymaG3hDMgLtJkc_Tv7IQMaH0brBw4p lLe7hqpFAvaj8x.S6wchC2orrjqf7UiIShTV2uxZOJc4vJE0th2ARg1T5xg6P4OQUsnNvFlBQABD Sw7e_E2_Lr11FcaYwMvLj4TgvW7V_1uo8k_TbEae1QMucux9lQKbwB.zzOdSB5ssvn89KKFW.bX3 kvC7GZzkLg_BY4wpcspG4bueSNnbhrjUMahWb3Jc5pU9xlEdELNYtr2HFvWlmLY4EcfcuuPP1.gw zCv2Kvy5jiHoWr9RrXDsXDcMkK3eaKMvrAM.Wm8vHovhoMgSSDvZpcPeajVmbAdCNPLv_rBKwlFy tCLP10589t3aOxWW1aQGhcdpBCr7MTj4qm.x9aXX03MWyTdxELqVpLmSG_E_25YpBrAmjKvR2LZs bsKi4Lfbepn6iEA6.boGiVU4ulHoIFH1DiL7PmkcKP6iVLs8w2XP.YcNx8ZHGv8EXEyKl8QblIHn JmczANlLzVPoyrLDJl02zvV44ynHz4jFnQQlGLJkuwIwQj.dBXuLEY_TU0.AnXC3qux1EQdHw_gZ 6thbf4HqSm7XTOtdfouEYH873fXgb2ceGoHiYY5cRChbs5kSMAmT86LdH3Se2vCKPo5k55Nbb75_ l_EibztkjXAbRHXPWDRjg8e4CNMpJVUhhNsY9kX21gJVD.zcr6G4kET86taJj8ReaxPLBDYiBL_1 5_iq4UsawJpG8EBV4GyC2JSsoA60OXtco4MIJmnbu8s_Wwi2toe0BNb15X6C3W8HHhWd45FfjOO4 uO2PW4R1Lr2t0DuK9_yzJmRqC_dUxJcb6gjvJdxwhCIo2mScXTgKvOfetb7WK4Q9M_tcrYtWslm_ pTcGZ5LKRnpQOaHLkGmcyzxJwT0BsUdNVPsurRzAN9fJZ8FE8eUHetWsPmKIy9K_4.keLUrZ8mZA 0Eg6GWB1DLc8jCMZ3PBXB_I_PvPpKok08U3guC9hGLa1e3gTODJw3iApOCXp834XLt35ur_Ef8ek CwnKwgxd._AiIsL.qEXusYaFJs1Q3zx071E_d74LLu4Elw6KmzsfT55T.w.5GQ8gkFqwvv5Si5d7 TTJgjpR8QAFD7RJ.1UisNFFoyqwiWeJL.Hjb96A0SUAg6PCSI7WcIbzTXHWenXdV4LfsTSCf1CY7 Q4g8asGOPLGCPGCLa1g7oE45AXM6Kk.OGLoac6KWzH0ltQcB0z3CmxzRhIPQ055QB98Sf06yQ6K7 B8dK7EnqjR36w3Kx6cfhWiFlUiIJ6aRa0iEwVyxsHPn3s.KCvodKPxdK5oCeDmh4nUj6t.LjQ6Qv CIJL1w8HU6ylGBHCBNPFp85jjTNsMexFpA1bypk_P9gBapUNmNhUrfWbVbVoRzGlF4cr_zCvbEQj fJErrF0mmynzGwboEMg0c3SMuvwBlyMocCecsfmHrMYoUMG7nqRQIa78oFZ4rf5hAdAcdUr4wrCv O.ZOMkm76PG7cGjBeSoQsPNWtn8tnEDmwL84.Kc_46Bs0CIb1yb0pMS92DhqqNUkohVZJV9.KwqG KoqYPEL50gzd2epq9vYPl_B97pasYV4uxLpnokX8LHJnNKoQljEh3xe0qWwnqxrC.pnPIhBTI5qZ CZdQG0Say0vrc2wm682fpqczA8qFe9eMZFd1BpDZPdi1vCiNJv6aYnqktXFh2scmaWo.X_xFm1rd 5FQfN8VfePc6NM4Ca.9bkqr4GU23kc98StFLi9X479keb3IwUlqyPlD6vUv9RzDNuwOzU4r4NXWK rbFQicOL3aC0F4BAt_i2XtGVyv41JzBje_iCsIR6B2YIOR7zxyAdPgCDz_nvMuUB2RR5Ls02o4u5 v Received: from sonic.gate.mail.ne1.yahoo.com by sonic317.consmr.mail.ne1.yahoo.com with HTTP; Fri, 20 Nov 2020 20:34:11 +0000 Received: by smtp410.mail.gq1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 8f5ecd6101be0ec9b2e955f6c5f9e05d; Fri, 20 Nov 2020 20:34:06 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov, linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH v23 17/23] NET: Store LSM netlabel data in a lsmblob Date: Fri, 20 Nov 2020 12:15:01 -0800 Message-Id: <20201120201507.11993-18-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201120201507.11993-1-casey@schaufler-ca.com> References: <20201120201507.11993-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 c423c7cdd095..ab6375d952ea 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, @@ -1512,7 +1481,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) @@ -1525,7 +1494,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 a37afbb159ab..c670eb0a9515 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 3f96a7aaed6b..06629441b663 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 Fri Nov 20 20:15:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11922469 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=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,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 0F826C63777 for ; Fri, 20 Nov 2020 20:37:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8EC312223F for ; Fri, 20 Nov 2020 20:37:33 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="fBlID/zD" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731512AbgKTUhd (ORCPT ); Fri, 20 Nov 2020 15:37:33 -0500 Received: from sonic302-28.consmr.mail.ne1.yahoo.com ([66.163.186.154]:41414 "EHLO sonic302-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731284AbgKTUhc (ORCPT ); Fri, 20 Nov 2020 15:37:32 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1605904650; bh=JextWAp4vg9i2MpWbzWqR82uz7OuRXg3L2+ikFbGf0Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=fBlID/zDCmqw3uY0U4K0AVju7NoqCseBtzrxPsWgWGCtb02FgdjVphP/zCDICLRUVDUwfF1bWm/QFxY26XYgC0Z8NiRoY284GolKT9tBoEGAhP6bEjSGMI7CLGSNtrJHmk/Vkpz0LVEZ9HfI98vs+FSdDn+v93Kui8RJCSiH2aW4uFPQy5uPZqvJRuNTXfb7hl6+B/Fdc7ZQXnKokK5yw2KrYxCfjhx+HzSKToktyoJ+uaX2yViCOA0YDNICjH21Tx0nglSGXF/GHmyOoGUmaxstZq5cyHb9dVJPioAic6ysvqfTTyfxp03J0wKaLnk2IxpMMlWOcM3FVqg9ugngOA== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1605904650; bh=iRq//zmHRdMUP8RUmRB41dLcbqZME5ePvED4y2PqUnb=; h=From:To:Subject:Date:From:Subject; b=m8bamwZrlV6sk42ieYhveaO9rXN5ZMazFmZMA70WxtH9Eq3jJwe96pmuLJqGQ1E9sFhsnfh91aOa+WOJA38UCFkU0yjnQZm441gAbGCs9fqMays3ueFNE8Aw2ldEKhWOscoBHjEIk0qjFgCGEEDhlzQWsXrA/qJKD7Q5oSHf3E6oOa8SchO5X6LHwVb6070fF0WBLrKFW3fAdnyLyfxTOTyKBx6pqdmGb5Y0WUJOEvBKbvBAe6Jh//rp4Y1RRKC8V++23/RxaGayRr7UjTx1uk3g9lT41cmltKIbHJPdKTB4zvnKl8ip9d6ctEEz8riP9Wnj8d4OXNB/A7H80SqOJA== X-YMail-OSG: mOobivEVM1knM7hmOpdpar.9uiUiRCPy1lur8e5xK5cMRlOJEARDKiLqIQMjttE jnn0.5qrre2KuUsLZl7lc21mC9btBRwmedyOdW8Qamnc1HPcSsZ_xizc5ggBeNqCV.Cs.VaOas4E ZqiUNC5yrNv2eAUSb.l7y0Bw1pfFr57nvagQ3X0rLsZP8S.AqdeVT2081x2A8qbcVpw4jBi4Z9b8 2IVkUpDlnWd.Mjvq3Cc39vvBnVEezFu0I0nzzWxRqRlCFShPYkZQVAOdl1uKOA9Tu_NEhzjlOeyz NUpojzYP86MN_lv8Si6rft8qlObrtQwtmdS49zBrUZ1hRfFm8Hs5GzTU.BkDJqgoFRtKJFl4n1nF NiY_X9cSNgmA5Pq8khQO6jC.pZbPWa8FX9q4eN2XST56ZIqapVaITNQ8pdW4l5tQHDo5OffZZ3.R U1DvviuesOJi2Cvy5lFpd5JhDXMLtnL3UdM4lUHgpmVYqauRDNJLGQM5XTl5Ucd0h3MWyRaHWWx9 ClGjppNUcgzdY0JSgKNj4TFz2n_kK8hZux7xZa1TDXr0TA6G4qzqd8XvIuObB8zhAZ24jPVLdyGm HrtO1_4molxSXOvHUEyo3zBQxqdMd.23ak0oQ63DzU4zt0hIKm8oNXgKQiRRY6a78sidtUIAzSz8 On7NWNrao34UOcWIm5VUNoFWUf2KdD37muiufIbgNfZJpHdpiSyyrTX_hJeSMs5j0toFl537KCJS 13Ul3f4ivgEZsOJE3ahucURkUl2rUvfBMttl7_y6JluW2vGOyEm_rb58hv8AEdR3UGWCOHO7v8ds KUuqtQmMNqQN6ZK.RpoDIUo3NiLaDaVwP85tAxhaYCVj3WjBMrSJz34NbBDVKOYTVI_.gLHS.ABg 6zjqyURAE9pzpphORb9f4IuWpJeBqO_A5dZoc3mvX2oW5lPaFYaeDPc0M5FfIv9jjtelcdp1Nx7A orWxRKYpSESiJUArmlLav44eFo.eRBb8Uzx2Y.rj620LZ24OsBnDtozk6xJ0kcah5YERqFsoBbZx E2FL9L_AhSQuP6cX1bUo7kBOHyF2K2750g44_2lZsIXIx_u91fimqHauBaWj_Hc.yVy8dnAt8VU0 Q6Hj9GSf27oURAPDHS6Zzz8B3S6hOFk_zgD7WGtxTnjINXyfo8F4MhIyxsHWTeaeb8qdrOmsBvoa WIiSGPydfj977cbmDsiVxdwz2i_P2iJSpKApoWAb5vdvhHTQCzFrgJnSo1fpC94kWoqn9IKLlh5m UETGtDypFTq3uyEuXhZofujf1fvD9ACyOAXWAq.nyorgg3CEm9xWY0qJudr8wSYLvmjYHoEGiYog b99EaDJTxNg8zyYHz80EY6rvx88gu5lMHnJ7qEPWxn0DlFWxGS1iCHe4tNI9w3Vx0J3gANoNyVjP kmyjxhcxs5O33SynV2IWStWAJuv2pZHYF0Ucap.OtRLcpgdjyVzaoIpSsajahLbca1qAjvaT.0Jn o68sEAGB5IaZqLMXTHjZwxIlL3WOtv2U8UI8x1.XyCCt6T3IPA9lAc9wKyyBF1mar2ufZBQy1GTy kFmI8K7f3s0HYew9LZ0ROhPCD7ySdSmjr61TScsKDTFpghFvmAFG0vzAolgDtHgJsiBcBuPsBm95 LZiaQHRxOj5tO_uzDCGwxaxfhYvnqw3aP4EHlhKG0gjMWqs81njosCkzhwsyC16q3Xr5_wguCZwx zU4jcv9M6Ju9A.UXwnMn_rQKgNLfIZLy4kFolsITge.lWVseX7wd0RrvEdaBsPNvRiuyXt7iBOO. 1uEnIHmNVNlCaxcg2Wm48T2W3bL8KjARulyKqkwEH_cWw1aYbn4XsbDeVK6Twg8tBe2YOTecA9kr mvVAqwdsrr4gJm7KB2Ih7eY4OQYvP0kagzYamvKfc6WXCasTIZJmCx.jPi_UZWn.uu3hLs6n3NpZ tfYVXOniLjTxLatX1kvf7CFEZcDaW01QfMQAwKkAzsid3DuQSASahcuXTfLrnNZ.8WNFuq024wHv _JiXqpvGyY.saKGvpzj4NGaTBHkXIEpTRk52oNIHn5Q3J2O0n.AnpNN59vRXrbbzMS8dIiyu32pj qinGwHZ2vImc011CaVO3rol2hKDt6ZvZJYs6UR6r4VsErz7afhKQT7sN.k0t_WzW9.BX4vvA4FUS DtqCbp223ys9S6d3sBxDt8I62xRowGQh_NkEQiase.WUaQBB3Pry0S7qSmq4zNJprqA8txwP_hzE hIBo1vg4a0OE3xtokRexOFTPq0psAvTThcu.5rXE3PBOMthHf0MFL7yn.TXG8j2vB43cxmrP0wga HIMuqZaAVGJoQRavPag8SlSyH3icNv0XunI6mfV1r48PUD1sBn2sVieY1hYmiHxQVdLm5mQM3bty pwiXt9IUcIaFMLGZaXNPicszAU58tcPymGMdRSQkRFpOGkep0ZUVv2OKNc.EvRJ5Ax_VZbV1_gYk uO8QwK13kPmk0Qctev2lWnTjdnZDsxl8yQakTHmEd_mOazSv3WVwkCrB0RBR6d9eC6mDZ8.uefk9 7yUfhQn4YVxtBa2zIWKe7cUPWb8iJz4QRihm75pLouta3K._iRR6H83exrZGCztXbApPc9aEFpjC jMyFfsWL8dgRVk4m2CuNA4WkqeSBCcBAl0BP1PxV_AgteL0XCfjAttHbTLB0TBE2KAYvW23o0Twy jZSZqEV3tsB4fMNXOxgr6cRq3J6aDhB_LklFG9rciuO1sK4Bh52S615XwZopN5IO8vseWNEvWjV5 V0TBBJgSckIhXS4GYbSx8knHcO_3vrbhgCn5L1zDbMBm2tlyMmfZ7HaWf4hJ44pw.guzY..Fl5dC 3XRPmcJ.ecZC3LlruF.Waj6g.4rUFnSKe713CTRRBBzQgrvsYY_wm9L2HqD_4TUPOxlQb6_74w.J ujxo0mPsC.yBIVXyp6N7eTogAj2TH_NKX4C_MUFOddqVHneujuqEi4_S4vV8dGV0Qynl_nf90GZ7 JT2WNsV4QvC9jC0ODSm0Y1VuZ.qUUvU.5.AkGPN_QXvY1PgdJkpn2mz2xI5fLsmoJ6IiLza42mHY l23kCpuF4BIjIVuEoypEtam2182r9FS2vl1jzNQS9Dtt2ETa_X9ROJ8GKZlODr9wGLZGJRQ2EYhW BHEorngG1NbwW3r_0Z2JlNCJhiibvvPQGDqv4d48.8.1n0HVXe.WdUliilcrad0mMd82BFNQ72jg xUoIeZSk6lSMoywhDP9UdzmiDBSDnJKlvgxdvHaovYbsvL9ZZkt85VZvRaeefzzgyVWVLG6qrtQ6 _zdiW2zFprm4UIJzmj3KoLGfgTIS2_AnConsJYc7xMRY9oHgn8FuCOP6aP.3Ich5zYXMR_hYwrx_ TpqxAxW8OTedJg2ZRb4VBIf9enpCcH9ExFmKyOOxfhgNmec2O1UhPw2eggjqNSHp8vPeWKZtBj64 kZEfQlo8XaNQtbxWk2fF44WPSz_6ntp035arNBnPq Received: from sonic.gate.mail.ne1.yahoo.com by sonic302.consmr.mail.ne1.yahoo.com with HTTP; Fri, 20 Nov 2020 20:37:30 +0000 Received: by smtp418.mail.ne1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 5052a7be9aee4e3f9a7d5bcaa0df0862; Fri, 20 Nov 2020 20:37:24 +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 v23 20/23] Audit: Add new record for multiple process LSM attributes Date: Fri, 20 Nov 2020 12:15:04 -0800 Message-Id: <20201120201507.11993-21-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201120201507.11993-1-casey@schaufler-ca.com> References: <20201120201507.11993-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 To: paul@paul-moore.com Cc: linux-audit@redhat.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 | 72 +++++++++++++++++++------ security/smack/smackfs.c | 3 +- 25 files changed, 280 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 ab6375d952ea..028670b72521 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, @@ -1528,14 +1531,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 a77da7aae6fe..23bcf0bc9e40 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -2742,29 +2742,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); @@ -2774,7 +2776,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); @@ -2792,7 +2794,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); @@ -2807,7 +2809,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); @@ -2821,7 +2823,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); @@ -2839,7 +2841,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 8803347424d4..cef9c20ce0aa 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 interface LSM slot list. + * + * Provide the name of the security module associated with + * a interface LSM 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,31 @@ 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 ilsm) { struct security_hook_list *hp; - int ilsm = lsm_task_ilsm(current); memset(cp, 0, sizeof(*cp)); + /* + * ilsm either is the slot number use for formatting + * or an instruction on which relative slot to use. + */ + if (ilsm == LSMBLOB_DISPLAY) + ilsm = lsm_task_ilsm(current); + else if (ilsm == LSMBLOB_FIRST) + ilsm = LSMBLOB_INVALID; + else if (ilsm < 0) { + WARN_ONCE(true, + "LSM: %s unknown interface LSM\n", __func__); + ilsm = LSMBLOB_INVALID; + } else if (ilsm >= lsm_slot) { + WARN_ONCE(true, + "LSM: %s invalid interface LSM\n", __func__); + ilsm = 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 +2316,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 +2809,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 ilsm = lsm_task_ilsm(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 (ilsm != LSMBLOB_INVALID && ilsm != 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 +2851,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; } /*