From patchwork Thu May 13 20:07:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12256423 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 97E1EC43461 for ; Thu, 13 May 2021 20:10:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 59E2961421 for ; Thu, 13 May 2021 20:10:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232470AbhEMULp (ORCPT ); Thu, 13 May 2021 16:11:45 -0400 Received: from sonic307-15.consmr.mail.ne1.yahoo.com ([66.163.190.38]:35732 "EHLO sonic307-15.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232471AbhEMULo (ORCPT ); Thu, 13 May 2021 16:11:44 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1620936634; bh=xolFaMNvm2tIVaWXyA4u0U8669PmDlk7bKd00ve9fDk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=lignkVTJ8dGuQ1J6IRkLpO3kqd+oO7RdZw/yRng5qvpNZqllWyWhxNVkXorE4NSDgoWpuT88tkiQe64uqVD5E/+3qp1ki/Q+MD9B9KSdvQ4ycrDLg+Njo3tTIpZXPkPnnyh/Fjrg5l4dkGQSAHYb1+fCK1umKJKIkBNeDwyn5ILIzeIlBLwX7tKSrthBDYiAHsyJcSonh/+s2WlCCjww5Z0sH4htVg7L28FwK7zS9b0nl/eAnUwIRExy82KtLLOsRwjiz2PJHPH94WFq/45F0ijji8uygVwHTTQg9GMFE5O+cK/sREwx5r4Ywo+JPOCaY4taiMPMDEmakQ19zsR9cQ== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1620936634; bh=wR1AnYBj4kPNDmOafcapwAV+hVImkL2ZewE36sYPFp0=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=XtDAAX8xMxJp+bsooiRO0/ythcfNogjAmrOxtRmNRPUCO2nL/pOahJVcnh1xGcPZVGzxiZ/hgaRQs7Ky7wLYj/BTZl19uFJg70F5S3OWHmNVRLkvnf5AtKjOryTLLZtflYz4h+HzRteq6qJrOklqW3R3TTyX9Ut5PqOMPC57FtyNLnISW/hNO8/k8XYGmUEvdjy3oDvJXIoTOKWkdhmeVy6E1mG2Eb/ess0zmsgq252njgrYDbHcxWW9Xb8w/c7saA9FtCsgEmngMmEB1+wgM+SXBM5nqfgp34DkCOC7hLqvMzgaW7E1TlJazvVxYwcwmlSOHP+7FnlrRqmi1vRDKw== X-YMail-OSG: Xy6XT_QVM1n4cVljfSEzVoRj6qUoGo2VupzMWVuccc.w9KDDaaiP46zGuYVqa9Z TyKg2x9VdB8LB8xG6TALsRwBGCgJozFbaHTClM020EuHp77G7IWLivmsHzeyuGDQlgtspjqZjP7C gtGx4jfrdCjwHkJDbUbzTZOSWnyxP_OLpG5AUM71Lk95.7PkU.dHzg1AhGVKFqyc2IK7m914m8Hk nWP9m.NUchOW7A8m92s_Gj_izqY4O6yoRGW7str4umBJXvxWt_vlbAdoHX7eYepHzOzha3ZOEdY9 _4c7KBQ_07eKevL3OHfff2JDRND_nyXpRAmnTw2UNSSGS6_jKzdeZom5nDIVK9xpe083zK0CKN3R 3m9oclH9aJj0Gd9VZozNLnD68X_xRIxDtXsOvr67SE1gBCb1eQEw9.5chp2ONWfwU4grr7Vu_X4q G3Yy.6iCkSyyhzXPdiuSGmSueUU.ye1vnSSQqD_ibSVsRHMtksmTazxAusB4VQd9e1cwrJ0DZroc ROluSk6CHMr.fjD2Yj2WASTyrHs8Gh7.vCpTUxqD.qp3GgdFIqAiQeDwDni0jEHOK7qK7GYatHfr VlQBIe.clJEzhLqgtXCHWrO.wCRAx1eb5EFrCEAZtcZrxPoy0W946LiASuKeiRFEtFfddVSYVjxk 9Top8uMsaEMSaL2jQSEBvAmtJHn7Uhz0MaT6TCwNeOTE339OMtRjoiqdCkvTGEHdAbBGunTMwh5. y43hDyT8.zvRp3yDkj5ERSwkqbTlSK9uLYweUg_S6Scqit.nR.mB2RfYJZt59y.5afRKkobJXGuo lZaNpHimROET0dfz61Bb0jPPXc7fequdTXd0CXBYHx4sv1j_5lA01gcl3YYaQgW5tfBxOXy_eKCM xOqv_cYSJwbwduXPlw7Eno5AvPEO26MV115F3YFjGgyqtNtNqIct71.mYeKqIv78UAjK0yKeMAjZ UJgGlOjk4XFe9HFzPV6Krszu6fJg_nLITlbBWs6aqJibZjm3HT.spTE0JM5P9lYY3KprCgRpEYiY 7uvYtS.brv..Cgnty0CoZ7gz4pU8f09.1qyEsW2PskePFB4KnQGDIhRqdxVbPqaFmAiwYjo3tYzZ 5P9a3iMwoSB58OB0f9fFn1oWufiUSasftSd5e6pfLvFmbVK9NSMfGlIPU1MEdUIxgYInr05YeiP1 1WFJPS4_V1cCR48IeJ7.EJECOBNcZlTWL5FiQ73YxUS4fYBvvgVubKt7c9wR5acvCBNehkrOq0_I i_Zg3DphS0YlrGGCSfvPC8GHh_e0ILHJKBT_9.hDXBSBwzj16bpGezEi1I7RY_zRR.hV3oiSpnBD sjKBQMFpTvEaVFj_PpzILCrFKHoOcOWEWon.0x1I1n2S0q1XGoqXRLcuAk8UJoZe.OZ43333uAZ2 B7RiJ3TPXQaD6n0fRj5YekjuRtbZCE0zsZ4LwwjxN1g1pDruiASMc7.kWfNQ4Fdo6qS2SfR_Uf74 pkT4qC4IA7lASbskrEP8uEN3Q8vDYCmrd48Wl2JW9mVqggI4JVdGpx3kPKUyHkg7RHocMR4yo7hp Eireyy3RCvZBBl3EJP5fqjpOWVfroXL1ZTOfj9SPou00s9Xag7PwBngsUDLh4Kv2OeqhAIPIY65i eIXaMrCYM0tkisjFeYsK3HIkV8T.ojWRq6_FE2CU_ToP4Rj.RcsIUkCf0y4UT7XId2MfIGJZuxVh tCvdD73V7v9NS4nCx63vd2uoPe6xMVuPkr9Qg4IOPQLaSsD73nFaIN.fj4rcslkZh4IzHNQIpuJA LiDO93Hmn30oOTeMcWlZZ.O6WbZpgWe7j9t9hYmKadFItfChZAKfgpCoe6VaF9udwHeHd9L7l1z4 ecJE1snne4_NkEhkCkMWWHmU7BvQZ9nlu7_kMkdDVVHv_pRffxvvvIzlviPPgQjuxTUL63TB4_Sn zhU_cOUyh2SbUIPKnBPJJwTE7r.SLp.254tDoaVUGuY37jKHNk.1KbgVP1asHTLagwsdrxU6UrAy bL18QKLpWQrPsFskyb_gvJKkZFyiKtn_p5OQbw2UVaeK1xOZ3akAjHI9dbBlpG1Qlv_rb6lBsP7o r3sou34DLessM50vA7MkBsEevFNMp3twJCu_bLUAXhZ_Y5f5GFOHtve0Msq6xG6rfH19gyqfoSIJ E4h03gTHUhKwwC4wU.DXdhoYCgPyBO6iz9l.e0o4m5sUKuqTJ9JHSIbJZn_bLYT7MP.q7fIHJHHe TryIHKvyS2B_PUnpoiqFtGIc6Ew3YMl.BH_wIujghqeYtSoFOxy71QWH2j8PyNAIKwM0pxN9yNo. NKJP_Z2Ni6zYzVklIc1f_aJ80t1FYST5r.3Cj4aavFZjXaQ3Gx1L0OCJ.PpFB7kh482j9Iu0Vo.C cd_Hf9DRISBzzJB3AEhliaYAIymFSO_6E4NAM7Vxe4rxabVh08vqMIhMQQMblGwsThExUvyQUZTJ x6DOzFAf7jAlnYM.wM29KN.2z2I_vmSGEhFcou9KGsfj2J0QujoLHvlkzIzpdabg_mEfKTTVS8V1 hRh_EwF880uFcQjxBp0fUK6CMJwMlHDSHgAp5AIJiYI4ctMBdttaX79UXTMvnZPDIzROlArtSkSs TqLiA98g3WH8qs7NdPPO0BfUYWopdwE0gri3HItES_0CcDlDlwKokBBk4WiuZBzsqMprsjQhTtho Ct5PTfYzcVMZLuMK6XtwiJM3j.Va9yn1_eN86q_.qB4f_2ZromakLI8ZxP7ye_1if13Fa0ll3TuI dZg7skemTrH72o4rulfnPkrlSWmsv3TsvZltKAGhCE6P0OZVAZNExrjflkwDkZbw8IvgbkWDxKgC YLr6kcVugP32THqT_6TWk_FRfQZ2hk5PEKNqUZsm95t8rSKBfFV8nUdFnPSuhQFZXKOkm4rkbFX5 inrrdVrWyMnpEinmulyEoqHrvBXTwkJNbP_yCYCQVvdsA.TENRzzML3HDqaHDA27XytOtp.X0K.7 XxqgrgbEq7g0S0F07iL7Y2i_VdEHFO3S2eErys9vqyZ4A8RwQKqOLq0Gl2xGTjGGMdZW.LybX2me kRp9V06TsIN_ZtfUOZ5FwC3.cNDGMo4kxnUHKwACmBYS_mEsLRPdxFWCk1CE5B0jijuZ_puEQhba HyTJuMFfiwdKw8azHi8zbJJ0HtZmnD1bLa1pdMvWz9yYiN1iPvlztTwq7ZOWAb9gDYQs6gCu7I3Y - X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic307.consmr.mail.ne1.yahoo.com with HTTP; Thu, 13 May 2021 20:10:34 +0000 Received: by kubenode512.mail-prod1.omega.bf1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID c571e24bb6d9bd02ecd96e3664e8c071; Thu, 13 May 2021 20:10:29 +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 v26 02/25] LSM: Add the lsmblob data structure. Date: Thu, 13 May 2021 13:07:44 -0700 Message-Id: <20210513200807.15910-3-casey@schaufler-ca.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210513200807.15910-1-casey@schaufler-ca.com> References: <20210513200807.15910-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 To: Mimi Zohar To: Mickaël Salaün --- include/linux/audit.h | 4 +- include/linux/lsm_hooks.h | 12 ++++- include/linux/security.h | 67 +++++++++++++++++++++++++-- kernel/auditfilter.c | 24 +++++----- kernel/auditsc.c | 13 +++--- security/apparmor/lsm.c | 7 ++- security/bpf/hooks.c | 12 ++++- security/commoncap.c | 7 ++- security/integrity/ima/ima_policy.c | 40 +++++++++++----- security/landlock/cred.c | 2 +- security/landlock/fs.c | 2 +- security/landlock/ptrace.c | 2 +- security/landlock/setup.c | 4 ++ security/landlock/setup.h | 1 + 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 ++- 22 files changed, 262 insertions(+), 60 deletions(-) diff --git a/include/linux/audit.h b/include/linux/audit.h index 82b7c1116a85..418a485af114 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 afd3b16875b0..c61a16f0a5bc 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -1570,6 +1570,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. @@ -1578,7 +1586,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; /* @@ -1614,7 +1622,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 06f7c50ce77f..62588bc522ba 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -133,6 +133,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); @@ -1881,8 +1940,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 @@ -1898,12 +1957,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 db2c6b59dfc3..a2340e81cfa7 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,11 +1359,12 @@ 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_subj(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: @@ -1389,7 +1391,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; @@ -1421,7 +1423,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 @@ -1436,7 +1438,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 175ef6f3ea4e..392afe3e2fd6 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -665,14 +665,13 @@ 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_subj(tsk, &sid); need_sid = 0; } result = security_audit_rule_match(sid, f->type, - f->op, - f->lsm_rule); + f->op, f->lsm_rules); } break; case AUDIT_OBJ_USER: @@ -682,21 +681,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; } @@ -707,7 +706,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 4113516fb62e..392e25940d1f 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -1161,6 +1161,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), @@ -1862,7 +1867,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 e5971fa74fd7..7a58fe9ab8c4 100644 --- a/security/bpf/hooks.c +++ b/security/bpf/hooks.c @@ -15,9 +15,19 @@ static struct security_hook_list bpf_lsm_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(task_free, bpf_task_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 3f810d37b71b..628685cf20e3 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -1443,6 +1443,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), @@ -1467,7 +1472,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 fd5d46e511f1..5c40677e881c 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -80,7 +80,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]; @@ -90,6 +90,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 @@ -335,9 +351,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); } } @@ -388,8 +406,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); } @@ -578,7 +596,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule, 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 @@ -591,14 +609,14 @@ static bool ima_match_rules(struct ima_rule_entry *rule, 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); break; default: break; @@ -994,7 +1012,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); @@ -1004,8 +1022,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); @@ -1812,7 +1830,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/landlock/cred.c b/security/landlock/cred.c index 6725af24c684..56b121d65436 100644 --- a/security/landlock/cred.c +++ b/security/landlock/cred.c @@ -42,5 +42,5 @@ static struct security_hook_list landlock_hooks[] __lsm_ro_after_init = { __init void landlock_add_cred_hooks(void) { security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks), - LANDLOCK_NAME); + &landlock_lsmid); } diff --git a/security/landlock/fs.c b/security/landlock/fs.c index 97b8e421f617..319e90e9290c 100644 --- a/security/landlock/fs.c +++ b/security/landlock/fs.c @@ -688,5 +688,5 @@ static struct security_hook_list landlock_hooks[] __lsm_ro_after_init = { __init void landlock_add_fs_hooks(void) { security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks), - LANDLOCK_NAME); + &landlock_lsmid); } diff --git a/security/landlock/ptrace.c b/security/landlock/ptrace.c index f55b82446de2..54ccf55a077a 100644 --- a/security/landlock/ptrace.c +++ b/security/landlock/ptrace.c @@ -116,5 +116,5 @@ static struct security_hook_list landlock_hooks[] __lsm_ro_after_init = { __init void landlock_add_ptrace_hooks(void) { security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks), - LANDLOCK_NAME); + &landlock_lsmid); } diff --git a/security/landlock/setup.c b/security/landlock/setup.c index f8e8e980454c..4a12666a4090 100644 --- a/security/landlock/setup.c +++ b/security/landlock/setup.c @@ -23,6 +23,10 @@ struct lsm_blob_sizes landlock_blob_sizes __lsm_ro_after_init = { .lbs_superblock = sizeof(struct landlock_superblock_security), }; +struct lsm_id landlock_lsmid __lsm_ro_after_init = { + .lsm = LANDLOCK_NAME, +}; + static int __init landlock_init(void) { landlock_add_cred_hooks(); diff --git a/security/landlock/setup.h b/security/landlock/setup.h index 1daffab1ab4b..38bce5b172dc 100644 --- a/security/landlock/setup.h +++ b/security/landlock/setup.h @@ -14,5 +14,6 @@ extern bool landlock_initialized; extern struct lsm_blob_sizes landlock_blob_sizes; +extern struct lsm_id landlock_lsmid; #endif /* _SECURITY_LANDLOCK_SETUP_H */ 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 1079c6d54784..a2a2f462a821 100644 --- a/security/safesetid/lsm.c +++ b/security/safesetid/lsm.c @@ -241,6 +241,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), @@ -250,7 +255,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 e12a7c463468..a3276deb1b8a 100644 --- a/security/security.c +++ b/security/security.c @@ -344,6 +344,7 @@ static void __init ordered_lsm_init(void) init_debug("sock blob size = %d\n", blob_sizes.lbs_sock); init_debug("superblock blob size = %d\n", blob_sizes.lbs_superblock); 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 @@ -471,21 +472,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 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); } @@ -494,7 +510,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__); } } @@ -2070,7 +2086,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); } @@ -2083,7 +2099,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); } @@ -2576,7 +2592,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) @@ -2584,14 +2617,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 84ddcec6322e..0133b142e938 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -7111,6 +7111,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, @@ -7424,7 +7429,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 1ee0bf1493f6..5c10ad27be37 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -4694,6 +4694,11 @@ struct lsm_blob_sizes smack_blob_sizes __lsm_ro_after_init = { .lbs_superblock = sizeof(struct superblock_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), @@ -4893,7 +4898,7 @@ static __init int smack_init(void) /* * Register with LSM */ - security_add_hooks(smack_hooks, ARRAY_SIZE(smack_hooks), "smack"); + security_add_hooks(smack_hooks, ARRAY_SIZE(smack_hooks), &smack_lsmid); smack_enabled = 1; pr_info("Smack: Initializing.\n"); diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c index 1f3cd432d830..22f62c67f2ec 100644 --- a/security/tomoyo/tomoyo.c +++ b/security/tomoyo/tomoyo.c @@ -523,6 +523,11 @@ static void tomoyo_task_free(struct task_struct *task) } } +static struct lsm_id tomoyo_lsmid __lsm_ro_after_init = { + .lsm = "tomoyo", + .slot = LSMBLOB_NOT_NEEDED +}; + /* * tomoyo_security_ops is a "struct security_operations" which is used for * registering TOMOYO. @@ -575,7 +580,8 @@ static int __init tomoyo_init(void) struct tomoyo_task *s = tomoyo_task(current); /* register ourselves with the security framework */ - security_add_hooks(tomoyo_hooks, ARRAY_SIZE(tomoyo_hooks), "tomoyo"); + security_add_hooks(tomoyo_hooks, ARRAY_SIZE(tomoyo_hooks), + &tomoyo_lsmid); pr_info("TOMOYO Linux initialized\n"); s->domain_info = &tomoyo_kernel_domain; atomic_inc(&tomoyo_kernel_domain.users); diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c index 06e226166aab..a9639ea541f7 100644 --- a/security/yama/yama_lsm.c +++ b/security/yama/yama_lsm.c @@ -421,6 +421,11 @@ static int yama_ptrace_traceme(struct task_struct *parent) return rc; } +static struct lsm_id yama_lsmid __lsm_ro_after_init = { + .lsm = "yama", + .slot = LSMBLOB_NOT_NEEDED +}; + static struct security_hook_list yama_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(ptrace_access_check, yama_ptrace_access_check), LSM_HOOK_INIT(ptrace_traceme, yama_ptrace_traceme), @@ -477,7 +482,7 @@ static inline void yama_init_sysctl(void) { } static int __init yama_init(void) { pr_info("Yama: becoming mindful.\n"); - security_add_hooks(yama_hooks, ARRAY_SIZE(yama_hooks), "yama"); + security_add_hooks(yama_hooks, ARRAY_SIZE(yama_hooks), &yama_lsmid); yama_init_sysctl(); return 0; } From patchwork Thu May 13 20:07:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12256471 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 09322C433ED for ; Thu, 13 May 2021 20:16:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D6043613CB for ; Thu, 13 May 2021 20:16:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232627AbhEMURS (ORCPT ); Thu, 13 May 2021 16:17:18 -0400 Received: from sonic307-15.consmr.mail.ne1.yahoo.com ([66.163.190.38]:39052 "EHLO sonic307-15.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232555AbhEMURP (ORCPT ); Thu, 13 May 2021 16:17:15 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1620936965; bh=6peqJfPdN/dXgL1H3NqXlYMZc3JP5XfQeCnyhfKc7RU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=dt14UUH11tAWZzHS+TSilH3Q34L0U+5dKQcRst3667SomT/GwGqI4ZWVOM3xXpafx9O4wdAxHtgUclO6Kir5N1yMj0CwjI2SqIgN/Y8ebsO6Q+NeO2F6behOUcmFCyJArK932BhE2VjPCoXAK0XkVq1z6rinAezGfN8QlfEhWU2WynMPvFZRM/XaQMmDo1LcKCJlZgMXZuDwG5gk515nswUg+z7R7Pt1M8C9q9BB4qsYCMKerTGHLg9ggIEgjDxFecOoIYDnNxqApuuMKs5WMLa5LEwjsX72rfev48B1M5FySRS0bSoK7/hq9Hk3TsT5OahZU6espLy+s3s5RP1yaw== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1620936965; bh=Gs+ITJ0evIlZvvcfYK7S0hKd0UVk7d8s4XSQRkiQYxW=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=Yrk3hysg8E2B2PcXtwwZDhakLrsjw6SS7R6lRpcAKeKVekEtyebpNtSEY4dyCsWyMb9yXme72QFu7Jfrwrb3IMlzIVXzK4K4IjN7odUI1YbBK7XCtXEIatlaiLNmJ/11kZR/Mr5W8PBZEd5e5GcraLC3Wr10LP9bx28BgLZJVR6VOl+uHW95F/snWuyNHybOkEE1QWaBHUfeZEvj6L8ve/udQPcVJJodt3qXzygzeS3MZCNLbkrXodraO4unhvqE5bW4kpInJvJu4Uvg1jGEphSfmJxvFJvyNb72M0rfePrfmLaCO2gIi7nfxGuKdfz0WgulolaPPrGng0hwXSZ7Sg== X-YMail-OSG: 9WdD2P8VM1nJW7_H5Da1oJY8f9vHcSKGnco5UypsM3YnwuhqLAkjbcvM.4RYfvU FQutqzqRNerSsf4eJPh2rBkSCeOo5lFru.7eZG2UelJfc7g50oJGeYg58ZMBaRtGT1_EXbxfk9d. dtcQMUAbpdSqF6kBF7DBizVsdSQcal.YhuyMD0R7BVO4utLD33J4UIwHY6TeOtKJFhCI8PG0c87s A.R3YeeB09h0B8ljFy1fP_2zDnm2dvXmwDmW11heWfRjEGhoRPSo_3kJWNCymdfl3pAhpcMz63Io 9mSxkCMlO3JligkiC6TZXgL6kZlfkRT8YO1Dhepc8Hi1S.mG5XI_ky4UNVKbcKqtPDyTIVqsRFa3 OMtyaAm488jkgB3hWekGux7USP5QcQVH861kv9u8MDL9a6b9zCgt5LcgofkmQQowDIst0MGK4YOg XffQcZRGlNW8w1ft5sHwebSZbbvBt_FbGdoAh_NpjAQzzSWdHIQYGu0W48.3Z6j7hPpzKKzINzbQ tXFfg6TXNVnevKXuXRiHItFHiKAt7tJOGkLqm6giQhClMO2bdM5X5.1e0NLnsO4Hrrxk69LmlOoJ d5XgFkvEprsK3m3n8DhswP7QGrNO63SrOEDMJZ94BD7aKRXo7_5UoNkvPUOvuOeZs_22tALb5qCW DZjmfHJKVEjBKNWUquSe4DuTztWd5UQdOWQsBJ26DIpOlNKlo_T0JR0v7Y.IRCSqancoyhtNufrz NUKhq16AAkRy65wCTS.sMEvHIrrKi.ReRINxF6aM9e4faGGwoV0LzVvg_JaSurCJ4DV5oA51RCeN wVVnHQt_mrGUETkIn1Yf2u_JkJP8GSPwUfiUB7bPBJTFmeAfdSOVn6K6AXjMALU9_3KOxeOVfVUd g.ZdrGHBc9xPD6nRuWDBr6S.RIbEmeCTwge8TJx0vPVpxp4Cp9oRDaHq9xWbmslCxu22rPA6z1Wz keb_vHfiw4L3b6KSqhpZ7f5byMbq00C48kAsN2QQwFtYDjZDqB93xhFrNpGuv5izpIvb2qkzciT. rwPBFesBMzw2S5qivEpaVChgmaSnATRtMv4MOh7tmlsA9zGW4cZjBYfHEEN_mQf9B58mkOuz6mY9 Nt5fuAk0CYbClbxVNH7MMV3VYKC8aP78tlPmuX97xjyI4OS1Bbvf1v4fI398ngEIgAr4689vHTKs ltDTbIATdu1RFzirBh2pzt4S.h1rWqXO79K5ofhob64oqCZgKVMSanBsSMnZGdB6ckePdBHNrsTW rzESDFHmBj.ThL5I42yqJFOGIfoGymexxyimkmetqhcRvmaGy5afU4A.WroOAdit0SZ459f4NYg4 sVzQugS4tvRwfJ32WgUE2gtKcRdexAle1v.UEPclV3JrxKcqfIqOUsUYYUukGWT5JoRQCPKfmToF sMz_R1zCxVwxeuQGqVciPQDLXWbMXH7coH6gOIJrJ_3HEhyyac1L9WGMMSjYSopFd5DsUleuIRoG o7KCs3CTTqSpdhAmPOq5NYhm1G4.2gUv492Y.fuyfJeDYei_o7TKmYvIvbpHokPDOp0Rrj0wCePD bPosD2okldr5lLTfcrFbhIqSBQk7jq1fOZkp09_S4_4UPx2iTCVTXxHaXVDQNi1sipPZeuTI4xJW H_4zVZpXNlUHB8Tpguu7S7ivpp.IpKY48I3hcJB.wL_KZ.E3zYDKMExUeQrEyl8VmcK7THIbdi1X e_t0dmWov5A4rRD.xy6Zl0ixWdkPq02D3DzRPplKzvtZkpxibB2R30FI4UipGt3pCTjLTt.PC5H2 ydC7I0GXLEZRAvoSN2IfUZT4heY22IDWuMVx2ZtuqXqgNWcMqpOQf8gU5HGeEsoMSvObeloY.jho FecLAKLoJF2gDj77x1wRY3RCu5j.e2SiXvEN3..mu959w6B_1h_MaK2y1zZSw1n39miYy.NixHjc cedOQvjrLzEeAi5NJTvHdthjL4GgZH8LXWQjsPpo8aZcNRmBl4701ktJs_FeaOiSndRJglMp8cZ1 YysuKgVZ.8Jj2TQ2sYZP5gEioG_RV4_Kw3pF1AtSMMJmJSaHZosE10ojPTIyyZzljlsHaVBx82wV UoHJXz.DCP6dejqNwIaikQ4javtXZpuXpU9q8pSK_6.SjYVLtHTlXW.fPIGwRy25H__WLp3FkYhY kW3v9ItHaVU9gVQl9ogf5xmv9d6tPAXxKuvmMVoeVqPDb1h8M8Mbz.xQG2bsFuw75Z.yv_7mr3ey PvUIiKy9YCDSgwvnyslV3_t4znX3zU4Lv0tNm8BqLZ6EKFTwi6jMOOvYVuAjzGMyMlBVkLxEEi51 NZK7ewyL3xhwFxHImbLLCXbTL0x7Y6Li8pjL9w0oFP2jlB6i1wxQgvpf7tZhzsX_kO.Pdom2pzCC JQfKgIhGdCUDcZncdiBWqM2gVZLJ2QnAJODiXEMWg0T_kmKK8odKq2bXm4DN3yBBXxS6MoyXvnNa MFtGoBCZvl3msIRtyU.ZRSG1qN7H7T5_lTAbSYypNMqp5O_3TXuw0QtMs1e66l.8KHAc2beg6dZU mzZ7YShoK_p1Hn6rdGPVq9XdeJzk0e1s2CgZDq71IHTlUYLCzIZKXbzItUkvw2kNRKJjVjsrm6MZ UALwAVIxIeBVv8AMhA6M8hYW3fW5Qn3Uj1vczNaae5fkC6.ueJUCwAJ4lnjNL3w_uP9D9Fz8Ya23 TTemYThQNVTMWbKKuCSvh.ruY6W5JDb76if0jOUfXbhCQCAHylYTnqc3TY21eQbOwD3JTq1V3Kc0 6VjMxdrSK4FFe_WP07wz9UdkZ756I1sM.Jg9UYKVntmpy8y94EGoixLaI4Me7mf_NisDVJDmat5I NSlzuXd5otVcn3.5ihiDI2SYOH3vMRrDlr3VURhuGYjtTx0pd2sWblad1apGBSZkw_MhcoyZHILk 5OUkehQQonHeFl.jooRVPf79ESSj4PjbuJin_ZsWWbSJha4qPTpA_ObNFVKBv4YZ2ubO56WT6h.C ClAyYt4bP9u0_3.xCPJ7dUwCuh0xA2LLXWNRZSGYRLA2IsVZyPnvI7Zjh677mhZxdf5A36QXl3rN kyr0D._eRLOH4qqmT02KFFAWP9lHy_ws1zRk0B2uoBerwgqKSlrIbJaNJZFJixd_oRevfiZ7Q9vF QnBj_nHQ4tnSPPA2edDaXNxTLn.nVSWmulugvH1y6YppovqEBuLVxcG_PDRqpZhrGjM96tP0sZTZ hakti_E63WfHOdwuOjhQwtd6M8vDiAWpXQFhXXJbnXhvjHEr.4kqkraAbmdlFiWI._1o4vk41pP. 05DeC6qThfBCnPeVZw3DaSts.vacVUnIjbp6557loKxDlLMnfJ0_UWQ62PQ-- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic307.consmr.mail.ne1.yahoo.com with HTTP; Thu, 13 May 2021 20:16:05 +0000 Received: by kubenode550.mail-prod1.omega.bf1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 45557b7ca7ac37bcf3f99977e8ab1c0f; Thu, 13 May 2021 20:16:01 +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 v26 07/25] LSM: Use lsmblob in security_secctx_to_secid Date: Thu, 13 May 2021 13:07:49 -0700 Message-Id: <20210513200807.15910-8-casey@schaufler-ca.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210513200807.15910-1-casey@schaufler-ca.com> References: <20210513200807.15910-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 Reviewed-by: Kees Cook Acked-by: Paul Moore --- 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 5c664ba0fbc3..dbb1e5f5b591 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -196,6 +196,27 @@ static inline bool lsmblob_equal(struct lsmblob *bloba, struct lsmblob *blobb) extern int lsm_name_to_slot(char *name); extern const char *lsm_slot_to_name(int slot); +/** + * 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); @@ -527,7 +548,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); @@ -1382,7 +1404,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 ad845c99e2d1..b8e15dd371de 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 a7e01e9952f1..f9448e81798e 100644 --- a/net/netfilter/nft_meta.c +++ b/net/netfilter/nft_meta.c @@ -809,21 +809,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 498a0bf6f044..87ca3a537d1c 100644 --- a/net/netfilter/xt_SECMARK.c +++ b/net/netfilter/xt_SECMARK.c @@ -42,13 +42,14 @@ secmark_tg(struct sk_buff *skb, const struct xt_secmark_target_info_v1 *info) static int checkentry_lsm(struct xt_secmark_target_info_v1 *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", @@ -56,6 +57,10 @@ static int checkentry_lsm(struct xt_secmark_target_info_v1 *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 3e6ac9b790b1..dd18b259272f 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 6a8233d746d3..cc61dd46f517 100644 --- a/security/security.c +++ b/security/security.c @@ -2191,10 +2191,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); @@ -2345,10 +2357,26 @@ int security_socket_getpeersec_stream(struct socket *sock, char __user *optval, optval, optlen, len); } -int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid) +int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, + u32 *secid) { - return call_int_hook(socket_getpeersec_dgram, -ENOPROTOOPT, sock, - skb, secid); + struct security_hook_list *hp; + int rc = -ENOPROTOOPT; + + /* + * Only one security module should provide a real hook for + * this. A stub or bypass like is used in BPF should either + * (somehow) leave rc unaltered or return -ENOPROTOOPT. + */ + hlist_for_each_entry(hp, &security_hook_heads.socket_getpeersec_dgram, + list) { + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + rc = hp->hook.socket_getpeersec_dgram(sock, skb, secid); + if (rc != -ENOPROTOOPT) + break; + } + return rc; } EXPORT_SYMBOL(security_socket_getpeersec_dgram); From patchwork Thu May 13 20:07:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12256473 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 56ED7C43461 for ; Thu, 13 May 2021 20:17:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 22CF5613CB for ; Thu, 13 May 2021 20:17:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232671AbhEMUS0 (ORCPT ); Thu, 13 May 2021 16:18:26 -0400 Received: from sonic317-38.consmr.mail.ne1.yahoo.com ([66.163.184.49]:40446 "EHLO sonic317-38.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232633AbhEMUSX (ORCPT ); Thu, 13 May 2021 16:18:23 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1620937032; bh=K+g6ymJe1BwDYckxJIENQEgzeJI9bR03NQWSV9PeId4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=DrEPIeikM+mVF85KsdSGoY/aiMiauhJ56o0Af8Plypsc6sswELOiFgg3jzWq2d3Ofp53N5CTW5eD5ZuH9ft3HH/GQLizdjyP1hWNklCU8kloUDS2qgbbanWKPAKejm+RrY8KuTPSrlLlxHe4p0PJw7LiczP7bHaV1JNLcg5pl/E17/MASBivWuZK+BnsZCEKvOeDW/SrJMsJ9cv52SZSjzzjKXQs7fmXlqFipy13H1bh+tpHxBhE7C9tUr8uZGGwrRN9qKYrEBj+zUU7DWv62ImJakl/+3tk9DpiLWfYt3aYOnkAtxLI4TfWUZpiWEA47Dbj18olM/OkghIvcLlH5w== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1620937032; bh=DAQk3XROJJRhAfhdKRCd2zCtzYCOllSYx4VPu37/k9t=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=L/6x8gyf3dss/6/sfk9CVMxA7inkQqJ9rhkdaqecwMKTJlnZ+wpYo/Q//McqGOTeT63r8plD3cd0AanrnA5MCk+PyctOsGgzvKiztewYRb0sje7WPRv0GVy0rb9SnJucaFAwUdIdt2nzrXJRnseEkcCeaDEi2eEpSlKg8ArEWgMYaccbKDuCJyr5JILrs0zmg0OgbzELm2GO6xH7rlPuqllWg2JHTUhqGrkrh4zrKD0qEEsPkDVaFEXeSB0De3iE4L8EGz1QwA4KgcBjL0DSxtOu1CFljHVHsCITz4yaafc6WIHIJY/MaRmvJDY4s6hHkxNPfiM0JkC0uCwicAOI8Q== X-YMail-OSG: nSPVlT8VM1k86yeXJIWFUsaD1jxHwXWDgTN3Uu9tehskZbdGxZij8zj0cEckzOd .MBjPD41CtV56BRyXZ9BxyMBdqBDH4kPZlXGkBFEzERiAwJO1k8H7FaXaMHfoWPheVEjBYlQlSnM US72gcEK2kN2qelVbJDbYJJV2n3cmkVcRZ82ZiD2t06DmYmewh3IRgaUQIHOHMAb4gbKetZnh29Z n2HM7r3aRCvOPl0dmLNDqzt2bRlvg4LPNxJz2QBiFx0yvA2OfEwrL4lBz17Tv6e1Y9MsyFpL4RIv gQ.eJZuryaHA0EAZTYlwUi1dN1WAoHwbas8thSUCFPn46BwFdljtUeJo5LZBtT0nFXG4EADC.CGQ ul32w8t40z_MuCGnd1ZVfo1QW9gMhifG73y25HdoEZTPY.oJl.0ksrd7h6R.yeDApMfceNm6LJtS ZGiXtv4mHMdK_Wk6ksgAueq8swv1p7Mf1Rt9oN5kWT3VTJqPm_A3IvOYgEH1JXgqskBrRBM_2jnS dwICvItw8FLJEQvgSHKh0shIUie6DSQW9nD4JwvgyCuLefEsv2924OkQ2KF7t80HnCHS9ThKBRJz t1NPCwZh5lNcvvmsII1qB4CA3NuSqIsVjbP9_G_nH39qvMY8P6P78A6Z8qeUNPzT19rclrfTciVS FdDuSjUyKnhWRE95LJ8_DJ6VetbVhWSFsSOyF5228OcaJWZxpFDXydqQStg5i6J.mwG8t8RIwklh lc1dr3lHOBElZQHYUE_cKHsQr7_E1DB93V3Hu2oTXFNROlYdmL23Ik28ASql52ya3XE4HPXapn7E 7ihZm1g3qX7xm1Z7jT13nld59SD4PlMS05pOcvjG.oxVQr359i6aVF2s4E8xuN4nWAIRJHi5oFuV hLiF3wN935az9Q.lljuDBSEGG3OXMJaWFJcU8Zob4x6LMfBv863.x9e9SLiQWLw19f5Unm7M8awx InOiKw2LALLA.PCY4Mam_dHy00vPjb6.sD51lJlEYEY3vpmqPF.MbqbzRW4D82zyv07LPK7LGYhc fqctYMyLXej_ZjsQ9vDFsLxKMd0.N2nflG1B2oWc9agcyv5Rxp2E6IIwn2SCDrxR9IFi4cZcnP4X bz.CUbE.FXumDQdCUc_tv_LjAuUDamefM3G6Z73_hkrOkm2JjtaMdVqscSls4FYJZzDBFSaur4um YWbw6d7UC2ThVDmlSagqVzWUHN2siG0cy.y2OhtSzKt1PCHu95orMWgwaYK9K_eSeZ6oJ94G.72e dNcuYc05fe6GB0XPLqgmz3JDBUKY3ebCFpT6itZZtA6F1gsBBmUFCa9I_2bLqWZxbkIO_Mqn7c5s FKH9Xx2XzV.0k.ndXdAIbjBKTKvkT.oPPZQmixKmTG_6l9CAljqq5gKHeQBEgCfsXLQ_xrgmjeI4 0LPbUxeV_8Kl7oxLcKf8PAqZ2kHybPFuOTMU6sWfKj.HWek.7jm8s1g2JO4a_AC17YYBO54CW2iF j.k8NqoirCYmw4wM04T1QN2i8bdeKK.i3zDW8Oe4ZTGbdOY1bdGEkofmFRJ_VjYAr6wp2IYRMjQ3 nx78MWWXdrNNAVhLLQWt_7PEkVMGOsCn3Na7gbWaDx9939ZbyiXNovlXp9.x0Jc_5ApTgx9N6hyp eedtU0x6Jd1Du4wEHRrj1UDpLSrXgiiR1qrStmwddBOmtUJRwLT6wowc2RjkujEz_C.J9zQimSnf 76im09jfT679QCnLby5FUMQ9MXebuel5ZNKQVHVmZrc9DkAFCUtwyasW1J9uKq7lY3NBm79DbSzl U6ABdygZ6eP39aHKPPVIIM5LE4u_SRxDuAgftKisDNm8XGmc6oz_PqnXildv5Qcc09IF_5NJAj2F 4UKXLPwO1xanh1ptBEqWqMjJW4RQxgwnEy0A8kKUKjQ2x.U4FZx_T3ffFo5QHoycGNv16lPWcEjN fBMemLVSze8uZ9hbImvxIWQXJ8xbHXZCdjqoqT.JhPZbSsOIJYtD5WGcU5X2itfS8Qu7B3GhEwPw wSOj33o0UPg36YE0h1dT7xwEYgH0EzhJw5J_P0AiTgt23LlL93Nvaa7V_0G2ceYIL4dQdpZ0IyPO HMobCRTWCSEJAmm9f_pPX7gJ1aXR_ncj7ABdHfi7oOBjdMfawUosMjsnytQO_wMzdLk3aCVmcmXn yRGVyoxH.q4NLMqwkyRVsx78Rt.GTcQcNrBz0t.p_NUcSEjHZr.lNAykWl0QY_EG1p9DIqI5VpZ. 3Bmi.bFtFY7hTk6YAQQOTKRnIYn3ysfSzYzWAZMLvilE74C9fHOKBc_3ufrCOUe4n.eONRbtS2kp TBW8hE4I9Pfp0TJl653zLjN.KNdvZftcEGy1AkPoyi1CnqSjeMR0JKOKkBK5LYWZPF8qTpzfHFSO AxsVBN87VMexAEYVj8WnSemJint7QBTiu4JV1HQKWA6JcAGoUcJDVrTvOB5WxjyhDmcydWEqCcKw 5jbjtqxVKbn8uDfRjXEoJnrLadUcl.HHmTHDkoRwSG8tzYUVLj9TfmpQgTj5RmMwulJZN0Uh9vBR CwFNOj2m61M4J9_HaNYKR7ohKva68mu3TIMAfSFle2.hswUJRIBekay4v5J7mp7mqwSyoVoF2di7 6iIL2JgvBoyCMKNg_e47D69V8ocjp6Yg.92hKeyoSVfh9ZQZTm99abfHx_w9IouAGks6y0srynaf Fq4EcTZWBKNs4Sf703tmLr9lkVqfJGqGmYj6JoQtaEg5CH5WESMmpAEZ8GISIZ8P30MhC_EJCdz3 RBISUi502h7YbKXCRh9_yvxUw1ZRYjV95aoUmoDL8j_GwO4T3zaeM91h4cMFgJufY4eYBuyhqj0Z xjVzL2Dxxyi9tYMOMcIgqNgJFQe5YazxISzKzEKyMUJrY0nWHGRC9heBH73pLo3UnqVjlYAwwYJE jv5hAn5fL4gwT14HUBsOP5.tx9Lo1NbAhQFnv6_36jhNO1_Dp2NuTHo_eADNV4yjSjqcoDvGo_Ms mG31jafIWKSjS9KyfeLyB2jPAksECEnU58jczHw69hOhptCi5Cc2K1Kt3GIjh2_PQ167ZmTQhXjj hNhytuQ0JINuvW_M95xmBAbDoyTnsqXQT2rsrsiaQvUn0COtJQnspA7MwZ_GacBLARfJT9re4yXV WoP8YTrUbU5YfqgrBJQ1nndEpyYEYz_YRp0DEuQIY3rWadPLoUqvmUx2lpZ4DOoE.ULl_trpqtit 9.tt.yT3JAtpSfWE0hHVTLOHaAEvv2s3sQVrsvgh_cd215_BITspsugxEx..KYtxwIMXPXpxBCVz fng-- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic317.consmr.mail.ne1.yahoo.com with HTTP; Thu, 13 May 2021 20:17:12 +0000 Received: by kubenode508.mail-prod1.omega.ne1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID cb03e82022346e6b80364451e06275af; Thu, 13 May 2021 20:17:07 +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 v26 08/25] LSM: Use lsmblob in security_secid_to_secctx Date: Thu, 13 May 2021 13:07:50 -0700 Message-Id: <20210513200807.15910-9-casey@schaufler-ca.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210513200807.15910-1-casey@schaufler-ca.com> References: <20210513200807.15910-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 Reviewed-by: Kees Cook Acked-by: 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 61d34e1dc59c..193397a1fece 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2711,6 +2711,7 @@ 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; /* @@ -2723,7 +2724,16 @@ static void binder_transaction(struct binder_proc *proc, * case well anyway. */ security_task_getsecid_obj(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 dbb1e5f5b591..5a8c50a95c46 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -547,7 +547,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); @@ -1397,7 +1397,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 121d37e700a6..22286163e93e 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; } @@ -2131,12 +2140,19 @@ int audit_log_task_context(struct audit_buffer *ab) unsigned len; int error; u32 sid; + struct lsmblob blob; security_task_getsecid_subj(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 71d894dcdc01..6e977d312acb 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -671,6 +671,13 @@ static int audit_filter_rules(struct task_struct *tsk, security_task_getsecid_subj(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, f->op, @@ -687,6 +694,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, @@ -993,6 +1007,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) @@ -1002,7 +1017,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 { @@ -1245,7 +1261,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 { @@ -1398,9 +1417,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 8690fc07030f..caf3ecb5a66b 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -338,8 +338,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 aaa55246d0ca..b02afa0a1516 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 f37a575ebd7f..bdbb0b60bf7b 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 dd18b259272f..534dee9c7b6f 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 cc61dd46f517..67140d6c17a2 100644 --- a/security/security.c +++ b/security/security.c @@ -2172,17 +2172,16 @@ int security_ismaclabel(const char *name) } EXPORT_SYMBOL(security_ismaclabel); -int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) +int security_secid_to_secctx(struct lsmblob *blob, char **secdata, u32 *seclen) { struct security_hook_list *hp; int rc; - /* - * Currently, only one LSM can implement secid_to_secctx (i.e this - * LSM hook is not "stackable"). - */ hlist_for_each_entry(hp, &security_hook_heads.secid_to_secctx, list) { - rc = hp->hook.secid_to_secctx(secid, secdata, seclen); + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + rc = hp->hook.secid_to_secctx(blob->secid[hp->lsmid->slot], + secdata, seclen); if (rc != LSM_RET_DEFAULT(secid_to_secctx)) return rc; } From patchwork Thu May 13 20:07:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12256513 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 D413DC433B4 for ; Thu, 13 May 2021 20:19:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A23976144C for ; Thu, 13 May 2021 20:19:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232719AbhEMUUh (ORCPT ); Thu, 13 May 2021 16:20:37 -0400 Received: from sonic307-15.consmr.mail.ne1.yahoo.com ([66.163.190.38]:45803 "EHLO sonic307-15.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232582AbhEMUUc (ORCPT ); Thu, 13 May 2021 16:20:32 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1620937162; bh=a7uyTu+wm+XMgRetIvea2zAb2tPOrXH0NpJuMVK9SFg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=dbtNDofc2UjZL1n2GyMLwbu7hydzP+Cntzwuy5cd+yANMBa3CYlfCfnPoDXxoTEuA85GoGH7wgKmZRJvqwfIlQJJkci5BWIQ/58TB5Ct8f08XQJ3cOnyO8HPtAofDn5nOzEknmcfpfhfNK0+VyIsAY9g7K+AiEvXOyenfpasLD6tFasDgE9pq+1ZtCBtF5V+Dxagg09zVK8gtvKGL0VEnkQ/bzbO6yaUuc/SN0ZerZLuVKMofiYmxG8L9aXEzLusfp7C+q2rt0bfpRiOuduVYsqOWff2D4ExRybvqQP2toATV5kzDHjfki1LyigLRU/aKEAGrbT4q+AoAnQRfGiSaw== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1620937162; bh=gUHj7wZjLwTZXUr8mDspBbn1xhRGGxI/meyJWdeql+N=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=nooVRB5hsi3zmw+AK73pNEP8vwpel40zzLcUxy1EzH9QZRAKw5KoEjrEfns6882j6iNCaPcv+/bMtLOQw73Q9QWf6kPklLD+Jr2Qz9hXhbitviur0Az7a/ItzY0Qb7YdXS69OsO9L2cd84eUUEw4qX4fah1yrZPiUbvOoR/f3Ag+6QkeuTvKAOLt1k5YVykGY7oXZ0e3Q2fyht6iebwayTLEKKXzUEiS3uf6K+RwQDu/unibLVsObtjVb5VT6RtugE59ljvxTEUtubQYZNP2dlwFLjkSPgP+NCc9dYEliQOaBIL2ZPCRimVDeOOTc0JrBI6m9vCE7PyWz3oGP5Sqvg== X-YMail-OSG: L97p_SUVM1lmBc0WAHV8fvYKBplreNkdtardHJdOde0z_iZCdAxkTjKb65rCCBH GfYOhzwNh8bHozQLWo.s.jZiNnZwuPCbXEsKsf4OfJXoEmKjXdnzJrC6pcBmh.JwcELy6wxic2LJ GzvmUtfKo2J_jCb2LRKE5ikgkL6X8H5TtbqtQxeZ.2KGTbYoo.QwJQIqcSXu8URgEkDSXDPtalY5 pQmBU1G5VCjtxD39sFOShLJy_EFjpBLeSvz4CGgG.msD6JSiy6LM9934Jhv_bllOuSdXHqP1Zudl zw3F4wJJBV5JbFGUCGBx1tozd0ktoARe5n2YhyDaNc5boNvrt4OzVK9JPl._mP0DrrB3t5q.ACC3 1qQZOmjNS7MuXN6g5ruIbss_1hjXFTGvP79maZiYzWukmiWO7PF2CJiqI3bgOqpJ_j5eiQJT66so E3trA4zxLbnI3rb6dLd5s.hrtlEC9PhwS1MrwNpKWr5ilUgiCezcnUoA.kSOGT0iEN4HnQMEssOF SBdjH7hEI7GD7kPCTzTXgcLX0I9YwDcGDsM.n9Rhc8HyGRLPOVBEFvz1lpSnXOSOM0AaqUwxNIss VN5WoKDxFVGRfUoWHJ3N.tg.c1qtlbV3DYnSF_qT7R4OE0YBvt8ZorClyfxbW7d_nqmXXRQkD81E JreRYI_iekQ1hUTP5XzDWa8afHZfvrBTT7ulPRkJIegdTeglWetGPiriaG5bkYq7FwsLW9IWCjjX XzY9Vikz7AxQHv6_CLL0KddHEB.uIEPQQM2cqRTck1HhQ9H.AIOFKwu.o_nOt6buI.x06dQ51RLS TqMx7wG85Tqm6BhQH9FCiEhaEz0lTM8xE33d8UWNzelzAcpkFkDYNMiWBoRAnLfJ4suzng7PniVB hOx97OjCLLzZlYEm4bav4Qm0gBkpS0kxJkEbaSs.yaS3xwkeQ.7d32LJ04vmG3GhEgK3ynQ4vMET v08i5.chz5YmuoEKmPmEZ9zBvMXM88rSJTshizaWXS5IeahrleMDSd7TZyis_TnbdbFIicajK7xH sXcDUPljpYvi4VSVwCrravn3mwpMykShtBNPFzvyEATHb0WVsxkV6ncrh4TXpMpiXkLjCLxzmm0O TvS1KgflFGOLP2V1Wt0l1YsjkE9Ay4A.Vr0F6qwYAP2wtoC4PmkhHO4NbQzAaxh0tNo9BfVLdfcj 2e8Gck3pbQ7tT1ez7fGGZXgY9kfLDklwxZyhRsBmGOVFjp5muPH3pxnKtqfAuhzTSEWAJu1jUp05 G2kZq1C3B6lytPMM.TQkqaok_RUKDUIEs2wMJUFkDpnTxefjDxrkaUJ05YM8fanM86uJ.tJr9r4B kUKZbKdpq3tNdd34k5H0ZVnXC8XvslFDk8DznefCI3lDbcVIvFXnUKKDEbH5TIdh65cPvEVZTtBA Nyfs_TvMwXxmCPVLlHE37TNjSmTpDryTg4csl6n08CXheT27EzN_TBQxOVgY9mighcKAchUndkOw 5IZHRt9T4zJbMjPDtNH97FwO73894Jk66XH7glEWDHAAk1b4AgPG_evJhwJRg08wjf83HrOEu2e4 R6c2rVY42wWzrHXdapOXZLTiEAEmMbDd2uFk1K0VPlyBSfywjZXbl6.BWd9phc8SesXgV1pqg_P4 OxfMKme3Y1icTHLz6uINSLzK1ToTBD1UF1ztTfLH.ZRa0bbDz2zwctpDpgq8cs387MjXj1GVbglt 5vPc2GmSuCCCurVtr.d2uRmGSm4W7I.wqYNmXNfx9DEaOmugvI_YhU.j0NMzbRsk2nGqAsWTmv02 sMFsbPdkDLJg8jJPjByqroBX1JenX1PRBtm6hmF.dheGAJmzwauEiUkm6zDMXDyp9XI01ekBWKbl ZWox7HLjJ_4Ais3i7TUhVFQfsUFuZrvHlueeYsO0jmYzX84ZB0_HtUm6cBGn.PxejW.haLMRLOt. QVzE9rSNu3I0U6Z5CrMKE8qlKTejE8uxPkZ6mLhT.xTqDDpoVnsiq3rkUONwZlMW4XHxrHBk3x6l 1peSiK_DrbLOMyIleOTNHX2IQPyHBYeo2wI2NOHcldYEScW4wL0kyAzg0geVziBgLpAUhbiaiX.h RQDdTfDRbWTie7L7sZHidjFrSs9KAIZ8XZiIch0K3gm8A4F9ILBYZLAagHR3qqG8nBIfOLQmkGBY K0DswmV4owZhsaCqi54ApkPDRzXxU9Tp346V8GgrocDcW21Iuff6BPAmsbmrRlrHD2LeIaYIiofg F2SiH54jSuJ28D9mdVPceIpxL8cL1s3NJni90gMZXZyBXyWSfrM0fZDJiZYxDnlgjFRWcxrTfNC7 DZVuCk9OVz9eNIMM1Rsm8mYLvaOfb2JPlf0QM83jp5bm3.R.02Z50otJ3bahRXp.3gm_JQ3o9ZSt r8qXJomIyqY_RbbsyONN7a9wZkQOX1pgEHj_8vUzdBXfNDyao1YEOcv8WbtJQ2bXOoIdSyTkRq4j wZLiu.oikKn4VOEMejMPBZ2Tgl.bJUz6AdvxIqmRuhWfHaaCB4GQWys149cauYb3KxvPOtJDqMdJ SbsTANgwgxH23EaWsR11jvJ9FQUg.CvP9kv8GyRqkMtb7F6oE3wnV1zzbdrdd.sWEEo2XduzKPEm kZK8RKvvIfOPMDDETSpuuAWzZEvDGZ3ab2gCvUu9OJV4ZYmYm.pXegKsyvwK4Sr1OLGmyMCMrPOO OeS1qGrcBueyiSwbp3FA_.viK8kGOZ2A2EM6iwuBc5ss7.km1R2M4bHb4syknAD4NCwdDBk3HRH0 Ta1T.aeRdZ2Rm4E_8dnIytnkSEmZTSCtHCmo1ejm68kYFY5B7ZkR6hF5Nu8TaamAvg23.2b3MntX 9CoKB26ZDWYJwFGRXmijSWAnFK3HbTYovHgaLnwp_Wy_VY48imvyOXhbmMCKP882ZxvMpKtQTrnI IIWP45DSJrU0z5rIrA5.VjZEgZ00xz8BA1FLlE6kpQ8CAuey3ZSHzzja8aaAZUTHXan_I6GrThe1 Wve3N1g3HH2MxKKxnnnuviW4xHUNGOP9OJ3RDGqknntrJomAAvGivAosJck1eEOUglxVJGQyXk5Y dLlYHFcld6OzsyUJotKnowzt3AD3S5vNNYBVMxv.jxDQVzDdoWQJ1YtmzSv41t8If_4smVJazE21 bRyABwRHzdMlZkmarrry2hozZjVOFgq.dcqdrcIfrljDH6yOQeWOETzM8YiXhf8hdgJmolod2q9E .4nKGSip_CIUGnlb389Ho.TkFdgFdUJO4pQH_rLSqNPSCZqm5lawGK5lG0Q-- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic307.consmr.mail.ne1.yahoo.com with HTTP; Thu, 13 May 2021 20:19:22 +0000 Received: by kubenode540.mail-prod1.omega.ne1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 2b7f8645fde6207f4cb0830c1cd3b2e9; Thu, 13 May 2021 20:19:20 +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 v26 10/25] LSM: Use lsmblob in security_task_getsecid Date: Thu, 13 May 2021 13:07:52 -0700 Message-Id: <20210513200807.15910-11-casey@schaufler-ca.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210513200807.15910-1-casey@schaufler-ca.com> References: <20210513200807.15910-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_subj() and security_task_getsecid_obj() interfaces 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 | 14 ++++--- 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 | 25 +++++++++--- 10 files changed, 94 insertions(+), 79 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 193397a1fece..ab55358f868b 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2710,7 +2710,6 @@ 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; @@ -2723,16 +2722,7 @@ static void binder_transaction(struct binder_proc *proc, * here; however, it isn't clear that binder would handle that * case well anyway. */ - security_task_getsecid_obj(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_obj(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 bdac0a124052..60f4515b9181 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -500,8 +500,8 @@ 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_subj(struct task_struct *p, u32 *secid); -void security_task_getsecid_obj(struct task_struct *p, u32 *secid); +void security_task_getsecid_subj(struct task_struct *p, struct lsmblob *blob); +void security_task_getsecid_obj(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); @@ -1197,14 +1197,16 @@ static inline int security_task_getsid(struct task_struct *p) return 0; } -static inline void security_task_getsecid_subj(struct task_struct *p, u32 *secid) +static inline void security_task_getsecid_subj(struct task_struct *p, + struct lsmblob *blob) { - *secid = 0; + lsmblob_init(blob, 0); } -static inline void security_task_getsecid_obj(struct task_struct *p, u32 *secid) +static inline void security_task_getsecid_obj(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 22286163e93e..d92c7b894183 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -2139,19 +2139,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_subj(current, &sid); - if (!sid) + security_task_getsecid_subj(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) @@ -2359,6 +2352,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 || @@ -2369,7 +2363,9 @@ int audit_signal_info(int sig, struct task_struct *t) audit_sig_uid = auid; else audit_sig_uid = uid; - security_task_getsecid_subj(current, &audit_sig_sid); + security_task_getsecid_subj(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 6a04d762d272..1ba14a7a38f7 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) { @@ -1362,8 +1361,7 @@ int audit_filter(int msgtype, unsigned int listtype) case AUDIT_SUBJ_CLR: if (f->lsm_isset) { security_task_getsecid_subj(current, - &sid); - lsmblob_init(&blob, sid); + &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 9aeddf881e67..dd902b68433e 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -471,7 +471,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; @@ -668,17 +667,9 @@ static int audit_filter_rules(struct task_struct *tsk, logged upon error */ if (f->lsm_isset) { if (need_sid) { - security_task_getsecid_subj(tsk, &sid); + security_task_getsecid_subj(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, f->lsm_rules); @@ -2422,12 +2413,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_obj(t, &context->target_sid); + security_task_getsecid_obj(t, &blob); + /* scaffolding - until target_sid is converted */ + context->target_sid = blob.secid[0]; memcpy(context->target_comm, t->comm, TASK_COMM_LEN); } @@ -2443,6 +2437,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; @@ -2454,7 +2449,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_obj(t, &ctx->target_sid); + security_task_getsecid_obj(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; } @@ -2475,7 +2472,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_obj(t, &axp->target_sid[axp->pid_count]); + security_task_getsecid_obj(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 534dee9c7b6f..b08442582874 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_subj(current, &audit_info.secid); + security_task_getsecid_subj(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 b9ba8112b3c5..11f6da93f31b 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_subj(current, &audit_info->secid); + struct lsmblob blob; + + security_task_getsecid_subj(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 4e5eb0236278..f8c7b593175f 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c @@ -71,14 +71,16 @@ bool is_ima_appraise_enabled(void) int ima_must_appraise(struct user_namespace *mnt_userns, struct inode *inode, int mask, enum ima_hooks func) { - u32 secid; + struct lsmblob blob; if (!ima_appraise) return 0; - security_task_getsecid_subj(current, &secid); - return ima_match_policy(mnt_userns, inode, current_cred(), secid, func, - mask, IMA_APPRAISE | IMA_HASH, NULL, NULL, NULL); + security_task_getsecid_subj(current, &blob); + /* scaffolding the .secid[0] */ + return ima_match_policy(mnt_userns, 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 906c1d8e0b71..9d1ed00eb349 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_subj(current, &secid); - return process_measurement(file, current_cred(), secid, NULL, - 0, MAY_EXEC, MMAP_CHECK); + security_task_getsecid_subj(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,11 +430,12 @@ 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_subj(current, &secid); + security_task_getsecid_subj(current, &blob); inode = file_inode(vma->vm_file); + /* scaffolding */ action = ima_get_action(file_mnt_user_ns(vma->vm_file), inode, - current_cred(), secid, MAY_EXEC, MMAP_CHECK, - &pcr, &template, 0); + current_cred(), blob.secid[0], MAY_EXEC, + MMAP_CHECK, &pcr, &template, 0); /* Is the mmap'ed file in policy? */ if (!(action & (IMA_MEASURE | IMA_APPRAISE_SUBMASK))) @@ -469,10 +471,12 @@ int ima_bprm_check(struct linux_binprm *bprm) { int ret; u32 secid; + struct lsmblob blob; - security_task_getsecid_subj(current, &secid); - ret = process_measurement(bprm->file, current_cred(), secid, NULL, 0, - MAY_EXEC, BPRM_CHECK); + security_task_getsecid_subj(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; @@ -493,10 +497,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_subj(current, &secid); - return process_measurement(file, current_cred(), secid, NULL, 0, + security_task_getsecid_subj(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); } @@ -672,7 +677,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 @@ -692,8 +697,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_subj(current, &secid); - return process_measurement(file, current_cred(), secid, NULL, + security_task_getsecid_subj(current, &blob); + /* scaffolding - until process_measurement changes */ + return process_measurement(file, current_cred(), blob.secid[0], NULL, 0, MAY_READ, func); } @@ -722,7 +728,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) @@ -735,9 +741,10 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size, } func = read_idmap[read_id] ?: FILE_CHECK; - security_task_getsecid_subj(current, &secid); - return process_measurement(file, current_cred(), secid, buf, size, - MAY_READ, func); + security_task_getsecid_subj(current, &blob); + /* scaffolding until process_measurement changes */ + return process_measurement(file, current_cred(), blob.secid[0], buf, + size, MAY_READ, func); } /** @@ -859,7 +866,7 @@ void process_buffer_measurement(struct user_namespace *mnt_userns, int digest_hash_len = hash_digest_size[ima_hash_algo]; int violation = 0; int action = 0; - u32 secid; + struct lsmblob blob; if (!ima_policy_flag) return; @@ -879,9 +886,10 @@ void process_buffer_measurement(struct user_namespace *mnt_userns, * buffer measurements. */ if (func) { - security_task_getsecid_subj(current, &secid); + security_task_getsecid_subj(current, &blob); + /* scaffolding */ action = ima_get_action(mnt_userns, inode, current_cred(), - secid, 0, func, &pcr, &template, + blob.secid[0], 0, func, &pcr, &template, func_data); if (!(action & IMA_MEASURE)) return; diff --git a/security/security.c b/security/security.c index 0364531d92cf..f3b985f76dab 100644 --- a/security/security.c +++ b/security/security.c @@ -1902,17 +1902,30 @@ int security_task_getsid(struct task_struct *p) return call_int_hook(task_getsid, 0, p); } -void security_task_getsecid_subj(struct task_struct *p, u32 *secid) +void security_task_getsecid_subj(struct task_struct *p, struct lsmblob *blob) { - *secid = 0; - call_void_hook(task_getsecid_subj, p, secid); + struct security_hook_list *hp; + + lsmblob_init(blob, 0); + hlist_for_each_entry(hp, &security_hook_heads.task_getsecid_subj, + list) { + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + hp->hook.task_getsecid_subj(p, &blob->secid[hp->lsmid->slot]); + } } EXPORT_SYMBOL(security_task_getsecid_subj); -void security_task_getsecid_obj(struct task_struct *p, u32 *secid) +void security_task_getsecid_obj(struct task_struct *p, struct lsmblob *blob) { - *secid = 0; - call_void_hook(task_getsecid_obj, p, secid); + struct security_hook_list *hp; + + lsmblob_init(blob, 0); + hlist_for_each_entry(hp, &security_hook_heads.task_getsecid_obj, list) { + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + hp->hook.task_getsecid_obj(p, &blob->secid[hp->lsmid->slot]); + } } EXPORT_SYMBOL(security_task_getsecid_obj); From patchwork Thu May 13 20:07:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12256543 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=-14.0 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 C4042C43470 for ; Thu, 13 May 2021 20:24:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8A726611CC for ; Thu, 13 May 2021 20:24:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232854AbhEMU0H (ORCPT ); Thu, 13 May 2021 16:26:07 -0400 Received: from sonic309-27.consmr.mail.ne1.yahoo.com ([66.163.184.153]:43668 "EHLO sonic309-27.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232835AbhEMU0F (ORCPT ); Thu, 13 May 2021 16:26:05 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1620937495; bh=HEKDnSOsr5dIFPnVk7iUYZ7liKQS915UhYcg8nARtyw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=BbalSgCDfzWDuDi+XRvAZUpAfv3sLjyOzEjJJErhw3ukiiAu0RactSC2FmsTUYp+TPz8xcE+tRxJwwyxdlJej1K4OaoygmSRBkApsJsufSCgI/yJWv/JhJ/22gxkULgPa/l78tjw5LcGccJATBeobXEEaHVE2tesaLFYCmRwDQv4pL74C1xOe3Z7+zFAMNrpJZ9Ti+B+XFD1abM0vPYmLbSGUPCW9ML/2PFy8K4ptNpPfbR0U5LNR6GgrAo5uoe7m0xHA223Va1Y1vbY9s47+dFqVGuxJ6lH5Svx333y4olc4hemBkmH3kpQnOZlyQAkCHjisdIjBrTnFqvW9FxCrw== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1620937495; bh=eiHrSYKSvQAlxtj3mb09JmCS2y6EawkaHusS8IiyEfa=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=SOGiOCMpM2fb5y7kPkFkY3n7XWLLHZF1uRmktDhFGhIn4TxeD78uooRF1ZwijJBfvasXmUbzlPP/mAQ3/R49KR9fgpWl6I/YBA3AmongFAxLe67KcKXPM9hRgmgfp/pBrNX3axxHSvSUpUsfSzr3AtfkyIHBMQgyi0ExPueVmV6uRLSRJCzEKJkzJxvPy+mHQ8cMog0oTPmV5VvwZL5BnD/2Byce1zF87DzSv4kMc/WvcB1vljMskzaUCRhK7SXYZhFvtSdXASLZo/UB0Mj4NnHUw99g3mHt7iAh9rOJkqeGtDVkzZWmaVAqWiGsjjuuHuVFEJG5gEr+CZ1bvPh+NA== X-YMail-OSG: L4ONLuQVM1m0RYOa9Ivx6NQT29rx48s4hQWIAEFkL99wnhI9ZrZv9jkwSPzJC28 s_Ey1OxBFVtg8POVVFHwBjOkHwSBbTzp4gvPCWOUjwHm9DO5FcvRMw6gzmTt7nH8Bu8.GkMJNbV0 aRg3XeeIez6HjryjQk0oF9OpgMAjihQCC1_MqvmiQaoCYpHeg5ICO0dYXGvn41KhwIE4UqjZIwWw TSDy9ugmXt1epRhGBMP6L77U1RgMP7_3QfHUOmEg6sEgomIqs0Q.nI64R.OX9Pm2fRHU8np0XVC7 jGjJEo4CbjWECl14TCwBozmc28R3eZtaNU4G9BdVV3W6lXakX2wXeceCCVcXVnYf2J9W4tbdGCT9 oRD4tl3MOb2EfahORhQ1WDmMVTkA4EUt9ZCCc1xBn4MAy2cUscFL13dtCGteQNWayHEpLYN3se_U zPaCiDG198lLMddQ5WUDTaU2qjVDqHGNLFwqFmlC6H93r7ESZnpyAMJzJp.3Eedkn.dLv9tLzK9M Dbr.LlcWdQ0BYoP2ZKjCspWhuncXeehkbft83V88ZN4TYnBauG8o2XyKiMElYyySErvrEzBtQdsI gfrz5f_WEFRjZ8OLXouej8cufteaKh5fmG_gEQVyKlWpe.DqldiDOOAd1nbJbACwyiCeoOGCLaar eLlzTzf8mSUwd7TQ653oJA90ZALvF69le3pAa.E3k7bVlS.FYgme2ZGoanszDRIa1h9znu5qqW6C 2xXeuRgVXSH4BFxITWvgvLk4cw2xAMYHNzWWAJspxHPdctrvwHnBh0M4o3rM3z6nF4bSRZsaiCZQ sE.bvcyGXN3BQDdO2C4v9LOLmq7lwQ4WFxs4GN1pbI_mQvgidjw1ve9_slM_Gl54L2LcsqlENoy_ bbmh_rlrAkwocr0IjJWzioy4WBCLfSFI3Jfev427EUVHYjihuGwe6oX.XTBDTYv7pgdrd_4yG8zI WqYP29vQhjjXn51EN7FeNzPv.qd_dV3m9o.7ZhA4ygUCJ9t4_Yy8nNIHuIp7Utu0Nu2GhxnsXh1K OuTouabohdVFqs2hcOp.GzN.Z31GJfL82mMR_jr5n6RLp7j55T.0WdarMgv7EPUy.u.O7tHaPI9R AFd7o4XXxQA2.iMN59YRhK3Bpvaa_ZOVT1UOeMOnjEBHPU_.RtzEAPpB7eZa1lbNI2onAcFR0QzO OZp3xmEUWV0rzemNJScfp85UkZhMFq3.hlGuIgWZTpLADwGY4UteNCmJFnsUEaWYErCgRVFAul.9 TAhZfIsNl.l.TgX30zVP7BjTAikQ535bGRQahyyjMZ2bRhFbch85KLFJEPRsnlOf.WPn1bLrXtnH FIGi2z8UUfPqhY8bOJLx6w5soG17S_XeZ2ETkDbouV6XY0evfYIpKGbHyx06nCnA8ycU5yYVtj8B WdyTReJIMh9w9qdJR5qO4fR.spO1mWk12NciwQsgXL_EaJDxcyjTSzq08w_Lu_3OymFeVKMujKGY M6ud6gA5cSK0fCnQXrX_foI5Sm2WSixnH0eL5G61wFZb1CFOilbTy94MTyJf3f0.MJLVIQ0u1RDD SzlJpnp1qsOqTBZUhmWkybTCKy9CKl0rq3ISr5SLw9PDWusx7UPv5xPpVtSSilRqom8wYsFFg0BV J35upPK7PXYDmq2Z488kpuzIk6a8E6XMDFvHn8Inb6ummvj5w5RAunOiwEQBPfphhTBrxVopCsWc o6oDkgBqYvnr1XLh79ub5yv6IESoFd8Prdvd0RUJIzScJ0KDP1h_QNqjf4y67s50hY1v2hsrfj3q 8omY5XvoYxQffV0QPrwoT.Wu6v2qxUo_msak777AI9xVMLZtkN1MBGpJRRvDOW.Y8YvQRPqFcoGk WQeKMgZzyD8HpUD6DC4U5RE.qbGCs3rudKDUDfz46UNf1i_q6eW_fM0Qe_iqXi74hKiIxHL9dax9 ySUQis8gvd8XaaiPxZSNjQMOUydcg5td2m3GUp9I94o_JleldVIOhv1QQDGvPnI1ck35y91Y2Bf7 vBEeEU5N9YXBDRS.a9Ioi426tY4kRMMdhLqlaGdypcH2BQyyLkxzRO2GEtpRiN.pSXdeYJklQVk9 uHk2BBcHja_WaoIG0lV7eaaRDtNqLTEMvFxUyGt.1BVWXjdOudNQjllwwHhd6kZ5UaVuicer7cyy JcrK_55cWprb7ofgNz1s2GFmVVPK_guMuz4dbsBDHGs5ABcmBriwRTRLfbya3q7SwvCCkKCgGdN8 lsjicmux_sLNIOBnYdea36aL6VDR2_Cb04PpVjMZMNYfBGzkfUVHvyyP_xyfQAsDRejwb_RllauX IOLrwCwB_7JZFBVUTJpB9cmYnqyVdFEl5hmwW3vznkDcPDKiEIlCp8Agg0YCv.rU1OFPvjaOf4dW e4rtVKUMa3eLp8CrItbMAgkDlYgRwPSDKcU4Ln6BUGJXgnmBdO6Dac2.DmAei.ACkxwP_NbbsYrp UMGO50Qs5QQqUEA6zjtYayRMen2UExy_gTEYYB3wVn.T.IZEoZB3iVH_JJkQ.HBdyGCEWMyWBd2W XCNfs2S3LxQz74zO0I7JHW9fLihKPa.KnJ_Ac703vglLCmE623cAE1y4xVASKQLWNei3nBVFi24d E2dXzEMW_r69xdad6F7nH7WgvYqGgLwE45lqa3vNwG6K3xE0qhTcq3aGj37tAIx7oc6e6S8SfLbz OoHhnLRwAPoSClFIZCcypGCzpD0fhN32wCnRiOjo3_SaPbzcTi6eXrX0UyVAQvEZcWMQght6YzBU EO_3tmVNMOSqOA1g56FLs_MEw7iyzePTTCmaMRRWNxcDZVDeL6hfDgnx2T7XophrfW7CWr2wDVgw H9Y9uZZbGJZ.II0.ccRg7mniiJqTwBXLfSUApHt0KPu3rrtfRzM.XKYXpZZzDqi8gJhk8R_rZaQq NzGE4IP.MKb1dbfaYjTh4WNz63hvoFeezJRfcvvtoPfk_UFBvdt_M1o.KbadjyaFFD4dRbgbA2yX NKLnLqOeSMyIiNlt1R2ziMymwVcnzzjTEP5Y6ky_WhwerNXCt2VTB8S6nrbxWG9zKqbludyMliCI tDfAai2wlHwLfCo4aJ1d7CbHYOTKS3QEkNYJxvB_fVXkIsyyNWtuf_KNvxw0ataKxYx8EDe5wQgn lBlpUq2Iu1GQCm86XjQvNdk72e1qJ6tkvgk0eXC6jnfoKv9QCUhCV2QX6FWDc1Xzhzc_cDuc6.oA iuHI4WOK37BaUuQH_2LE1loKanSKauG7Evm_jVM.E1Pd3shvZqI3TDLyGl3jSZI1_HJIJGsMD0WS J8x61kAoJj6eOeYq6UPslIFIvF2tHfb3N0dkvYrpkKJKMzbYyNAG4mNgvjSHTwQK2GpHSyVl4OiK 5IfWIzE33k8tCa1.ixJrCYh_aS.4D.45oDKGpfjDIRwOPwTctFNRcvDtmjRLx4FeRHGOODEbaNEt ErXZrcOSBRJorj4e5WuYVGcz.INaE866xYkmccXwPxmmVu6KHWtXDwUZEagxZq9hEkRn.FoY2Rs3 ikuvvBw3K X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic309.consmr.mail.ne1.yahoo.com with HTTP; Thu, 13 May 2021 20:24:55 +0000 Received: by kubenode512.mail-prod1.omega.bf1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 5f07466c1e228d479742e3c8b2251e2f; Thu, 13 May 2021 20:24: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, Chuck Lever , linux-integrity@vger.kernel.org, netdev@vger.kernel.org, netfilter-devel@vger.kernel.org, linux-nfs@vger.kernel.org Subject: [PATCH v26 15/25] LSM: Ensure the correct LSM context releaser Date: Thu, 13 May 2021 13:07:57 -0700 Message-Id: <20210513200807.15910-16-casey@schaufler-ca.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210513200807.15910-1-casey@schaufler-ca.com> References: <20210513200807.15910-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 Acked-by: Chuck Lever 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 Acked-by: Paul Moore --- 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 ab55358f868b..eca789340ef6 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2461,6 +2461,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; @@ -2772,7 +2773,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; @@ -3114,8 +3116,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 1242db8d3444..b867089e1aa4 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c @@ -1356,12 +1356,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 87d04f2c9385..a179d70eeb7e 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -136,8 +136,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 7abeccb975b2..089ec4b61ef1 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -2844,6 +2844,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 @@ -3345,8 +3346,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 c1c31eb23859..3b2ffef65b05 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -133,6 +133,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 * @@ -550,7 +581,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); @@ -1414,7 +1445,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 8ec64e6e8bc0..c17ec23158c4 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); @@ -2132,6 +2136,7 @@ int audit_log_task_context(struct audit_buffer *ab) unsigned len; int error; struct lsmblob blob; + struct lsmcontext scaff; /* scaffolding */ security_task_getsecid_subj(current, &blob); if (!lsmblob_is_set(&blob)) @@ -2145,7 +2150,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 573c6a8e505f..3fb9d3639123 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -996,6 +996,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; @@ -1013,7 +1014,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="); @@ -1226,6 +1228,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; @@ -1259,7 +1262,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) { @@ -1408,6 +1412,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)) { @@ -1416,7 +1421,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 caf3ecb5a66b..914ab6a96573 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -339,6 +339,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 @@ -359,7 +360,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 b02afa0a1516..b039445f3efc 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 bdbb0b60bf7b..06b7751c7668 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -397,6 +397,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; @@ -626,8 +627,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: @@ -635,8 +638,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 b08442582874..8ca1e2b33dcf 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 1ce125c01782..f6a33bf2a7fc 100644 --- a/security/security.c +++ b/security/security.c @@ -2359,16 +2359,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 Thu May 13 20:07:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12256545 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=-14.0 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 1C325C43461 for ; Thu, 13 May 2021 20:26:04 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D8AA861421 for ; Thu, 13 May 2021 20:26:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232873AbhEMU1M (ORCPT ); Thu, 13 May 2021 16:27:12 -0400 Received: from sonic309-27.consmr.mail.ne1.yahoo.com ([66.163.184.153]:35575 "EHLO sonic309-27.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232835AbhEMU1K (ORCPT ); Thu, 13 May 2021 16:27:10 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1620937560; bh=58TrarWqrWx19kx0PD1EPD70n63T+nBmry7xCis3tXs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=OlHuYhIb6Tfhu4n4QfF134108Rj/KGIhluSQvZCRCL4Chf3hlibP9YOS/ORmndH5IhQXgVCP5TH7rlfw/SRLVV5koUX31gJoEsrfPFADmfnw3AAYZ2u0JnKZahzCG8i3nFbfRvDdeUlRBf1K8F4y9Q7vve5aXR44g5Cdn9X1OlmJvvwUlKZvRvSaps0Je1PHypr2J85ahvy9NUXGwF0vrnUKpRHZVSXKIXdyT60TcE6dDQn9OzqbWeu2EdxArSdzKohm6mqDdmIP+/vEtk8m/MqJSTTjZ+DD/sn90jCK4pEnazuKkbwVq/37GTZsJspfURpazKuKWbNeiHd5+weg4g== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1620937560; bh=ifPUHRm2iqQFgiD5jpWcWIQrdpNmFN447rBcN+3woH1=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=RYQesP6yOWkZ/yb1aeGSiwM6O6oL1yL2EKwwhO4f9nxXGOWV5GXGyV/1tCaft0P1VyTACQxTjUc6YkDTlPXLtloD1r4ZOu/h9pXNv3uRDiY1rEE+5jMWD82v0htKyqpc5RGWFcr568x77lt0ZGIOZL3ahMlv9tcRDmalrLzcHJ5rX7D9ASZ+OD9jcHpzq1kj1MbrsAeD8V6vSM0S3m0NNHuE2thb4/2VvDlaRvdLGmKdy/qLYo8LwkabIBNfQRlEHcdOLn8S5MCzEboP+wvhWjQ6fNVjJuk9xqWrR4lb8uZKeQ4r8r3K1tT/DlhTW0ZKK0ftxig+rp0MPUMQQtF3Ng== X-YMail-OSG: C4PA2x0VM1klmEe7Mptwb_ubcq7SV5aMN5Xe5Ds5qasZoMtX415U740LgeLn9TA ID062NGzeKp4mrnnLxYFh1TYbuun99VZ.iWfsZEgL0c4MgkMhC0P5O6iioyGzdnFVjm7sHbwqhPg b1VP5VgcteJvakT9j2xyf2odCVnj6_liE4mO_FslJ6S3qyoDmQilYz1cvQsgoCwOhIzy8_1vcbZw gbEuP7GAkQOaBj81fjOgAzKM4uO.y9s4NpXbrRTk2K9lnvA9Eaoo5mPhGVmsk6slHbYRLFa_34xZ x8dZHDZrrlK.uxl5n5zLPWegss1AUKhMJPjy1QgR58yRptWHnn_YuZkqft2PhHuYMnSAd1GlMtkN jLO1KnQYJLp2QgwS4K4V4iWQm8NdLzUAfJdpaN_uy37nGTTUpsVMudnoNl0uD9WFOFdlP8S6FdVr BmdbNuNCQ.13ftcufBiSeRvgAhkLG.OEiN7yoL6CbGQNtcGMLvrGainy7dCPw.pboCcV.PUSlTBN jR31eM3wJmhk.WVRubwHPEhzfuaWOjZZvFoptHBwIVNNLGuixty9op8amCsw8uQc4kxY88mEo00J F4EPG1Arym.piB.Lg6EqC7yorWEw0yuqbChnL7KnUoKS_XYbEJGwmSPysMrd11afXt2l2umd_roy fu.nBRZvdHoWnUgyRWoRRBfaA65lUPQff0uX4HcxdHx9GLmjSNDFasGq4HRiLn0Y_iYeEgqCMps5 jqoMr7J860sojCybbpco7xnqha6wVxb8qMJWdjlswURBwi2g9YUEuDYyFojSJuFfgKBwjGHkQnjP VynJpouDmIBJ4xY_Uoh3mTE.0kxIyifh32la2bhuWb3zWunwl1yXYsrJ7SLe0SvFZeI1mYIkzfX4 KA3DL6zzGy6yGV4vIsgYcX11Ha4da7xYfiuYKHfOS2xXN_xyhV.Q7WBKAWGG9RAOck7av7xxkeiR qw7VKSR4Uim10gw32cioMLTobHB62cGClrSalpPGBsHut.9mKNhghhxqdTgygEW1vJqTC3ekJXcB su6r.qTC0HjpXc_TxaiB6_R1inp..NCzMKYI3d545sibw_4Hv_TLTp_oIfZyymxV_QSQXDubg_xM M4rBfXj41sPu_AzKvZg98Py5KuJEAlkfyNfvPOQ8A2HSHURimaHlK4A3H0M1qb8ZKpt9ulZUzMp7 Guwoay8ebKXnatfgwWZ4wbFvc4n64frrkw.ub0q1hKgTU5N7vP1L9HSrOlzT4KEXehNS7GEMXzuj 4orLLLyanqoUxZOE8fK90uvVOcVvEAW_FCHREHtWwc20jnzGgyLZwCuujX2nGXk_WbRLpyrS09V3 Jb1h84dxoZ5j5NLhRHqrV4sh2X_ctl6dideYkAxlMMV9fGZCDEC9fYwX.7wXghSE1lw7girFx2i2 HIU5sjv4nk23YkHip4sQ5rKbL3Dto1T1cEWsLJI3pgXkVXC2whR8gkev2q_m0dWtqbTHy9Fiw8Pn ZnqCZ69M7eZEJLFkm6toF_iARO_UU27c8x1XsZxHqlwLV_lvT5zvWyXW6xaDvvJSJWQpk4llVE5_ uoJConH7h0RLMydOu.msAB7PUn.OLUM7gGsGx5JuIui7e01.5cqGyiD8KO82Ch3_2s9yqDON.JqJ QIEdnsL1CmE7nWDaPL1oA0KllOo4qIN94AGbBUYFMqOrASdPWcph46bjvGRejFXKZLrpYqPxhmV6 HZf4WMRO1SjxEg.v3Bv6n81mUGLAxd3weeu4PSFO8U9Vk3eGBy0ueIW3EKzlq8XygpONLHW4zzh5 6wuCMwbTe7Hgsx8z8feSPSKnAEHopgrWNeAEpdARDFwwIT2R5SYniGlSVZHLcC4_YE7qS2smYaZS atXkRkXa3TnMiZ1eHXhQxoEjFHlkn9yJJQmF.vHmg3sTujdc55wjzE7pFlzkEPCJiqHf2R34Qq1G R5bQ3ydFqUTiWdkGCwhmOuEOtw_7qomtwSd2LmHxWiV1yCabYimj11wpniiS0wG1qA6T9egK5u2Q bgdeXIajnt0KsWgAX1zjMQORnJMGLTmj0TNEEzh9XCNVraxEIL2jwlBu.xtt9SqnWHL.oGH_n76q JXzQ7Ml2mxNdvI1daXY0XU.G_BV4mDwyAwWOooadhSz9RdJp0x4Kgu.pZfcYbwdzjUtg.7KvihFo xeHL3Tv2SH1YdQYoPfWdhIwIK.luDEMIsFyNWrtX_EfW3yq5Znc7KAXLQxetq39pxWgiQ5SS0Gt0 TaOxPPVDW8Mr.UfHDlm2uRnOXihv6hbsOzqy2J0LKR0iV2U7FKClUIjDea8UXdvhIAWHv3n1rhDY xCPz6DN8ASMzz.zyN9b5FowfLAfW2ba45kNywZguqf45HgqWOTUc9Cbmya8IYfNvP44sp65.D1dl kokvgkha.Xs8DvQhewwvyrT2Z3SzB4v_bQ9vof7XQo4z7q4jwhQc1XHmsaHgL71uGzweZ_XdusFU w2X.1_2Vn6H_3qfJhutqS6yJGObijMHtaFpj7b1G.nMQTv8urh2X4nRFsLGSWLjq94ULPadHY4E3 liHCCfCL7Z2NVGIzsSfx4REi9r.sfFDL1krzzD9cqgSI.g6tFw5vl3MnAQhu44xUpVEAggtpClsT 7uzM1oyB72vcg.Gg8wShzSRbnj5ypaEeDHDmlh9uWH40xRTcb4f22zzEeBkM__crDKt8gIE7tZ1t gud9_csRsdz4jDT4es2Uinv8JC_EjAH1Ibs_5MYqlbbmkNEnxhb04ow5xYC00TtaA5EsO9_RlvYz tpAU3bRouRNnjDhnyNfS8SU57kp2G1bW8rcb6mKxba4HTD_Fbdv_KGUXtEjFtTV7aREMAO4eXBhH zk8BkuY6W.2fbCeHwteHD3uVoUvj3gmNBYPtZbQbl8FIpVAxe3IDwsWzWsip8u.3R9d6A_Mom.Hn qLWX1t2b5UjHvdGlzuY3m_gbnmLHYRxrMxZd5MKPsoW34sZJDrF7waDSgBlQHhFT990RsrOtRK8k RDvcAUUuaxZHR8YNvmuhc_nAVfT2gu5kyP_55rPN9xWLRp_6tPldmsNo7YeNUjx19bMH.gI1yAPh LqXUM0Vm72PMOJ8CMSmEMukunJcjF0z3taFUbTpfEEVhlhfo0s3QDksugUMO508jIsmJzEx2qMee QDirQ7fd27QEM4V8SUuX2KiqWV71I8zfRRQePjJcZNU1dIns_6FafI.GhN4CcCK__Cg7zLbN8WfO 5YpeRqssZsUNCLvTol42jTdeYp6iR79ig99RMzJ5HkWZxqQql4BwaCVfS7FszuYbhgdSecZ.D1Or uOPQjbw-- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic309.consmr.mail.ne1.yahoo.com with HTTP; Thu, 13 May 2021 20:26:00 +0000 Received: by kubenode512.mail-prod1.omega.ne1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID ed75b12c0acb1fadc13d01a4b8163364; Thu, 13 May 2021 20:25:58 +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 v26 16/25] LSM: Use lsmcontext in security_secid_to_secctx Date: Thu, 13 May 2021 13:07:58 -0700 Message-Id: <20210513200807.15910-17-casey@schaufler-ca.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210513200807.15910-1-casey@schaufler-ca.com> References: <20210513200807.15910-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 eca789340ef6..f2a27bbbbe4d 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2459,9 +2459,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; @@ -2724,14 +2722,14 @@ static void binder_transaction(struct binder_proc *proc, * case well anyway. */ security_task_getsecid_obj(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 */ @@ -2758,24 +2756,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; @@ -2832,7 +2828,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)) { @@ -3116,10 +3112,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 3b2ffef65b05..666bd85e142b 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -578,7 +578,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); @@ -1433,7 +1433,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 c17ec23158c4..841123390d41 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; @@ -2132,26 +2130,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_subj(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 3fb9d3639123..67da23f6bebd 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -996,9 +996,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); @@ -1009,13 +1007,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="); @@ -1228,7 +1225,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; @@ -1252,17 +1248,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); } } @@ -1409,20 +1403,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 914ab6a96573..215d3f9e9715 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -336,8 +336,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; @@ -345,7 +344,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; @@ -354,13 +353,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 b039445f3efc..df6043d1bc22 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 06b7751c7668..719ec0f0f2ab 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 8ca1e2b33dcf..3daa99396335 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 f6a33bf2a7fc..5bb41ca1fa9f 100644 --- a/security/security.c +++ b/security/security.c @@ -2323,18 +2323,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 Thu May 13 20:08:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12256579 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=-14.0 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 EA656C43462 for ; Thu, 13 May 2021 20:28:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C9B12613BD for ; Thu, 13 May 2021 20:28:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232892AbhEMU3X (ORCPT ); Thu, 13 May 2021 16:29:23 -0400 Received: from sonic309-27.consmr.mail.ne1.yahoo.com ([66.163.184.153]:40850 "EHLO sonic309-27.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232753AbhEMU3V (ORCPT ); Thu, 13 May 2021 16:29:21 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1620937690; bh=KfyRLiXkN7GzdhRBaMWAjvKTGVbL2Tujl8ObV20Uuzk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=WNZXM8Q2CiDQ6B8YDf75bZhLP2Il24zLLO+EfN8SxBKdyPcZwS5wCGdOSI16od+4fcdhCUvO38BaGQLvqq062bO8bYBMFTcjatAyeGlMvxPGjO1oe/na5lw9P2EJVntMPHoqt4IAd4V/LfnNyBl72YwyY53XL6mzQpbXKd8YQCYcnj9bKkwcxUO+nJ4DsR/RE+yH3XVfuUaSBcWMSD6oWHxV576Z+UoyLmuy8nHWAa6HkcwAel7UYjoxT2Em6GrwPuhaiLRWqCJNWjxJ7ZdYyUgYtN+cAtpB+SZvSw6G5y1TgCfmshjgjn9Gg523N87TDwr4HXicKLlLvlT7t/XQXw== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1620937690; bh=AFG07ztm7H//CNQNPdbBKGSh8Pj3cSvWwCBlx4qakhj=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=qWoiw38bJRMeHH8IgEWnwUwVxu3gUtHh2gG/L112o0XdGstStErXcA2Vj3yXtiiKKB/pCgSyGxnn5AxijV0wCQZu70uS+PKJONjtrAMpoHwNFNPCuabtABgGa2Lrbezd9kyoNd8bOHr36+Dcc5WK1l3ckDurDImFjjx6lOyuW1+mtx0L4PZKNx0+Gm0eHP/oxvPNAhel5AP5g/xWBZsYY+k0zJ2qBKYCQaoD+scW2lXB7HFI02ulpO/P4DnrXb+iIZtEdzvLaVGpEUCLGDbH3KdHmkLxq3nQoA4VRfS8i6KcQtWD2iN2TJnzftyT3+hHyDro0QnJu58VWfBdIuAn5Q== X-YMail-OSG: IXfK2b4VM1mB7g_Rz9YS8HJ2BslidVrIJl0SWj3yp3HeY5LYDwvnRi1c7bJ8lbD rIh4y8omufct6U0xEB7VomjZDRH0md9ESU9oECKZA7MNXj5zZP2kzQGkgzRqJvyk_PAoC7EAWSkX MGHjnXUWst3avA0SdaVRrS3PINCFc7evaGlsUAXh7v5ItqE22sjKPjO8kjZVK8UM7m1nT4N4rrw7 0ogL2rAcarxE54LQw8WmfceuYIZfB2XzABcYFHiILNLiZLffhszATR18Y1jWz82FAk2VNdsUB6OR axr4dBfAXlLSWyJ7iK3SyzV3KLBFpWsC52dOq9cL3vALczcWnbmpoWpxR9U2vMM76at5fJ5nmNUM .8TzaOFuaypJ_43i61v_I8sWVEwCKXeMYgOUu4GgSoSj3RqIK14C5_WrmhvQCe2U03U6rSa9sFER 8IdeYrh_JGWto8na44lP4ZMoa2NWIWGeW3ujpFKSQagrEGyAdlQmeGsc148Jyu208ARjsbYXMgBM saQSMdJzkFxMvw46hs9UARuZ6921eAWS1qJ.M_qVh2phFgRWBD9tEsC1kEa0SCOaAD7a.8Wp5I2M oxe9J7HT2LvHfSXLAPuYH6zi4ma6tWy3cCnp0L4FlcYdsOUXSgjDUrn3.owgXLNSIizyWUPXdPbh _fGS.Uw59oRj7EAbVDVVeD021Q8SzHcY19e7XvbYNjbYiiLhVmQY7ik1ZoXu4U0q1RBxZ6OJFRz9 A3evX2NyZs15ARaiQ43LeZ7T1lotglFXWFyyapyna9chytRsu3VHww5WS8_RSfIzYeqsEVOkfqG5 8pfX4dE8Sn8jiHQWlp6WhnVC1LRNmj7dR30QTe1AqfvFUa6xLyeTRUemu5W_HnXxuEs0WmuWbWMP 57jbjF4Bs6PRslzF0UxiBtuuAuq89dQ51E3UVK.pK0L.DIT281WBgVnGOTajjH9LXdJAYMHDDlCT DDYrRPl.un1tWBlzcZKOoIuKmuz2S8MOYgZRGM1X3PB.daRC969Or0i44pchsit1l.gfCYn4zwgw .lYpleb4.7oHbq8m7D6Divdg52CXt48ubrCzgIWop_TqKQWwCtcrJHDn62HcxG_ACDFnd7Icsvp2 h_Q4Ai7LY_219G0QbknKB8kDWJeD2jhKDxrlkC15F8Twpgq.aE5gXyuX.lVuIf5U.jrnRTLNMCGS oAkJUeGdhVq4gTNxVDDwo_8j87J.U2TEWx209kjvmX3tneYeCEe1K_.tNoGMl1LjqlwV9FLggWL6 qFCFhDWwyoje9wjehh0F_6J1siL2sx1UvWYrP9Kqefq..SNKxZsZe6UHsEv5TQFSk3ukNWd4q07G FlhpjgPAYJ1PLbkV7we1aC1ymscpP8C1nBzKopfSb1tdRSTwpSKTtItmsYxk0tb0VJ0y9ZesvFSv jYnfuSYDPYCGpWUnXltA07a5B.7lr4HBVBkrTuphKvjxL7qP9vixbsCwN7lRlIT7xZCDfiJyRRKk 9K8P6i7vYW63G1KNswvjsp.aiUiq5bwU3ZEeJg6GlyeiKhPvILJRshhECmvRHZNcb84UfvrJ9H6f j44Gvt_NHhNvqEShzLhSD3TA1ZaJhWgEKZNTO3AcSFh978QxKbvPlTCz4hv4bOATo_rbQBSIX1a9 2O0efmNxVy..M_7Vx91WHli1f_WgQaEy_9ewYTtA1Tr8V1BYolA7nq5uKXRPXiDquUeEUu_C_qzO 75nav3racAQmwo2WNtXIWhaE.pu8EVM5vUuJMI7PzwWiRxoiNZI_gvrUnPaXys_mDDwk3E8gQV6p bV2Peo7IVymZLrJJ45s_jluYX4cwJ.52xQlzsRnvQc6rtAi8zCNzfgFixskQDYe7NEZ31B0SoxbW Mpxd3XmqoN3CygocvNAr42QidyHqAzupHi9pxN66wOLDgZIyufULM2FBgKtJnqHdjI6kGXCHPK7F kxhwY0bAd60GJz.vaFw93G5jYMsOPtObJfluCPGiMuWIST8j0vbBKAg_dRo3B1VxrcwG7ErSeV0Q EoHEzLXcLCspfy26soVmFpboEJ6H300iwwpcgs8zMXnj2wswASOKDWnWqaETQYqosxdZvvMza9HR D7nb2WYUHKTfW0nhL.lfkg8Bl2HsWqyWuWZ3l66jzHSz.MLcgyuyfOhfatNt7k8lgjKvBLURM0uQ aWpo72FdtyH7gxP0CubCBhzB7J_0THAY9g8SIGmGjXqqoEp5UR.0vPrMvnWiJSKqUuBMjyR3zIip RFHqiEoTgDah0DmaMzVbpYpgfKy3Dh.pJBHW3PDdtKN_SbWMJRJkVDQKzT2Xi76umvR0oqANjYRR kEX3Oo2hTXSKNgN8R5B6Y2ms3WMrkDHYI_OxteRHxumukOPHYM0mMqLFkcSexFyxWo8acX1j_BxD 7zwRrgGyVAYz0vvobEWA1GZjzsEeJUpJiR6Km7sxu81rWXeKv2QpLgrQUFm7fQ57qDKy45wQ5L9R yvsB8EEvAlEqXMjuhp7HUpYo8jhQ9Qq28po8DDN7XWNYuV_EvtWRPe5p1eMIlMwGOjCKE53Finp1 Ug5lyfCVVfOp.ZvkI4FPTIeoPuuxTBlB.eJCIe_l07lInkT1heGsZMHyAn9z2gBUG6PKtvH9HwNt 4yYsY0FAl.PV7MG8r8LprnZHLkxE3vYEPfQVE9jeg6g.AS7SE5YiRtGz8KgQjs7tzKoiEoIScFgA V5OHf_Vd5U6A3J11YilVIKw4SdFOYo7QXiop3lwqWM6mXeLbHMdtdcOKo6T8C5hlOHyX4exDXL58 mY5nUcxNw7ccNFtE0JZFtx4h9Pwt1V0LrGXNfk2m5Cr794m8dwx3Sbj2Cg9jHoIndo7OHd.UKSHM 3aD5wzklA_gtVF8m3Y3_.GVAPnp_hq8N0dKVT1FwhUvbxQYciiSP61xL4JdwEk149U2Y5bYi.F4O gsyanQmAikdxO.ZpVkt5OuKrskXUnBU8mRFMXxDe6le85MZkt2rns2a9YrDqPpKJlPpik_e2nyC0 fY_I9b9y5MaMZhuryAsPBspskfzgTRnc5XwjLoqN6LEJOvsyihdKjMzIYI4y2huGOUQbILmjpYke 3zMS9UcoVDYre9ekn.jE1PMM_WTGMYOpwn2z2nbNZKcak6PZqDmMCxiBM7Vk2QSwHxcbKCR7NrBc 3LUhfIpG0CZh5KO4FcSl53h4idIJFPJavWnh9Kk8kwLqAMaB9vr1hNv3nSTqERME1n2QuroUxHdj KaWrTJcIxWe_eW6a3htM99oWEdTygqCvTqBHCxDbc.wguVd3TZ6_kjFHZNjys9fM8dWeZbNMJcyW 75fD0ZLCfJqpM1kaP4KOPtJmaCKR0fxRes0o_qQnF2LVy9B3GQPf24geywP3wRlHHFyvDYwIw99w 3wEloZHhifo0YX5X..kI45QsgO03cgQe.jAXG3zM15RAarpgMBVL_HqFkx4M0_yviHtUc X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic309.consmr.mail.ne1.yahoo.com with HTTP; Thu, 13 May 2021 20:28:10 +0000 Received: by kubenode562.mail-prod1.omega.gq1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 6937fff4db5c11c6fac9189ee4f4cbb7; Thu, 13 May 2021 20:28:09 +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 v26 18/25] LSM: security_secid_to_secctx in netlink netfilter Date: Thu, 13 May 2021 13:08:00 -0700 Message-Id: <20210513200807.15910-19-casey@schaufler-ca.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210513200807.15910-1-casey@schaufler-ca.com> References: <20210513200807.15910-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 Acked-by: Paul Moore --- 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 719ec0f0f2ab..bf8db099090b 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) @@ -397,12 +393,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)) @@ -470,9 +464,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); @@ -602,7 +596,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) @@ -630,10 +625,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: @@ -641,10 +634,8 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, kfree_skb(skb); net_err_ratelimited("nf_queue: error creating packet message\n"); nlmsg_failure: - if (seclen) { - lsmcontext_init(&scaff, secdata, seclen, 0); - security_release_secctx(&scaff); - } + if (context.len) + security_release_secctx(&context); return NULL; } From patchwork Thu May 13 20:08:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12256581 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 4A30FC433ED for ; Thu, 13 May 2021 20:29:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0859761421 for ; Thu, 13 May 2021 20:29:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232906AbhEMUab (ORCPT ); Thu, 13 May 2021 16:30:31 -0400 Received: from sonic317-38.consmr.mail.ne1.yahoo.com ([66.163.184.49]:33275 "EHLO sonic317-38.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232677AbhEMUa0 (ORCPT ); Thu, 13 May 2021 16:30:26 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1620937756; bh=B6/eTJ18z4eQ+mOCYA8J02+OIxRGwvinHOaRQJDorLg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=d0ShEwHa37GKEmFAHXwRkeXPXedQQAIDTbpyL9TT/zENmYkA48MjTljeymGY7qw6v4CJDH7uW0AA7YmD0BbMVPRM8Zd5+FqrghU5ZzBkNpPongkqCbsR16H0TBSpS8cvZCrFaiNPiEV2D4/YXqaD1RBm71V+eN/tpAj/0DDRgHbng/n1e2mLuj7dFxsAjDuB94x6Dc0js0G/961k4a/QOF8aYGMF2T6OWJ+wp+E/57MKcgLUuPCvn0HLNkextFoRlEERWQm84WJQuCWWc/o1ZErfJ/+QsiTcVQD8FFh+ioLrcTaLSuJavAixSlDSPlS05ksQ0TPccd1McYZhRY63Pw== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1620937756; bh=cB+q4HJtWvPDRHd3q/Nkw/CgggArKTvReHOzgcVGCE+=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=t7A5WZVdrQ6XmtJ469jnc7Lec82h4aL7aiNoiMkvSOf4GOtAbCzePA5/FQDTp2xiTHHiqQkdcgYHb6Z8K2J/WEgQPBXS7JeFW1x+Iq81O49HCZf2QZPCfB40Q1RVW0RbWpEAZCJ+/wBxa+xLGNe8Yu3/YyBGNsRHmBUnBOnE4UYcZiEYZxt9wFJteOr8wZOPxtoK3/oI9VbVhTbmGaAyyCddCQyulWj8pFkqG7NomOdX4CzRRUqFhQiWCkdTOPzi7wjsTpkWmXHljjpnFvms3DITKWjTkaTxLgGFhQIY+8azP5C+QcVZMC0URuVDJYx6Yz0+eDNqwE5eBlU/CP10/A== X-YMail-OSG: oKBeU6kVM1mMc_cEu8U53A.NaN0abWzx8OkwuMzUmKYqAxGOjVM5U_pKnXskIu6 dEJwaFVRQQIeGLxaOrYvw_0jru8aaSfB9Fv_XjcyBDvlPt9dkCuWjq733GKmj4mR3SZyiAgEaDcp iXk3_a0eaVzfhpLb1ZzYmSOSumEWYwmX6odtlVTJPi1dCd0nAVPWdDYiUqhF37av6YcXvZNi_Sa9 9GfmM4lsbedS44OfFf.x2Sute5mGtOdt2MSbFAcuf81wYdrXmRqX2hs9v5gGXuoCkwLZJgOqNvpx EmvL1kihP.o7bAO9rXKFJhgA8kmVRQfI9ZSN40RSOzaRJc8qOdUmznW5qz7OwsgWKY.vlYHMb.Zb 1H.ywf1W3NMEFi17NP6q3rx5bYrTNpsz9FEXBATE7Jy_5.O0EV_Zx0Z0DtGSzZkSsV4zBmiJL6dX 3seq290zCbIUkJWd6X_hqf96c7Vq7KE84SxyeGJv3FknuMQ6wiccAaF.JbGUX34NW18OxY2yrDSm 070VUEGvyhbVb45iGNEvyJ8N.NVMRHNRQ7vVxiJgvzCQIXaBvGQ4oGXR6YL1vHc7jNBAiOJhOTNX _XECiOWOTd8RDebCU5jCeBLYm6tSQya7yQwEaoHAxJkfiwLmQgvgbgyo0DUuAFpufp69ghrfnwSV xAznDif2lWIEo1CIbEmVZNcvt5O4Aj.SmobgmZlGTCXRDjyVe9zePa1rNNKwhQDlijKYCPyjoekJ gWSXxQ5kVIHuJVVyzUzuC7TbNs5jAg.yRy.CWGBOYTgP7BFKH6KKtaRG5l2SUHE1qZraNHBVLp.E LgSBB6dBswsh6YbnLUxryNG1jdi89mIKZ4hQuooC7htiWma6BqHuAGmsNdkGl6a.QMoL6Wfo5VfI yzW.BAPP0iFm_77dPwIbfawzm_TjYnt_tZYuy8XP55Kq3VUUz3UCpGHRoKTnMHq39.w3P_ChL.ty MVAtsjiJjeM72u4pM0gBrSbro5hUM9TRR69LWcDg4Ed69t_y5DRStDo094GrSeD0y58QY7gv2pDJ YGfYn1Ec.v.nNGwf1fr7FR58_mjs3mcbVxmS8fZ2Fu_MAuJ_xSG_T0Jv2lEpG8kLUjckd2xi2hlj Ro47vGBezdFAqf32wvcRfkk2qwAtEJTVwBccEXf8NK5Dh6Oxg5IvFxyIuw4_nI_p_BnmntrJgyUr HyF86wXkljZ6oYcS.inggSZkVUIW83N7XbUmpj7S2gE1oNRaX9OEeQT_HP..G7.7ShVDxNDt2grN s0XqGNreZLnGM8CwGDQiUzQRqX70K94Rrx1Ix0oYvQqyGRwHYTTS5lznespj1_kOxpAs0TyvrXpq fJgDUHZhvQuRmyJvxlWUJ4bNaXCtZW_F7zONsyxc1VUV3Q.hpKg9CRWzgqUEgpNzbHtNUeMK5Ik5 FHqhCXJX1pz0zn7zvhVt6efuyjXvGjP7ihlg.QM8ApJF7jOTPH6XC0LvqovAY0HVryWwfY06cg9D miO2dVm89rpqQEcgmPKKnl1MC0GyPwSatuVEFn006JqXQ99ms2hsdMyW7JdL4F3rMxxw8zPwWJXu 36SUSrOI.ytxnFustvcBb1YHuhIKQHgi6fn1WYY2CFso8JMxuG8l6s_eZ8moOp692VPKlitDaOZw rNmLhlwxo1YzVNHi9imzNAgzMk8AwNdAXF5XE_.3eQ.h50Q.FcEUxGII68CeQaG0QWYUKZdP02G4 5RXepD1jVtTlj7spNo3czH9R6eQ4jCbJvGi5low6wnzXq7TRcLF9ox9im2PWaJKvX4qcJXQwtMkr hvaVaLz2uStOl6IoZhDTSGw7Uo.Xf.cWQ2kqHtk5h_i3cRCA_eSM8B3h11a1C15IFqOz6cVBxPEu PxABcKbqnf1U0HbAMLt_tX8DVRpYy6t6uoeTVJJQpie4FCmWEaif4q_TK4Q9AepPjfyt_.1gq8Rt PUFtWSUsHgHIXnRBHSPeTIhSUmN03QMYwWFbl8iasvb9YjV_MF7bcZCg5T5GjIMKxsyqwQyAUSI5 y5CCNPyJcEEKUTqfftIzEzrcUP3m46CXXGU2376J_DJaWtVigrunpVKnDeM52Ef7eDbLRwDTCPDC j46Zw2AHSgr2uMtJnYMlqEmR8tOUcM_BP5XRxCWymXDzIEMmDE1YEo6ZhjM_n4.mSWrEFif_OkhV 2dMnk5UXxn8iICQithmHPZJEw6QnNJB6MP9Q5onXJ70kxHuDPspL_4aU8wj4ZdZHMeW040VLDrkK ASwa67_Ad0EVkZEwJtXcIIxCY30x65LwCTo1byCbmAyQfB899CXDEJ9jpynpzQFvqPjBzwMMoyOz bkdwfvcud_NeWq2Sc0dG5sQgbSzTLySsbIoO4DdH9M4s2TAkkq1z0BtwP2as5sqIILW5_DmS3wUG SWpf7n2otUgFALAVD6zK6PWgPzb.1VRtneB5WAJw5wtEfb8GrkId7ojwTt4ARUTbTV29rJPU2zAO bwH2nj0OWv2Qo6AjyGR6SVeKGf6swBTtIEYxjSE7s0tavYcnlJfC3.71lx6QXC2rGRZWLduk5ZFo IgFz3DfS2zrvRz7HJC_qBjLMKVgeTf.8ku.xlJtg0Ut1upc16yfnrmByY_fYBHZHdsYM8i6Ge1VQ vSPFVTKomwb6Mjc.ltWPHAMTrem6G5Rht1mRuKxqT3S.h.t1KTzWs9ZxjolfoGf.hbu2OxhvCe2R cDCJqrPk0Lyn5coXr7tJYm87Nhc83zbs2EbiWIpIRv.QkFJZDcojt1DlZv93_d0ERaRtJvFXdbXl wu_.jJ_ZT3Bra8MWAe63l4EI1kmg7Wsa7LotJa53JtjoAmwNNUZiOAEaKzrErxO3dC8NvFW69Mzy 5X0Hzx_Xz2FlrMyUCt6DlFw4YwjaDpq0Qdq4CQ0ToJI25se5fTNxTCEn3ZegUFJgH.FrcfiT1It2 urGNmvuced5bVNTf1Ca_w9uqW8Hb4JObHG6wZBfznOhaO1mLjQAMRmu88uqYQsSehRzC8SVrRSWv J0dOPDKGzwiextyj4pmPHwVmvrkEIQQy1XYcr3tVT374fc8mx5iCeHxAI87jgqIBUbq8RV_4wK7x 6h6yVdwt5oOdEVq_6qbNYJiojskyx.VsLg43fVRsCtrYYyRONmOOMXu3JJOc9CVtxrT_cy3QEkP8 k_MywknMESl9ojrX4Em3x.D7ZG8KaBtswUJspsPuGyMaxZeEpFE79Q5TmhFWZPEmcxtTrlHTPAJ4 onhZPQVW1CFXZprrvwAey2Ft0 X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic317.consmr.mail.ne1.yahoo.com with HTTP; Thu, 13 May 2021 20:29:16 +0000 Received: by kubenode524.mail-prod1.omega.ne1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 46f72a20891a8e88b1a5185d10a2c10d; Thu, 13 May 2021 20:29:15 +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 v26 19/25] NET: Store LSM netlabel data in a lsmblob Date: Thu, 13 May 2021 13:08:01 -0700 Message-Id: <20210513200807.15910-20-casey@schaufler-ca.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210513200807.15910-1-casey@schaufler-ca.com> References: <20210513200807.15910-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 bfaf327e9d12..6f289821edb7 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 @@ -1460,7 +1462,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; } @@ -1480,7 +1486,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 3daa99396335..0ce9bee43dd3 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 dba867721336..b7800fa55a34 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -7122,7 +7122,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 ac0ece01305a..9f856f2cd277 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 0a5ce001609b..b6071e977cdf 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -3883,7 +3883,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); @@ -3960,7 +3960,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 b5bdf947792f..0eaae6b3f935 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 7eabb448acab..fccd5da3014e 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 7aa7ea38f627..e65497a5c095 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -3720,11 +3720,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) { /* @@ -4701,7 +4702,7 @@ struct lsm_blob_sizes smack_blob_sizes __lsm_ro_after_init = { .lbs_superblock = sizeof(struct superblock_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 22ded2c26089..e592e10397af 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c @@ -1140,6 +1140,7 @@ static void smk_net4addr_insert(struct smk_net4addr *new) static ssize_t smk_write_net4addr(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { + struct lsmblob lsmblob; struct smk_net4addr *snp; struct sockaddr_in newname; char *smack; @@ -1271,10 +1272,13 @@ static ssize_t smk_write_net4addr(struct file *file, const char __user *buf, * this host so that incoming packets get labeled. * but only if we didn't get the special CIPSO option */ - if (rc == 0 && skp != NULL) + if (rc == 0 && skp != NULL) { + lsmblob_init(&lsmblob, 0); + lsmblob.secid[smack_lsmid.slot] = snp->smk_label->smk_secid; rc = netlbl_cfg_unlbl_static_add(&init_net, NULL, - &snp->smk_host, &snp->smk_mask, PF_INET, - snp->smk_label->smk_secid, &audit_info); + &snp->smk_host, &snp->smk_mask, PF_INET, &lsmblob, + &audit_info); + } if (rc == 0) rc = count; From patchwork Thu May 13 20:08:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12256583 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 78134C43461 for ; Thu, 13 May 2021 20:32:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 56F6C611BF for ; Thu, 13 May 2021 20:32:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232958AbhEMUds (ORCPT ); Thu, 13 May 2021 16:33:48 -0400 Received: from sonic317-38.consmr.mail.ne1.yahoo.com ([66.163.184.49]:36094 "EHLO sonic317-38.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230427AbhEMUdq (ORCPT ); Thu, 13 May 2021 16:33:46 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1620937956; bh=sJ9e8qsmpa5HneGdK4dPH8thQK5rJ0jRuPc0AgwVcI4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=EauFfg6M5Q0w4DZRikeATnp8ogwCw1+9K/KbDWfxFNDVYjZruRXPas/0uiSnaCZKxoeO2bZBUvumpb51vEwftTG1ndEoIRRARFN58T6BaRad835JUrZsjFhvLw3hVmS/lnNGZRepu1M0bvpzciYrgiZ7/+/8t9biKZPt4SPU4mhGJlu0nvUrXWHoeaFKhu4Vl6+CttsoGM+/pVFlef8v/oRfRRfaFXkfD2lplV0yC5iWF291cxdteJT0UD1at3WHHCTxF1VNm1dHSKSGnJbiKtsC22e98ahXVTWOaeNUp3RBl0XROyEqoKVM85ZKUxUltw59TmN4ViAu1zuNSRiV/g== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1620937956; bh=z+Uplu/4K2KS5E/XqCMsbkvJFCRZ7CaF4qefZ6D/R6M=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=nxzTwifUUhcccIVnkLXe1YdfLAXQcyG0r/a48vT30S6g93slBZlajfo/4JXCIJ+7N4UreoXcpf6NJZJ7JiI08Sv4IPiwNFlAu88qMvugc/eTxb9kQIXB8vUUTDJ2VWE17AA/mIN4G+8YwghcqUm/a9iM5PNXNFuG1u3W5dKdO64TgZjc6//wO/YmGpkPP3tv0CGXslytwSNSSVl2x1skrqTTP21GBfPYnqZZ28VON8V4ljxvlgTn6IL6JENGr6VoNtdzYoiM6IbwzMjM/8q5aIbOJ3OnJRxSruHwz3deiXtF3zLmFnQ8IPJ4YOmO2ypdYW41WAZgvrDGSDewiBppHw== X-YMail-OSG: vHYBfcgVM1mNMqnZFBL7UTydBQQ92gKWNn.QM9AqkUT7HdDYqKPza9ZEGL60cO6 zDS1n5IfdF2taKkV2dUTaVKgp_NtN4jcdWr7m2w2ajAlVDJZn8WVDd_h87b1CxEaEDNMgotEA829 PAA6PnaBOpBEM59P6DuJ5swfj2qgj_4iT2tYNL5sy6eaeXtyGTkQBS9E9B5x9SBlL4htkZ4q6QPg 9VgCqzIwIh4pvTTk5EmFlsXf28kcPp9uqSOYjOw0ndtPwd3OSs5_fc9RFeO6DyeP3Xz7Ofblx.NX lp14.n4k5ZPInaOLHF.RQ3VC1Vjo_0KC4BxmKNuHIykRaP4puKfyaMbAM52OW0BkgK4Z8fYivKgb QfPESv0S1g4lIufT4WjyhewPiBeLsejGDeQsLZJt5JYpV7S1Irhccpu1jfQ.sbA2.uHqRAhimguq yXgIoBPdQfEuHV3kD3VrFXOQA4pM6uHo3JqFaZsoXMUTYdFRU1NOHrKkBiD7EXUbg4SfOfTdmKP8 EzRTVZXMCFSP9eOpZAYUkcbt793ahVkCoHB_1X3JYUGeUPhzXFpEgXMPt_DSOOdDIQC.adjbSIvu srvsQ7YmJjYJuV8VGFkk7K4ibFvisywytAOySBSk3HfhcukXUQpjDgxKCWcPWgIBkLCowEABK7eO u5Zi9TtkvItOeDYMhKNLSE1P9Iq8ZGggtSPtgWfiS.9t2nB2tNvIEWfoUZXiiqIN9buqhXhI5qGn O1lxzU9BhhYC_Iaa6Ow0zz9ZccpKHFnJ69XPxBpP7eXnRI5SO6GrJ2xqsIqOe3gJf6P2R.X.UWk5 8gPIfIPABul3Wt8lKQgknDO9MCJWQVESw4GRDQmy5nb29MjoY6gdj8EFshAA1okRa6zXDonSr3Sv UAAzxRDXxjTUZYBwSSYj09h_3cu9zDVDzq7ImHeHWIAfz2iQhMJsfC5a_FgRDh3_iHmDkTyv9A4M UfSpYcFdlImiVBK0AC_LKdYEFRGALz.ipveDbQHq5FFowZo_GmDidFTRwDyAWoLHAEkU9HFa_WLH 1tUT5.FsnAzU40y9KpsVPZMb4FFDrquGdHnqFSIfTgjVuxxQFEgt34i0AIbHz7HlH1DYYiBLvPEQ tszMxoeAYqDiofrFXp7xqmr.k8DvxadlGq9uuUskX.3OEKRabL.RGezxrsU6_1OSZ3KzjjdH1Ehk BKIhLZaXz2aA0C4InPW4_vc1mJxaiuzVN8guNR5SE4BhEf.s6zf4qWKJ.ojXZB.npcRTqodI9hjk AG94OS0CYzPbkLL9I9L8HFalreuEIzVh1PZAg.20Yc8V1b9NNvP18qXGh5npYxGIKy6L6lQ4H7Ck DFvBmY5tSEZVV64NwgqzdIQuETfpiztAdEqOcYpfQxRvHEI.LPX9eUpLLEvLVVY4nEPnmt3Q3Yvl KcGgjJtSo7XqIVnsi8XNHxnQyriu0f0QjFIiiTefUu99kggXh0TbWU.UWW4UW0iXNMSdTn23irWu XHd.4wmk4Juj7ZxnlRsle0WIXTxod5gJRn66sllYTzPbPxtFHyZ_hbNqdArGCzc6T0qfxh6kd7RH 3ch9ouO8eMDlN5gFtOV2rMNiTi78YeusigV0GHgPrD5lRwQgJqmGgho6ZCYn2of3gbviP7VsWIBm MjhKr0havbayQqse5EL.5FaykCu3aklo9.Nn52AMIFm9QbulBsIxGS00rh_NbFko7AUQSXSxNztS _UUUlcIC31eS6q1ev8xtOfHTjcHL7j_tt24UczrE.v4P6I8E._dN.WUMB9bUtCUWswHLAIsYtO38 z.ou_LEHDmHE3tHciiHrollapmlUV3hnMyhric5hLydzA8hG0DAEfPiIEXtzhx1vqLawQ5BBau.Q IDhh9TDX7ySs_W9hMF36QHMe544IkUMEyqoUUBP8l54n_nVTjc8WxnII1T5lC2eSqrsN_idmldq2 NvRLzvAweGU_sEI8f38KeUueoLs3aOnmRjpCJBBCGQKLNkKODk.Bcfcka6uSKx29AGzcrhapPtv. nBIyT.1YsefBM15JgjISFVNCfR4BYyJ.ghC_9JR3sdTqrcRo9svdqOrFopxn5zwQ0xUnDkFlwFPQ 1faFBLPr1ihgSjN4C4wgKMQKHynl7I2fKlTDpQqLi.b1qScYU.J7tDKY3P10PnocUTDUGEbKXp96 mYYkOQx7vh9DoI6UKcXa3A96iZ83VVojy6oQ2HAbM41C2jHy5vCHTRzOFAXP15X30nfnk2uSq.wU Vf.B7H3J3n2wRHnQIsTAdYCn0Shho.u0JEfM6GIK4QOtkxEMruOvtCrpajMUlr4y7ABUo6AZqbdA MFs6Vk1Gnd3RaKZ0mtX9yUyoV8pn5I9IkeNTj87ja9CM1K6U5VUy7EdtzfMeiWxcmEOS_yVOfc18 bRJgrJyD8X4y64s2TaepTN_0u6G5RIX3C1Q3DMgo82QfWzNwuHJ78oGOAz0udsrJVcH1_AhuC.3a _QydsFmSWuEiG2is8SPQZHPPW0T3Eea8M3y6vByzpFXQs7KbBd3FO5WhstRIu5rdpqxmT8BhtC.C qYgWShZjHbPjYg7RYOn6OQOzfdjuTchNvsEHlC_Qyw7BZa6nq602zRyr480ZueNop9V5yrS9QH2o xIFnvcIils.OlVr0fTPM9KfBfCKSUz0l0800HEuhIC7.0ZqEY6syav6Id2_Y5zxz7008zYMq3O3v TtT5VsjTKP3SqyDrd.4jGIEmFPgUOofdJsmFw_xg_YtWF36Swi2RnLDYDdciqvC2PpHRqS7wCbgN L6qIWL2JoEf5ZLo1RJmsqNpGfWhhZ9Nur8iE6V93fdFcAb84g56Cdd2Qy6k6.EsIP7Lx4sPKPlI1 baLc5p64UgnD62YoqNqeScyLxfevWWIXgGrtQfqtXGa2ABd2UXso0Q4Yrq4rYPYuVlKM8DqPK4jx DQfLHTcTwPcZVSf_hJmcM.MvYpUih35Z8LsD1xKdzYteRUb5qotvcDy8St0ihGvxDBGqZe81aAWj cIpsdCd0fUDcNesL0qkOcafWnLinhdpD6sCTrcJ_gyWrQO5cGMpI1krneAPIOHqqRz69MsltkJgf rjuNN2FcwQ42uBa67Lm.8m.TTL.xDH32Au6q5U9FsYntiQxY3hiiPcXAIHNmjdDeb.PrSRYkBkRE LdgL8IsWm2Xhm9I.bTSuXjeXYJkx4z7p72LxU0u_8PL2Pkq7nBBOr0DKd_ljo4UzR8ZMNqQzfHo8 AIrHw9iyveaZ8F6NXbEzb.F6uIPt7a1mzVKXd7kJSxw-- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic317.consmr.mail.ne1.yahoo.com with HTTP; Thu, 13 May 2021 20:32:36 +0000 Received: by kubenode518.mail-prod1.omega.ne1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 30b071452c09b5da941082a96c8657ff; Thu, 13 May 2021 20:32:33 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov, linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH v26 22/25] Audit: Add new record for multiple process LSM attributes Date: Thu, 13 May 2021 13:08:04 -0700 Message-Id: <20210513200807.15910-23-casey@schaufler-ca.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210513200807.15910-1-casey@schaufler-ca.com> References: <20210513200807.15910-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 To: linux-audit@redhat.com To: rgb@redhat.com Cc: netdev@vger.kernel.org --- drivers/android/binder.c | 2 +- include/linux/audit.h | 24 ++++++++ include/linux/security.h | 16 ++++- include/net/netlabel.h | 3 +- include/net/scm.h | 2 +- include/net/xfrm.h | 13 +++- include/uapi/linux/audit.h | 1 + kernel/audit.c | 80 ++++++++++++++++++------- kernel/audit.h | 3 + kernel/auditfilter.c | 6 +- kernel/auditsc.c | 75 ++++++++++++++++++++--- 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 | 20 ++++--- 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 | 46 +++++++++----- security/smack/smackfs.c | 3 +- 25 files changed, 274 insertions(+), 107 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index f2a27bbbbe4d..7818c0fe0f38 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2722,7 +2722,7 @@ static void binder_transaction(struct binder_proc *proc, * case well anyway. */ security_task_getsecid_obj(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 97cd7471e572..229cd71fbf09 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); @@ -386,6 +395,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); @@ -560,6 +582,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 0129400ff6e9..ddab456e93d3 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -182,6 +182,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 @@ -248,6 +250,15 @@ static inline u32 lsmblob_value(const struct lsmblob *blob) return 0; } +static inline bool lsm_multiple_contexts(void) +{ +#ifdef CONFIG_SECURITY + return lsm_slot_to_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); @@ -578,7 +589,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); @@ -1433,7 +1445,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 c58a6d4eb610..f8ad20d34498 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 841123390d41..60c027d7759c 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); @@ -1110,6 +1106,7 @@ static void audit_log_feature_change(int which, u32 old_feature, u32 new_feature audit_log_format(ab, " feature=%s old=%u new=%u old_lock=%u new_lock=%u res=%d", audit_feature_names[which], !!old_feature, !!new_feature, !!old_lock, !!new_lock, res); + audit_log_lsm(ab->ctx); audit_log_end(ab); } @@ -1190,6 +1187,7 @@ 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; + struct audit_context *lcontext; err = audit_netlink_ok(skb, msg_type); if (err) @@ -1357,7 +1355,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 +1369,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: @@ -1378,13 +1377,14 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) if (data_len < sizeof(struct audit_rule_data)) return -EINVAL; if (audit_enabled == AUDIT_LOCKED) { - audit_log_common_recv_msg(audit_context(), &ab, + lcontext = audit_alloc_for_lsm(GFP_KERNEL); + audit_log_common_recv_msg(lcontext, &ab, AUDIT_CONFIG_CHANGE); audit_log_format(ab, " op=%s audit_enabled=%d res=0", msg_type == AUDIT_ADD_RULE ? "add_rule" : "remove_rule", audit_enabled); - audit_log_end(ab); + audit_log_end_local(ab, lcontext); return -EPERM; } err = audit_rule_change(msg_type, seq, data, data_len); @@ -1394,10 +1394,10 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) break; case AUDIT_TRIM: audit_trim_trees(); - audit_log_common_recv_msg(audit_context(), &ab, - AUDIT_CONFIG_CHANGE); + lcontext = audit_alloc_for_lsm(GFP_KERNEL); + audit_log_common_recv_msg(lcontext, &ab, AUDIT_CONFIG_CHANGE); audit_log_format(ab, " op=trim res=1"); - audit_log_end(ab); + audit_log_end_local(ab, lcontext); break; case AUDIT_MAKE_EQUIV: { void *bufp = data; @@ -1425,6 +1425,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) /* OK, here comes... */ err = audit_tag_tree(old, new); + lcontext = audit_alloc_for_lsm(GFP_KERNEL); audit_log_common_recv_msg(audit_context(), &ab, AUDIT_CONFIG_CHANGE); audit_log_format(ab, " op=make_equiv old="); @@ -1432,7 +1433,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) audit_log_format(ab, " new="); audit_log_untrustedstring(ab, new); audit_log_format(ab, " res=%d", !err); - audit_log_end(ab); + audit_log_end_local(ab, lcontext); kfree(old); kfree(new); break; @@ -1443,7 +1444,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; } @@ -1498,13 +1499,14 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) old.enabled = t & AUDIT_TTY_ENABLE; old.log_passwd = !!(t & AUDIT_TTY_LOG_PASSWD); + lcontext = audit_alloc_for_lsm(GFP_KERNEL); audit_log_common_recv_msg(audit_context(), &ab, AUDIT_CONFIG_CHANGE); audit_log_format(ab, " op=tty_set old-enabled=%d new-enabled=%d" " old-log_passwd=%d new-log_passwd=%d res=%d", old.enabled, s.enabled, old.log_passwd, s.log_passwd, !err); - audit_log_end(ab); + audit_log_end_local(ab, lcontext); break; } default: @@ -1550,6 +1552,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 +1561,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 +1580,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. */ @@ -2138,7 +2142,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; @@ -2224,6 +2240,7 @@ void audit_log_task_info(struct audit_buffer *ab) audit_log_untrustedstring(ab, get_task_comm(comm, current)); audit_log_d_path_exe(ab, current->mm); audit_log_task_context(ab); + audit_log_lsm(ab->ctx); } EXPORT_SYMBOL(audit_log_task_info); @@ -2274,6 +2291,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; @@ -2281,7 +2299,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; @@ -2296,7 +2315,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); } /** @@ -2396,6 +2415,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 + * + * Emit an LSM context record if appropriate, then end the audit event + * in the usual way. + */ +void audit_log_end_local(struct audit_buffer *ab, struct audit_context *context) +{ + audit_log_end(ab); + audit_log_lsm_common(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 27ef690afd30..5ad0c6819aa8 100644 --- a/kernel/audit.h +++ b/kernel/audit.h @@ -100,6 +100,7 @@ struct audit_context { int dummy; /* must be the first element */ int in_syscall; /* 1 if task is in a syscall */ bool local; /* local context needed */ + bool lsmdone; /* multiple security reported */ enum audit_state state, current_state; unsigned int serial; /* serial number for record */ int major; /* syscall number */ @@ -131,6 +132,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 +203,7 @@ struct audit_context { extern bool audit_ever_enabled; extern void audit_log_session_info(struct audit_buffer *ab); +extern void audit_log_lsm_common(struct audit_context *context); extern int auditd_test_task(struct task_struct *task); diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 1ba14a7a38f7..be59ca46b0a2 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 d4e061f95da8..55509faf5341 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -940,6 +940,7 @@ static inline struct audit_context *audit_alloc_context(enum audit_state state, INIT_LIST_HEAD(&context->names_list); context->fds[0] = -1; context->return_valid = AUDITSC_INVALID; + context->lsmdone = false; return context; } @@ -987,12 +988,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); @@ -1013,6 +1013,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, @@ -1030,7 +1037,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 { @@ -1275,7 +1282,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 { @@ -1430,7 +1438,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; @@ -1504,6 +1512,47 @@ static void audit_log_proctitle(void) audit_log_end(ab); } +void audit_log_lsm_common(struct audit_context *context) +{ + struct audit_buffer *ab; + struct lsmcontext lsmdata; + bool sep = false; + int error; + int i; + + if (!lsm_multiple_contexts() || context == NULL || + !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 ? " " : "", + lsm_slot_to_name(i), lsmdata.context); + sep = true; + + security_release_secctx(&lsmdata); + } + audit_log_end(ab); + context->lsmdone = true; +} + +void audit_log_lsm(struct audit_context *context) +{ + if (!context->lsmdone) + audit_log_lsm_common(context); +} + static void audit_log_exit(void) { int i, call_panic = 0; @@ -1538,6 +1587,8 @@ static void audit_log_exit(void) audit_log_key(ab, context->filterkey); audit_log_end(ab); + audit_log_lsm(context); + for (aux = context->aux; aux; aux = aux->next) { ab = audit_log_start(context, GFP_KERNEL, aux->type); @@ -1628,6 +1679,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) @@ -2619,10 +2672,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", @@ -2632,7 +2687,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); @@ -2667,6 +2722,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) @@ -2675,12 +2731,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 215d3f9e9715..60539221e023 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -344,7 +344,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 df6043d1bc22..861106a5f605 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 bf8db099090b..90ecf03b35ba 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 0ce9bee43dd3..380eeffd8e00 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_subj(current, &blob); - /* scaffolding until audit_info.secid is converted */ - audit_info.secid = blob.secid[0]; + security_task_getsecid_subj(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..90a18b245380 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,11 +101,14 @@ 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) { - audit_log_format(audit_buf, " subj=%s", context.context); - security_release_secctx(&context); + if (lsmblob_is_set(&audit_info->lsmdata)) { + if (!lsm_multiple_contexts() && + security_secid_to_secctx(&audit_info->lsmdata, &context, + LSMBLOB_FIRST) == 0) { + audit_log_format(audit_buf, " subj=%s", + context.context); + security_release_secctx(&context); + } } return audit_buf; diff --git a/net/netlabel/netlabel_user.h b/net/netlabel/netlabel_user.h index 11f6da93f31b..bc1f0cd824d5 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_subj(current, &blob); - /* scaffolding until secid is converted */ - audit_info->secid = blob.secid[0]; + security_task_getsecid_subj(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 ce500f847b99..a4d554214d4b 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -4173,30 +4173,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 4496f7efa220..a1fd0e122be8 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -2747,29 +2747,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); @@ -2779,7 +2781,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); @@ -2797,7 +2799,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); @@ -2812,7 +2814,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); @@ -2826,7 +2828,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); @@ -2844,7 +2846,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 691f68d478f1..8e7c660b9b01 100644 --- a/security/integrity/ima/ima_api.c +++ b/security/integrity/ima/ima_api.c @@ -342,6 +342,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]; @@ -358,8 +359,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; @@ -368,7 +369,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 d1e9a54e22b4..bb4c7f6c62ec 100644 --- a/security/security.c +++ b/security/security.c @@ -2307,7 +2307,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; } @@ -2352,13 +2352,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; @@ -2388,7 +2406,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); @@ -2882,23 +2900,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) @@ -2930,6 +2942,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 e592e10397af..d56e55c04aa4 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; } /*