From patchwork Fri Sep 24 17:54:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12516365 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 56840C4332F for ; Fri, 24 Sep 2021 17:57:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3819B610C7 for ; Fri, 24 Sep 2021 17:57:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345357AbhIXR6h (ORCPT ); Fri, 24 Sep 2021 13:58:37 -0400 Received: from sonic309-27.consmr.mail.ne1.yahoo.com ([66.163.184.153]:41279 "EHLO sonic309-27.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344997AbhIXR6g (ORCPT ); Fri, 24 Sep 2021 13:58:36 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1632506223; bh=zEEMHZqg1wpNk81xEuosfeDezE+zGzCw/HrPZ0wK3P4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=FgRXTwnxUcRCfHLRqMxzJNMr/yE5XDIu5mN9amCTf+YKMrYxhHKPHcDH4d/WpCJyyTqJW9ubu0LXqpVZc1Y5JvWCd8JHRsU/x0wdwaZxt5IZ6z7ZfBfyvkxVw5W+Bu2W3oRJR24+eIo0XyVRYp5IerrEEmIX31049v1mQ09q9ndPnsl8ks2Sf09qWJYcwQPPCTwlnxqw1dfCQb64TyNMIprG6MC1bFMpN6XzfbyTmo2/ZhbbjxkFf72Omi0BnK8t5ZW0uFTehH3hcXQNNWgVzz2FWF1Tz6E7zR4KODvbno+G+O/Nkn0aDhYbMI43jA6lAt71Y4469nRKWQj+DKdCBg== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1632506223; bh=zM6Ib4cqssCLFCfVNXjawAbvxHoa/dHFGukia5H6L/f=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=UOGQ9o1Xti7D4hqYBSyMgW0VW82aoO2RXh6JbDXxm0HauFBKJq4IP7cSE7ROeM+kUv1KkTCMkSj/vSZDwn9Dh+uIUwS0CqqcPJ9R372h28+KWzCK/wckcgDhNb8lWioeksPiKUrGiY2GswGnSYVQZb7gIn8dbkBOwa0gduz+wSKoLqg5IUb9qOwhFrBAaHnjZC1DgVau5T7tdD5KCKNtd6crBubJaxG9m4IkOde1OWij5vSv6bT3opzBWGQswceACBo3vftrmKmP28S6042yNSDUR7T7BoWiK6eSNgB3vCcovguDc6V9Jp7vv46mI1B2uOZRNUIRn5/CkQBmqFy+rA== X-YMail-OSG: 2WNoQ_MVM1nQRfuKjPRGrREgOplFamg8.qGf_dRD59d7HWAlmyFamQxHinL8sCg atd0wNnEpNYMVKAk47uTVd7tEQhiKcqOH9MH5ITtZY6DiPDHy9I1Y.xMixyxac8Uw1tylWfP_gvN 1t9B1s05n6Xog7TZV.8Kn5LoWik4Jpz9o2alBveyT6ryN3d4sWMzVDAS1zotSZxTGjWATHq14MPq zctRlioDzAzci9DouI3FEcUDpiMD7tq4jVyzv7gsMQYYRSCVgnKcTMksE9N.g0ayD_nqwZTXLvij qKvEx6ntuvMvNLINEoNCXTuA4YpZ4267A4NwT.xZC1v5QRDTob4ib9boA8JXGY6c4UI960evpl6x ncAfLSJzH8iitXE21ylboII_LNjXMeT2VcVifpKooixdLAhVx1N7eF2qI7HYo1_QlQWCv1.FLHTr zyGXzMWRzw7Kj6pVGt5UeJrAyVT9UwOEeTsLryaDImv2UY2Kr.LEP5jwDjbNVS1JM3tr0Qa.OiPB Ys342HjcdR71ij6fZBDZAUuLyCVaaOB2kikoM9dOSr5Dc.lnA2DqZ1MXSqmrxbvYO7cu_XrIMtjJ RDf1muoreOUPqkSJVyG3mSfZSS32Uw9PZdw7OJQFhmVTVR3_aj7.6YbL2Z2BEqcjCn5mtTIq8lBq 7Fq_zNCwkGk4zbEayZZmH7an0IlA8OgzkcE3HEztoCQvFusvqpuGdfb0RzwVig00x1ZgtxSHtPGI 28lXTOrCFCKIA4Rl_.AOnml0lnkpeQFqsXLUtK0WsPAmmHskFxlI9TM8_efUVE_ibQ_JpUj5LcP. xUw292PkS_OjyWYzKxl6a7hboxYdhYM7zqCZ7SBBuFeFvosB1zLwgdAulXCdWQNRDK.783XOj45. PTnfguMQ.b1XWACm0qvvMzewDXZDjiYnPrl37xOYfQWMETGUMem7H4kO.yr_0uya5_HjVM6wa9IF Nz.jZeVwa0njRMVGSgePyEVAE0Dq.Ytv_CZPDUGLyODgQyL.5rX5uEJzAS6OkB1Qv5kAl.up.W0Y k7UZRVoOg9XOWaoVwCN5P_GHqswpRjWicSTbcGw8G0L5jSqNkkvIp8m9aJis9..mZ_R02gKrCMmJ I0oY9BACSpO1eHqwYrmCjlL4jsgSkiTyWmm6W2hDeBLA4cnLS6avDUtNxiQeq3bQ1JXsVCqMRRGw u4Zr_mncbC6ZUOgwJQKuIjc_H7amz8ltUesJhS7STRtB6J1UGF6yT900.L3pIhmkpnLOv3_SXpmF 58etOfyIiSJSh97jVSUX8Op_qizmLtOyF5xY6qSA919858swMZbIDdCWjjZcOjVILQkWTKmroeFA nlfZAajGCekN_5kofC_.yiRC26zJa.ssNJ.oZujeEEOBw4WepMj19YMcWUK8DsKf1.jsrFqYNtmA IeKBGGcPY91agWDwqrphS4HtIsrVd0JI7QxovHBXqt6PvnWM4eM2LAOFFrnooTK0iOL8bhPbuG3b S1_w7UsrGRpWKau_JziGo8tmyxAoZmNM8ljOB_aotbxP01xI1wESpxK1SDRmCwiQLe9_AXubvdLG EVso9BKmYQo2.3smODiRs4W9A9T1.YWBGAmP.tL_VvGQxe492AHtuh4jR0qJEwSGe0vKpim_yEJ7 S4rmKmmFoc6nyBLmWyjVlT.XxmMz38IpLD0QOL3hIrE16sbnSGjk8JhCGiIyxyL3hUCKeLjQGvX9 vWkgLvCYpixAIJKkX06Lx8Vd4KGCg.jZKNxTNCDLZpeFtIEbu8rVH9HxLVK2BAczA_XT_t67LCH1 X7RFicbiDhKRY0HT3v.N0_zevFea5TgQ68uAb27BbVLjdVcQqO0nVfVAhtphM0nAn01E.3XCAHj5 wpZog32uhA4a5N3yNJy88En8WDydI6kgcR7fG_T9OKrAczeML8zUepki9hqeTHbpPZqbFelMW1yb bFIiH5hk0WAhH4O5SOukoQLGMzCBO2k77WYMC1vPM7BPMpWlX498_HhQzn1iK.xPOu1ekK5u7wLs VEkBQ8zeA4OnW2EDGguS_V6ptoUElDpy3P2Xw3Djab27PSx1R1kfHqAm_Vgsb0953a.polf4804J btsrs3Rup8fICJtI4HQ_Gh1_2.p6xcbQOlkwsw.oU44QaVDw6heOGLFoRPJXKogDmZ0FSu35TTqE ryKJCBn0XJgzA5wbECScxbnX5c6q50RLll_jNMjU9.hVuMp49YdDJypVO26F5VbOc6ri9b9_Aup_ gaFJjv5AMnJE_caEjgKWQ_R52YO9aJcqn2huJsmhtbUfb20_TgUYjyOSrcVm9R7E0CIbASzaB3lU X7.3N_Y3_W2ZedU7kF1dC3_KIF5hIbQ-- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic309.consmr.mail.ne1.yahoo.com with HTTP; Fri, 24 Sep 2021 17:57:03 +0000 Received: by kubenode548.mail-prod1.omega.gq1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID ebdb4900de4e3e0b5dfd5e27d0e3044e; Fri, 24 Sep 2021 17:56:57 +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, Stephen Smalley , bpf@vger.kernel.org Subject: [PATCH v29 02/28] LSM: Add the lsmblob data structure. Date: Fri, 24 Sep 2021 10:54:15 -0700 Message-Id: <20210924175441.7943-3-casey@schaufler-ca.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210924175441.7943-1-casey@schaufler-ca.com> References: <20210924175441.7943-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 | 5 ++ security/landlock/setup.h | 1 + security/loadpin/loadpin.c | 8 +++- security/lockdown/lockdown.c | 7 ++- security/safesetid/lsm.c | 8 +++- security/security.c | 74 ++++++++++++++++++++++++----- 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, 265 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 5b7288521300..1b05094468b7 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -134,6 +134,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); @@ -1882,8 +1941,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 @@ -1899,12 +1958,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 8dd73a64f921..acbd896f54a5 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -671,14 +671,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: @@ -688,21 +687,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; } @@ -713,7 +712,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 87b9b71cb820..cbe6f1244e31 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -84,7 +84,7 @@ struct ima_rule_entry { int pcr; unsigned int allowed_algos; /* bitfield of allowed hash algorithms */ 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]; @@ -94,6 +94,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; +} + /* * sanity check in case the kernels gains more hash algorithms that can * fit in an unsigned int @@ -347,9 +363,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); } } @@ -400,8 +418,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); } @@ -590,7 +608,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 @@ -603,14 +621,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; @@ -1046,7 +1064,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); @@ -1056,8 +1074,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); @@ -1954,7 +1972,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..759e00b9436c 100644 --- a/security/landlock/setup.c +++ b/security/landlock/setup.c @@ -23,6 +23,11 @@ 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, + .slot = LSMBLOB_NOT_NEEDED, +}; + 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 963f4ad9cb66..0c368950dc14 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 26df1ff0b529..b4af710fbb90 100644 --- a/security/security.c +++ b/security/security.c @@ -345,6 +345,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 @@ -472,21 +473,38 @@ 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; + WARN_ON(!lsmid->slot || !lsmid->lsm); + + 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); } @@ -495,7 +513,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__); } } @@ -2071,7 +2089,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); } @@ -2084,7 +2102,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); } @@ -2577,7 +2595,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) @@ -2585,14 +2620,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 9f050bdefb17..824a0df03aca 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -7107,6 +7107,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, @@ -7420,7 +7425,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 f9c6940e6991..9474fcdaf002 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 b6a31901f289..e8f6bb9782c1 100644 --- a/security/tomoyo/tomoyo.c +++ b/security/tomoyo/tomoyo.c @@ -521,6 +521,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. @@ -573,7 +578,8 @@ static int __init tomoyo_init(void) struct tomoyo_task *s = tomoyo_task(current); /* register ourselves with the security framework */ - security_add_hooks(tomoyo_hooks, ARRAY_SIZE(tomoyo_hooks), "tomoyo"); + security_add_hooks(tomoyo_hooks, ARRAY_SIZE(tomoyo_hooks), + &tomoyo_lsmid); pr_info("TOMOYO Linux initialized\n"); s->domain_info = &tomoyo_kernel_domain; atomic_inc(&tomoyo_kernel_domain.users); diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c index 06e226166aab..a9639ea541f7 100644 --- a/security/yama/yama_lsm.c +++ b/security/yama/yama_lsm.c @@ -421,6 +421,11 @@ static int yama_ptrace_traceme(struct task_struct *parent) return rc; } +static struct lsm_id yama_lsmid __lsm_ro_after_init = { + .lsm = "yama", + .slot = LSMBLOB_NOT_NEEDED +}; + static struct security_hook_list yama_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(ptrace_access_check, yama_ptrace_access_check), LSM_HOOK_INIT(ptrace_traceme, yama_ptrace_traceme), @@ -477,7 +482,7 @@ static inline void yama_init_sysctl(void) { } static int __init yama_init(void) { pr_info("Yama: becoming mindful.\n"); - security_add_hooks(yama_hooks, ARRAY_SIZE(yama_hooks), "yama"); + security_add_hooks(yama_hooks, ARRAY_SIZE(yama_hooks), &yama_lsmid); yama_init_sysctl(); return 0; } From patchwork Fri Sep 24 17:54:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12516415 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 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BD228C4332F for ; Fri, 24 Sep 2021 18:02:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A40DA61251 for ; Fri, 24 Sep 2021 18:02:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345852AbhIXSEK (ORCPT ); Fri, 24 Sep 2021 14:04:10 -0400 Received: from sonic308-15.consmr.mail.ne1.yahoo.com ([66.163.187.38]:33769 "EHLO sonic308-15.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344901AbhIXSEJ (ORCPT ); Fri, 24 Sep 2021 14:04:09 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1632506556; bh=05vdcWHZL4PkRaRnUTngQZEvbM7FJn/OZ3TNy3QRHg8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=tbOdvGyhBLC6MHANNxhW8/jvzrBae5+bFD6Fr8Pnp91BPSKXGqlSj91rSwC1TYLlUqkQpT8UqHqArFYdRHlgkkywWRuRKGTtdrn986nn8cXpp4slwddtMdWvr3fcyvDP3zPTdpj6KQA9evtTWBhOH50VqOLu4v0tvegrIZZDY3ZPqOXwstWsh+B9FGK08YwZla++Fc76U0HngSt7flv05q7mLA39Uj3gn7sWIHWmqv9F1nTdGubMHTN2HPj/qc27qJ/XSO+aEac1QMmUz0RdvW3W7Oem72PfGIH0Ev0f8p0p1+YLYl8XaxOhIVt2oWWqlOr+mvaDwp9hLhcENrd7oA== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1632506556; bh=9k63uR3ERKxbEPkcntgv7N+g7Hm8OqDyMGuwOA6rfHe=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=YT4rBlxg0osAkCUb7E+/Ie1wpcMZbzdhINv1eZ3U9gJuiESsK/ANXsdGTNz4E2jVKmtMvKN6cF5q/gZus1imDeGBX4ShA8NiYC2A2zlxHZBj2WxAQ9BNIql3kGZMDYX3zEHBjs2s1jmcoNAP0nOuMxxVpOZ0ZCSif+uEn+aVTc72m6uHDrTLSUOLXvsOh/RhjjAbLSQKYtNaT+PULy5j5yTHCEMrG6+aUznZLHoSxXF/kN5QLTpcLooBCF+Ll0FUR1A+FYwcgOriZiJ1TMynQZ1Ca/e3Dgr0Osv1e0CGHQjV5gHgwScA2DmFnJUs/wliCnrfvJ3459FUi17zglnIgA== X-YMail-OSG: gaV0jtQVM1mwNQ24SP6xB.tET9GDitMB.5A8f98RYsKVrLg7KkeFbB.qkJPYl2c _xXbhoFWDVvFROwIARXRu_g6UyUrnrGdw_Oak_YN9jsLHNuOC2QJnIpe1dsx3YqX01zCAExfu1Gn 6frgzbJEifwwaOq6itbmPLUtIRgXjFgc07vGO0PYzhbMXdaBkkx3Acz4A.Iru.3E3NgR3ZE7tneK HHo8P2czQw9D0ZpioMczPLcdWTVdJtbJu_p_fs3AO0HaznLBEljdVaQ80KAN9YH3DW_zZuejkyzZ jROYQkqg81_9m7Hh8kMzP8xkfqo8AKsUWhDoffHTlptJvjdXafl8J5B7581NTZobMl6qK3ADIhW7 lnEVZRNE6E85uKqEHiLltRa8oNkNDhH7.x2oVX0dQb9LCq6aBhmqoeqdHlX9TzCKdpIeGQ77nn3G .74BAc9SAvDhI__OFTESVhPeQdjX3kLNdDxNpCULKWBgo_B4IQp5raS.A8F8_gbWVc0WErN7y6aM uwGq14IvwLF8bdNfMtocUSMZTIF4tBfHZXZRhgVBv9iQ052u1zHLXxxVOp4U3Q2SL4D8Q5OdehhK dP8U6LG05xkhNvyB9hsBYYgIOqVBDVTpbYU2naZG9udUyGS2ZiBlfUt8r355ZbPi17pFVaW6lIhy SF_BSAIzYg5urLjST2EuPImB9RDjLr3m1mskqADrm4XYW46BFBgzZSzr..yLFjTn1zfh__vsUz6z Q5ZMjCYquYH9j.5S9a_dZtr8LV9n2wyZt.5xueMwUXqEI9l5gdWYqUxDuZelfMcUm9Le7P3.Fk5e Wwb5i1h4cZQDdJAkcmGlHK0Gz73P84CId_7PbsHfIwUIroDZWwBBzrk.clLJHHgVxx7kw4lQyW_3 ta2ZgcZB3OBSHWWsP5DdtCGrBatROWkBKYprsO8S0rauSKIFXjYL2cXjdxhqjgGGEA5Mzpngqysi 4nCRfR9ZCwZhj0EBcbFCo.Yte0KQpEO0AHMHF8rhGJ.mHu2BYgcAG.qshHNBemwdrdjRgqeGzwc1 Gq7oZrw9KfBDMD5Xa7YqxNVcs9FkloT9FKUJOJ8gB.FVRFoDP1w0af2FhR6xErY5OKQgXPbxCyJG i_HYyXGxLhcMQzT2oMjhQgrdW8BgvobN.umlyKyIy70n6g9GM93UBCcu5PEsmJO6sMgTMsEDH_Ab IK6SvKzryzE4E6oHyCGY60L0od2jc30uI0gXHR8xcsvdS24HJM2UtxnhnWRUJxvVfCaLztjyP4rG nCq1KG1wID._5C1Ss5w5PBNE20bz5Z9bQb4c8GZVWe80rsY08nROKnz0m3MJw00497zEE4mz13gB vj_T2neCJu1pguJPMKnXFZwSEP6lkmtYk8tFb6Mdm4pSB8km9V7YL9mWhYt0cIxPz7fpquEwvYtX 4j6gOZU90AfUfVZFD6dPKmDEFwTiXHJf5PTtrsK8MfHFHz2ZOOt3f_pmC3ZJkCPUWnLyt86wWrL. b7Wfte21tEuWL8aYNisTfwPdpQ4.h20foSbBQSjVoieFMStm8fAmgU_qrdcJ4Rj2sWUgQ2CDds.H TNo7zgWcC_ZnO3hW9ZZroc7UN9BclyGniXv41M76LkUQRktpdp5SBChINZQBkRTzdKfEziqvxR_z iLbAETN30OnD1g39x7GkFra1wE6ZDQPgzOw2KTxyfl8Hv6V7hs3C1.PUBIftJx3CulXHdzr7DXuT RMVPEBj_PM24NV.heiq52QyDKyCV1d.vier0Hqphn3Aaq6g93m5.Wts3E_mpFgDYbBwMjVY0sJdr 6MtAKfUIN1aG0GXFCTNF6wrEcoDYOwfkUtvx6fnRaZBw8u1qA9fj3Ft4zbXD42y.hg8s6SUblnai fzPhOH.iXBJrHC456CfPrJj_izBL9HacJcCY03WLJlJkqVFmdB_xIcNLidjyaAJb36EWu7zA8txp YAVIR.fRxEPqgIIpvs6naWo9IIVE7JSOrwolLGUpSmTH.5Lcobkc5Qp8VpWvpAdvasdkyg7QAPNt pH922nDf4UwcDnRZ27K9zX23CYCjC_IKhYKn7wTjae6q9PRYW3WUE_2vKBSw8u9EhVwyiZfujlHT uvTclsBvbFWrcYYOpGTmD9HX5woMmHr5i_WrjT74dwDAxgzlcRQlsGx70znZyFQJbRj.JEHk3YML FTRPaXBFWy5sjORASltlrAihbDmYSfKL4STZLrgLsdVZZ2PwkCAhQgm9dTkwBP2CtmrHtsag5MzC E61Jpgwi0I3a7dhWqSkCTRDtlwjRNZlV3Pbs9vd4AXRYBUpYafCVRfHmVaoVh8PbELjumyD8RIkX xsqTmdLnWXHuKczSIrs.tbv4W6tJU4Y_LDFElWlIFy1SVpqDmnULuLTYHB3G4F_fWMwF4aw5FrGY Dqik8nOZfCmKXeCQ1hHPYXDfuVN4GlY8V X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic308.consmr.mail.ne1.yahoo.com with HTTP; Fri, 24 Sep 2021 18:02:36 +0000 Received: by kubenode558.mail-prod1.omega.gq1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID dbe4b2bbb40ee4c99862de801b32817b; Fri, 24 Sep 2021 18:02:32 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, netfilter-devel@vger.kernel.org Subject: [PATCH v29 07/28] LSM: Use lsmblob in security_secctx_to_secid Date: Fri, 24 Sep 2021 10:54:20 -0700 Message-Id: <20210924175441.7943-8-casey@schaufler-ca.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210924175441.7943-1-casey@schaufler-ca.com> References: <20210924175441.7943-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. Acked-by: Paul Moore Reviewed-by: Kees Cook Signed-off-by: Casey Schaufler Cc: netdev@vger.kernel.org Cc: netfilter-devel@vger.kernel.org To: Pablo Neira Ayuso --- include/linux/security.h | 26 ++++++++++++++++++-- kernel/cred.c | 4 +--- net/netfilter/nft_meta.c | 10 ++++---- net/netfilter/xt_SECMARK.c | 7 +++++- net/netlabel/netlabel_unlabeled.c | 23 +++++++++++------- security/security.c | 40 ++++++++++++++++++++++++++----- 6 files changed, 85 insertions(+), 25 deletions(-) diff --git a/include/linux/security.h b/include/linux/security.h index 399b83ad1a43..e2ca097b58db 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -197,6 +197,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); @@ -528,7 +549,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); @@ -1383,7 +1405,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 d82fd1236537..2f9ade2ffb20 100644 --- a/kernel/cred.c +++ b/kernel/cred.c @@ -798,14 +798,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 566ba4397ee4..762561318d78 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -880,7 +880,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 @@ -904,13 +904,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); } /** @@ -931,7 +936,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 @@ -953,13 +958,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 a049b82d58e1..520fa287c90c 100644 --- a/security/security.c +++ b/security/security.c @@ -2194,10 +2194,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); @@ -2348,10 +2360,26 @@ int security_socket_getpeersec_stream(struct socket *sock, char __user *optval, optval, optlen, len); } -int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid) +int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, + u32 *secid) { - return call_int_hook(socket_getpeersec_dgram, -ENOPROTOOPT, sock, - skb, secid); + struct security_hook_list *hp; + int rc = -ENOPROTOOPT; + + /* + * Only one security module should provide a real hook for + * this. A stub or bypass like is used in BPF should either + * (somehow) leave rc unaltered or return -ENOPROTOOPT. + */ + hlist_for_each_entry(hp, &security_hook_heads.socket_getpeersec_dgram, + list) { + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + rc = hp->hook.socket_getpeersec_dgram(sock, skb, secid); + if (rc != -ENOPROTOOPT) + break; + } + return rc; } EXPORT_SYMBOL(security_socket_getpeersec_dgram); From patchwork Fri Sep 24 17:54:21 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12516417 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 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D2172C43217 for ; Fri, 24 Sep 2021 18:03:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B235C61107 for ; Fri, 24 Sep 2021 18:03:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347804AbhIXSFS (ORCPT ); Fri, 24 Sep 2021 14:05:18 -0400 Received: from sonic317-38.consmr.mail.ne1.yahoo.com ([66.163.184.49]:36998 "EHLO sonic317-38.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347796AbhIXSFR (ORCPT ); Fri, 24 Sep 2021 14:05:17 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1632506623; bh=FLureY33Ru8CkMBIhaVMjd/jlAfUxcbfvb2ii7d0J3E=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=DTSgg82pZJ+x0TlSbCZQvsRVN5jIdQnbHyMKRYLh/5+04XAAhI+au5oWkeOqQtlz9mkPMqRLWuHEffW/wurVHbAtYkWKVEL3My7tdR2XnL4sAM897xilFH6KNSGk8YXHiYN6lnrmyWq5fn0y+RP1MQzqZd2fhNHOMoKiUNL+bWIUPuysiHGbdOdtf05YmQG+wVABmxZSaqd5DwllH0u742zd6a+OYtM+vfsIbmgFrmuqqt8CyiSXlA/eqgmK3VrlKC4B3XMtmasBE94dlb6W94CK6L/h9lV8UV6wY1IrA3opQ5n8puDK1GH+E4w3MBQQbhCsjZ/SbGqL/a1+2UaoyQ== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1632506623; bh=nraNd34jcqMZSRrT3Mn+7zd2PjpBbcwbZkDv/La9D73=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=IskwGNeQ8P7HyddwRZsNvPQdBhqVFIcGSqwOTcsvW4j/xHLBCNBLFPL/HGzSMf0hMMOQhhAlGq8HM+2ncX400IQZgXedytBxKVm7f1mxTFvFOPfbrWPoVxnMU13MdeJs5+cWED7QWc+hxCi3GjTtjaZOPgmtTY7ylYE2OAUVR3CwCXIJQHkataHNmZ9tmRbc2r5QF5kvu50A+FOUGegArZ5wtk8rDqt0c7s1Y3AqR6Es9MBkSrxEb/U4iiLyBHQ4OIX/yFsdyS3jh6HfGmsgJ0P4RJDC06pomH7FytbwycRqv1SJF7vz5//QsyAE7J2szj2+LUqYG+PmYxyo/MVfDQ== X-YMail-OSG: 7px3tTAVM1lTrEdKzAF3aBHK5D8bpdCaSmCivJj1kz4_rUL0bx8TAPUvL5wOY5J i0sBridApx0c5ZBo3vG9XaPo2c9ZxglB.QlTnuK_y7jrzBVZb5.2TaULh8L6NSCxnoGDs5pQ89IF NL7uj8NbWwW6HCINPrSU6t7tE.stcBCSqLo7ZPwsvwCkiJID.9zUGQEoOCuXAsjSzQNnIl_tXsZK GA20kOEzDAp7ZTdiHrBTAB_YIs3FHzj756JnuYqhLy0m9tUUxHA_lDkwRRBD6LNaKcq8SKSeio0b Jj09ccWf2dCsZV5CWuWp5PjRmVsgp1QmBCu.kdJC3qaeXzaJZ8T3neLMaRWpk7lQB_m1RMXi09vL CWJvXjGaDa3FVz3IyC0YPYA81dNxjSJ70mOrSdGoEDWLE3TvDVPQAjTjJLuAyW96pUYIdyU.VPX8 qEX.NDGVMeVKlo8i6fObnzNU8PT8i1h2qngD8gbABQBKrWBpVicr17Wg10ry408dHSZix5ZdN3hD K8rRwyk46NfbiveiTuw0C6jrgnM4GnHJkn33hFU3RgNMsiMKZ4A27aI5oNrBmmQ_P3xrQ_oR991K 9WL56.kWwoj2pOX9R8XVYqydjoLCIgPGx8w6Vs5Bbpqa1sDBgv4AwibiMNPrvGWbV9sOfeh5OITg Ww3bBmQXr2gN4skwomTqb_HpYqq2x4bwZIWwiCaab0QHX9qJVnoB9bN3ZnK8ueQirsXdFqPMTdcS PJcKszCwNMDNaFKjBNBucHL0oQqB7UOpTwmo6uUuqMLqol9U5FyFmBHt6wk2poTKhZlDDQyLr41p CtKqpV0gS_OWQMy_NIY5V6H5fr0dT_XmdNscFWILXuqOn6xZstkR9OdSsb9P7.eAeh8JT9UFgbkl oEMdJqb2EUSDkJ1i8aOJy6QFTV0WICL_Su4nQUfhCld4BsMY8zSZ6hNoQDVn2BRh1ucYoNS1HxbT qkBz1iSak7wZ2MhBf42OVuJMqtpinqxdUpP.ajlNDpgY1IsSMrNAXuaGLBEJkT6SkIrFFwcVJf9i doCpitb0ioh0NndLR4G_OwCIDe2N.hnJovIXcjc3B4We_5kQOvlD5JvBpelF8YaGZSLAB_IwFsQ1 1yLM4Uw.48jdA5ijmO6OMCeguiWq1ytEWQx2H.KhQrY5V_nOsWSjqOMm5TykRWmyBBkfy84XQYv0 JPhQ6A3PyTEFwFhA3Mf9xb1WKs5fAGH2G5sHMNArB1xLxG0i_113YtXmukBb03YwCJK6_vQr3HJB CyWMiWCZMYiqFbj5991d76YAR1Mex.bbulmQssRWI_9U5jD9qeEPJhQYt5CAGIqQkbSzMMkZVJ_h KSwuVRKN_yFWxC1PRs1PNzxI1HOUV.T59vISDFB7yPQ8zaqK.b5hSpxrLZz_vzmCUCkLz_CGpg7R wfddVs8dD2cOEuEmS0mYp46Bm859fd7LQMltA16f1AEZmj4e3xWVStxv1zDbIsbAEB.f3mpwTcc9 BhDu8157XCOzMChy0LMVgioJwesVJ1wqU41RT9sfktaDpJ3.U5oomHWlZqpnsicn0jdWtY5klFm1 O_bYUeeHgIDJiFU9i.H.8rDhPpAzyq3KP0gLfOUYebI3HfTfgxOQkik0S9_IPysHRgTFQnv36kS1 w_IYmn3UAX2zDgL1M2.f.DXecT1NCKdvTW4cyxkSCQlV.1fxD2YLPiFkvDojiFsxNTNMGAUyeKII eVssrtOagAU3wzz8_NpQuXlKs1lH5jvHzjV6_PzZOf.uCYOm2NjGyh9Q8gc_haeNCZjZYRMNEw.f DeW_rLWBH8FGAw1WwHiULzMPVG7H8b_zoGQ8rP1r1D8VaF.JiH_0rF6T1rqsq72b0YAxNtR.4w6t kjhgCTolqtE_YGVck2TZ.32lkPZIvX4SsZxHFFtyJ6m._GL5Tw5qMaydf9OAoQAjh410XUX2bO0d M3jY6tAa7S55cnz_kCgvuox5drb5q4TblGj2ENGA.om6H6FbSaO7f6m13agj_f1Py7cE2bORT0sG c8twEOzKWoYJNx5XVmkA98KPgEglOP_nmlVd3vMCAEQ5H1MK0wt5WpBify7bUdSqBaMf0GSfrKPH UL4BBTBscnFAiHQdcFJ_c0yIbSArLnfhtXr2wwhVHsR7Mp.2nTyi0q.1e4fM2jeWXj2T0kIaZlbS GIzfGe3_GgDc9vFbfmN4o15jg0tYKT.vlJLCbx2Ze95e5m3XgxUn189flzHAfzGEln7E8BeBY.zr iI.dkSoRWwxW9M.5rChskGF3zLnCf7ONfnqdx1vga.IBZE5f.1wYF3B1OiK448G3AqdacLDeZMUc nKOGHF7o3S1a836Yc2l8Evp67YfnNMU9g2J_Yh1LeWDY_sqhdx1uJtQ-- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic317.consmr.mail.ne1.yahoo.com with HTTP; Fri, 24 Sep 2021 18:03:43 +0000 Received: by kubenode532.mail-prod1.omega.gq1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 6b6c86a25dd254bc610006144a96024f; Fri, 24 Sep 2021 18:03:38 +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 v29 08/28] LSM: Use lsmblob in security_secid_to_secctx Date: Fri, 24 Sep 2021 10:54:21 -0700 Message-Id: <20210924175441.7943-9-casey@schaufler-ca.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210924175441.7943-1-casey@schaufler-ca.com> References: <20210924175441.7943-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. Acked-by: Paul Moore Reviewed-by: Kees Cook 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 --- drivers/android/binder.c | 12 +++++++++- include/linux/security.h | 5 +++-- include/net/scm.h | 7 +++++- kernel/audit.c | 20 +++++++++++++++-- kernel/auditsc.c | 27 ++++++++++++++++++---- 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, 122 insertions(+), 29 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index d9030cb6b1e4..42bcf22d1e50 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 e2ca097b58db..60f0a56f43ed 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -548,7 +548,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); @@ -1398,7 +1398,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 447614b7a50b..df8a57c5355d 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -677,6 +677,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, @@ -693,6 +700,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, @@ -999,6 +1013,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) @@ -1008,7 +1023,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 { @@ -1252,8 +1268,10 @@ static void show_special(struct audit_context *context, int *call_panic) if (osid) { char *ctx = NULL; u32 len; + struct lsmblob blob; - if (security_secid_to_secctx(osid, &ctx, &len)) { + lsmblob_init(&blob, osid); + if (security_secid_to_secctx(&blob, &ctx, &len)) { audit_log_format(ab, " osid=%u", osid); *call_panic = 1; } else { @@ -1408,9 +1426,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 b297bb28556e..cb10b5f03cf4 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 f1e5443fe7c7..daf554915e07 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -341,8 +341,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; @@ -650,8 +655,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 80f675d884b2..79c280d1efce 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -178,8 +178,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 4c3fbaaeb103..bb97e8af8345 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 762561318d78..51cb4fce5edf 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, @@ -493,8 +499,13 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, (dev != NULL ? dev->name : NULL), addr->s_addr, mask->s_addr); 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); @@ -536,6 +547,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); @@ -553,8 +565,13 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, (dev != NULL ? dev->name : NULL), addr, mask); 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); @@ -1080,6 +1097,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, @@ -1134,7 +1152,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 520fa287c90c..8163dc615ba6 100644 --- a/security/security.c +++ b/security/security.c @@ -2175,17 +2175,16 @@ int security_ismaclabel(const char *name) } EXPORT_SYMBOL(security_ismaclabel); -int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) +int security_secid_to_secctx(struct lsmblob *blob, char **secdata, u32 *seclen) { struct security_hook_list *hp; int rc; - /* - * Currently, only one LSM can implement secid_to_secctx (i.e this - * LSM hook is not "stackable"). - */ hlist_for_each_entry(hp, &security_hook_heads.secid_to_secctx, list) { - rc = hp->hook.secid_to_secctx(secid, secdata, seclen); + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + rc = hp->hook.secid_to_secctx(blob->secid[hp->lsmid->slot], + secdata, seclen); if (rc != LSM_RET_DEFAULT(secid_to_secctx)) return rc; } From patchwork Fri Sep 24 17:54:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12516453 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 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C1EF1C433F5 for ; Fri, 24 Sep 2021 18:06:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A3AC461107 for ; Fri, 24 Sep 2021 18:06:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347912AbhIXSHm (ORCPT ); Fri, 24 Sep 2021 14:07:42 -0400 Received: from sonic309-27.consmr.mail.ne1.yahoo.com ([66.163.184.153]:37385 "EHLO sonic309-27.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344425AbhIXSHc (ORCPT ); Fri, 24 Sep 2021 14:07:32 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1632506759; bh=lF1ziX5gHsSe9ECLJ8VrrXequmqld4YMJ0fxEuwG6B8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=P8rv/FJjbB4XL7jBlvrQPbu6yal6zIOPdlSi5TVlu560z/Hcq7UGacSzqsDkRaufl6oTfkKdvRLu9KZw6mVDpdYgAFWCjmarjGob7r4uc1Sr+8smLxT0FZ/jx4BWNcdmO2K8vwe71QdirF8HByQeHr2rpF58vOqooQ3yITy5Czfgp0ngsDkQJ+MCHzJiVsEEm65lcyI2vrmqjJ2uLQRdhSHF1vy5un2UENGFcIfQgLcOqAJMnv3hAqots91XNH1oQpP2eJK71AXD9g9cZ/NMD2CM5uIGUYU5gqA3/hPWSYLf2YxDie4DPlht4fGeLaLjWQb65AkSwAvqie2y2Z409g== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1632506759; bh=IidI1bz81wUanKA4KLf6bUe2F4WNKk7TxHk7pH04u7n=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=jSOMdyun9jL6e0jzJ3EYP/AqSoh1az++e/EyVBumxoZDs0q9eiXSmB4usQPzUicJjczAzIxRqUdMnZrUT6GdR+Sy2fHR289MA31K7pSEwzeFbFvvLLdOi/8Dj3AsksTXB8nXFblkiiK9dodh877a43hriqPgcfaXj64+m6XDhUeuLO4N3+yssGw/Wywk6bGUYzgXFblf+PtVwNptggjukxCQ4AE3sJJHs6Ok2zk9TmbcGrMpg5YC8rClqleJvRGNwxev+MmdW2Aqq66y/dJx+oFyo9ELIEwJMxAPV3ARp2PGUzhdUrJ7mvYEnXu9AlUNcbJYIoQJ9et0/GC5kJO4LQ== X-YMail-OSG: xJ1D3QMVM1mHqVa0G1WVYdCRFBmw4xNAAM5l5cRwJsmgvCc3kd7gsP6nVJyiLXi hBX51jqXUXLd7c9zZoiDfk21jR3oD8DuBMRYdrArtik65A5ubIQmZfCO9B6Ala641uorB5O0wvx6 7shq_0I.KhiQUuc.7.E9UQFGEL4yOp7hNq_oa2oYGFfc2t.fwHnDg_VaT9d1Ax6gaipVCz5yDdXr 7qHaMi3f1ivOJ0lfYjg.zeIS2m6Sr2g7mixTQAZoKaCVe.TDnC_VJTtHw6SVH4Qg2SjSbRXcYiLp jrkLwY3lI_tOThW3iVbvahtNFN5L7kTLDMgHc3Dkk.ZcGFxc0f_SJPAu.Uxo_0fk0ZLDVCfSFh8h zyublWco_NgDCKfIRe7ao30TPiOAkxx73INEklE9bWdSu4lqgR3TjomBLqPx46sgAoUb6SYJPDgc Ywi4sMvvulePPwgMD7RQuMA_KtMvF95cB3gI_2RKMe9LPpUZkP4bVppP45CAvCKRq39ly3ivOjbs Cam6GfcbtX57x58KlRg8asvOxPaPQqpTG49.MHAbst4oMG7F3eljVvNzPFXUYsdlbUBSMPXeB9ry 6T2ORlNStBSeB_XMkg9gX1ZKARsh4CTngqsXsWsYPy5FTtHKgiXfkPPksSD9IwcHgObFH2629nvY xfnqAoZ07MKEiMrUHREGZJO9jjHaZPQZ0VfLDsL8wHI7IVRJ2N90lKXzLudRbdhRY60d7tGMtKs2 jP_kzOMfPiRwk0B7Hpu5UazS9CHQMAl6VxmS_hkrVZ37rELXR7htwlmLjcQc.3WgekiNo3T1qrQD Rmf50CsoLw34gH1c3Nso43UIxvKYyYm05qrlzrZYNu_h7tx5XAjMGfC2ovwxst14hMhOw7pWkxn7 gRIp9aV7YlzC2e8uTbnTYeyrFOtTx02mvLKRG_meJ9G8NBplO1PWiZLqUx5SuXDTfRcy5VuwBDP8 bcfAi3wTuqfRHMYmaWPAjGB3t4jjwVV1KuPsEALbXOtef0w2D2GbeDl8ws4eYEQcaZv.ZMos9umu bNqf5lTrtDTsSydNK_r25RICi4MVJT1rQ02ITmSyGQnfkTCpGDfbVItnXrHK2AWKSe3aKpfvI2FT 9s_RzLba.5xuBXrDZFrB0GJhZC_rU3Szv36R8mncnpbtXFA4Dq33Tlv5yecFu4jol6U7XtH9I9p_ isgUlsvD6uQ7wWpMb_l9wUNeANTkX12n4WCfVsStUw.lqd1a.B5OiJWPxkgkmX1CoPdOoFqCxizk hY9h9y9dFwYp1XJOQHiL9Dy2xKOVp1Ykbcaz28c7yBK09G597mZhYgO.ws9Ft8yUq4YlmPuNsmwE MScMLVIr49KIC7_Am7zfG3e4vSP.MowMn0uydAffegzoEgWqztiDmfZNDoUIkNcGldgfXECajOoS qadBbYu4Taa_PUZYS29kKZX11Ddsg1k9xMv1_grTNZK2wB0zmBVGG95w3ov62Ij6hRxgkwgsePHs r03emvWQdWf5gZLX9RfwgD2ncfU8KSMV3DD3Cwd6gZiIbPT6TyZkAQb1FsMqTWL6kUppuwF_mbzk yZmSSJZ_cm.d6oS5Fz3f3IwQ9a2CK_hW0Ubt127.DeyJrFRoh70ptd_FbCZAVoms0tVxln2.rzap Ag0tFM.GUX1qsRSSVJY0CzFavFZfotGVgkGu.D_aly3lqaE9eVUazFT6Fx1d23auLiW0u3CAyA40 ia4kK1IuuP7qdYYYOudhFkhj4wQbA8ofAiP1ADhqCURX8UABJ0HmB2J_BH9V2pUEw0Sv4QJd1XST RD7akvGq0tLx5qo5NW7KDapp7xE2sME9hM8PEkIqxh4aemHXuJAdoBNnji3S2o0Wuy5s3ihKWRwn rNMpvDCQfBc1tnse74nFlV58I7WS6LWlxXpxKzPnSDQfgHpdPQLcRA0z9yuJaaW_euykam1PHy8h wmFQN_OtJimhkePQsh6aCr2OYfE.gGXlnFJftmXe0dru6o_I7QGWPbHhs_ubRwVmUAir7o34XZo5 50O0B56_08cUEBzNApflVEL3wFZCKU29DZcx1AQuqkl3CTJmLdo61NCfI_2C2SuGMk9BjHcqJ3b0 ytiFrpsz6DMYI.lZsaej3ZGv5eWw__CKLr9RCy7G7VY8DIq2.p2FaZuDbMbDlW968PBAtn8VB0Ma R_V_9r9Y26T0GHfD6B0qwaBiYA1NIKNWd7ZvjNGKh663axaYkygPZlets0t88OgHU92EcaxP0Yr0 F2jBQf77KoKN6Znvym3oh6lpJ5Cfgg6wwZj9PwWB9k9UwNG0KzbLq9_9R4G9vCk3veArQYw4zit1 8.mj4S9ggV4iyBCoDAW8hbJ9dn7KPNfDj.cNkHSZs.OJdfkJYiVksAx0wrLwRwc7ND_m20ZrKgKs 6Bxh04gdytFtjiUUFIj6LSyE.CEz8cXceZw-- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic309.consmr.mail.ne1.yahoo.com with HTTP; Fri, 24 Sep 2021 18:05:59 +0000 Received: by kubenode586.mail-prod1.omega.bf1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 8b07f85760cbc40cb575fb1fa28abcbd; Fri, 24 Sep 2021 18:05:55 +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, Stephen Smalley , linux-integrity@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH v29 10/28] LSM: Use lsmblob in security_task_getsecid Date: Fri, 24 Sep 2021 10:54:23 -0700 Message-Id: <20210924175441.7943-11-casey@schaufler-ca.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210924175441.7943-1-casey@schaufler-ca.com> References: <20210924175441.7943-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 | 12 +++--- security/integrity/ima/ima_main.c | 55 +++++++++++++++------------ security/security.c | 25 +++++++++--- 10 files changed, 94 insertions(+), 80 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 42bcf22d1e50..d17a34445dcd 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 e674a6cdab46..de70742c30d6 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -501,8 +501,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); @@ -1198,14 +1198,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 b4d214b21b97..50e3f2f4cb49 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -477,7 +477,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; @@ -674,17 +673,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); @@ -2439,12 +2430,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); } @@ -2460,6 +2454,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; @@ -2471,7 +2466,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; } @@ -2492,7 +2489,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 51cb4fce5edf..15b53fc4e83f 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -1562,11 +1562,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 6190cbf94bf0..aa31f7bf79ee 100644 --- a/net/netlabel/netlabel_user.h +++ b/net/netlabel/netlabel_user.h @@ -32,7 +32,11 @@ */ static inline void netlbl_netlink_auditinfo(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 dbba51583e7c..2fedda131a39 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c @@ -71,15 +71,17 @@ 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, 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, + 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 465865412100..c327f93d3962 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -405,12 +405,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; @@ -436,9 +437,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? */ @@ -446,11 +447,11 @@ 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); action = ima_get_action(file_mnt_user_ns(vma->vm_file), inode, - current_cred(), secid, MAY_EXEC, MMAP_CHECK, - &pcr, &template, NULL, NULL); + current_cred(), blob.secid[0], MAY_EXEC, + MMAP_CHECK, &pcr, &template, NULL, NULL); /* Is the mmap'ed file in policy? */ if (!(action & (IMA_MEASURE | IMA_APPRAISE_SUBMASK))) @@ -486,10 +487,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; @@ -510,10 +513,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); } @@ -689,7 +693,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 @@ -709,8 +713,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); } @@ -739,7 +744,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) @@ -752,9 +757,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); } /** @@ -882,7 +888,7 @@ int 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 (digest && digest_len < digest_hash_len) return -EINVAL; @@ -905,9 +911,10 @@ int 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, NULL); if (!(action & IMA_MEASURE) && !digest) return -ENOENT; diff --git a/security/security.c b/security/security.c index f6760b25fed0..74a7fb981904 100644 --- a/security/security.c +++ b/security/security.c @@ -1905,17 +1905,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 Fri Sep 24 17:54:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12516495 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 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D36E8C43219 for ; Fri, 24 Sep 2021 18:11:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B7F6161107 for ; Fri, 24 Sep 2021 18:11:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347964AbhIXSNL (ORCPT ); Fri, 24 Sep 2021 14:13:11 -0400 Received: from sonic308-15.consmr.mail.ne1.yahoo.com ([66.163.187.38]:33377 "EHLO sonic308-15.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344515AbhIXSNK (ORCPT ); Fri, 24 Sep 2021 14:13:10 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1632507097; bh=sSZAkFLtim3IMEiW/QSLmTBaEhGPPpcC/viHHuJ5ZX4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=mqaxQ1QGdcLdVyimRxLSx5f703LyYEBGp24+DJFR5iD6RA9eZbx7A3tNIzM7vGnaIWdAAo16o3WS5fqlPVXsZTmTFlE+8YY0mrKoE/shWNURqAHDh4mNItkwoZ5wH3maoYFgGdQ6cuHq2JSc1TQIjDPDuOqiC1DR52mVXMqHc5mZPFxcQ0BeRAOWMFRYWXUXgalE2X1Wd31PdWDqC/f55j5avbIaHXKJ+ST8b6wRlW3u6ihqJeSChQo3jioNOlcDfaQmW+4Mh2IC7GwrHIrjGZzhsYYb++Ffb5MSFdHPHerJ1qq6yonLTnQkjWZ7+GPKBIJ9UMFMLMdgMQidei4EfQ== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1632507097; bh=wuWBSNL+e0vBn8+uacoJ7yI7WoMWpcYGjb29nca2NjF=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=aZac2nIK1zC0hnQJtntkbtFAha/HpCgWcMzeO9M+++vIsE5XdTjqgak6KGBpk2KqdqcV9ieWOCUmXHOXoytVZcFl37NFW6CV8aC5VgpZNOGfXnwR8VdtiAXNKWNoDQR0u5qP9R2a6OuyrGy4HNp+noXpZH6dxmCogVuma2TmuCOx6umSHQCa5xhyU2YNlsajDxPwA3+hVMCbG9WibQysoQTz+YIqgNwO7/8xIlXYK1ifuUAr9jMTzcCfcOgy4yIoaoMkFN3TjgrK2j9bJ6d/zxxnlzRXMBhlnAOmNETo6cmtQ3YuVIGM8RFgwxUZip6WF7203a5vUYxocdUMCAcWNQ== X-YMail-OSG: jXv5SmoVM1m.ci_.2VWZKKdDRdxaGLmAIX2TFEbxUg12LvWet4kjB25XAU9K54t ctyygJ0PhgH.UkJRMo7A.6m.WWeRZ4uToo7FqDfN_vjOLZ1y8iBl50POl77oK.QM.kJhpgsROfc_ xecLHgDPRKiM0ZgfLcC07Z.16_ahI5isx8WGWbPENldklCLd1UqDJcVmJELj0IKPh86PG2CDZcl2 Y_JnnD6870_XJfTtqTTFNW2qN5oa5cRgCHLowMP1izreVDT4sa5C3ShGbR0V0_PzNK0kNP3CoKA0 n8t8xZzMW4KB84bL1GxJegkskqqnSjJxFQWnhE1XIxZRJ0SqBLa2ijF22diT1aNLkYQseRg0XFlW MWiMyG4TyccopHeC3TAjYEM.OH3acTzgGVa7jEHRu6HyBbHzzJYjInlyHhAU4mBGnvdEFup1it1m LApqcWVQia1s37bj1ZWYJYPXHn._CW_..hXu6fmYGhot8M1I6ARNfYQ01HxulV1dw3nziEmhAjzr Vj.p6QZQVMnvxlIq.gQXisvMJ.e6zSDNqrkUuDtHW7laApXbZlgoJxR8fukndV2Bd.VbjHynXUed 5xaZBku3bcHnEwsfWKvPZBjA4RJu_UUBq6ueAAaKXVpi3sAPdbyNiRRleVU8oKm9mca0XhJxCCYV FZZ3EDhCSvVEU6.DDJ0x4MC0UrWeNRhM1ju7xXwANaXG_nzygSiIMjGKk7upzkec9FOZa28hBPn2 G.mFqfYFYhqxPlvj4J96fXkvDBcfhbixUeqvrEcec4BM2UuLByvDpxaeIZfqD88GKHooGnTks1Q2 LLBtgyHL_dOxj27w7ccT5mk_TCtV450hDPvMRd7CgB5m2tda9eMcEf0Krj5smvJK4lfdtLUOcZfh qKWhTfEa41QvQPLtEqwkSTgZvaYzPqEm_GwXMM_mI2sUJEpXQpo36frbCckIh_pHMFq02yjn8f45 LsQJNFuUHqbr_Wti6al7wZxsweA4c64pALr2tKB33.6Jq7uZyb7rmIL2D_SPsH5mrgV9eJ3Zj5fV fqXNDzWTPZZj9DIt6EHSDHrzKaRVZ0AqZWLhXL8hsgSzy2kz6sdKGMfmtLkaaJ66jjKeWr7LVekP fhEbi0Vtto2TTz3nemVHWzUr4mP0fHcUaCezS9J.3V43Z7JOK9HmoEHd4.Sy7nLoxgUGHMsYOWSC wm.xg17QhE17CgmOXsmuYu9Cc3WxuajlMjNHvJ9PHGryuU9NynLwryU7qxbTF7.13fDcrlUqCUV. NveX_xVVTHABspIhceoPX6N.KfX0hO.s6fEDsWknLakQ3GN8C2c7CnhUxqHNsYJPasKPNmIzHmYr wwOSD16f.VHAqEGgAi52.fVneDh3Wh4dy6N8TJGjbP2OnwAdYeHbGyYLWoWJ53m9GN1Hv1Tele8S jofvQ8AfSpVF3rs7Vh7JmM0W.6.Ulrd2ywDKSVCM3.DtxhyntlZ4YSA5ngEeiHFq2PBLMVMfqHBZ RZU4qwsjnF3ZMfk9d579lhrNC77tjYbdUbZDR2YSp1KLbkooInVW.M_5JNYchWaS9jws4N_Z30Tg t6wT_exFN9lJk6OpMrcbGlCdiCBNudx3dnDkZt792sR6rUYkEqCtxVPKe65CgShQMoKv0R_98Mse _pLVdtStUnaKoXjWDH_S3N21LRAXZM5vVkZTxRSpxJQIlPoQNvHbM6G4u9okJ8m.v6iQSt.x5Wb7 VSwWHgLwC.67YG6cgU31diN8rpZXtqKpbqVo99KNzVv2p8she0KaAq2SVjCbV9DRi74ykZRRZSGE KBNIdXogXaHs46Z2qyjvsxVJFJjS3FoMeL4YI409JcA_v_ks6wq1NC_xz2kQxvEX47_29jtUyIAy 6A1TEb6FMmiCJDLDbcM6s7UpTpU0Cvg2x5as04jEBhWPs704pLAAIU1_32bDkdrtvPV6O6jae.ct Q.eDQEghjQEYS4K1sPki.0bPbm5HRpKW0VrjHuIz9kMAXM0SmpwvsA7aGPKWWN9c2TZ53VpDblIT 5oxBUWAySkEui1C5WiwZ_wBJpknC3LU80AbiPHWUw86K_kTl3awXQSBd6UAHOlhdXuGXetxnvqFq gPgSfcLbDfpJipc1hdCVd6SJMXrQCyVR2l0qSl0OT1S2vBE5qgbhR57CployeVW5qODfU_2S4rcy mqy4a5.fGQukNZXZ6OVLTHXuNaUgynw1z6M_R1nwEi8fzcoYnMbM_.wX9oNJ9LxaFpKhqK0M5VRy uqJRcscdgRKc8Au7doTp6FqhA.Y8iB5DuOtzmbLYQZKmp7D0bfSs9chGpdfcqTArECzOZRDbI9cI VQTWE8CkiVPnRinVoIXPzUnQ1wdlq2O8uMM3DYpHy9Sh8RdQiZs5OpTy9oCx8eSIELtBrqpMDOz1 rh8QE0HJEbvhPYC9Vep4h0XQDBJ.yRSpwyFk- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic308.consmr.mail.ne1.yahoo.com with HTTP; Fri, 24 Sep 2021 18:11:37 +0000 Received: by kubenode518.mail-prod1.omega.ne1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 3b42191bf6f420db991064dbe869fa7f; Fri, 24 Sep 2021 18:11:32 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov, linux-kernel@vger.kernel.org, Stephen Smalley , Chuck Lever , linux-integrity@vger.kernel.org, netdev@vger.kernel.org, netfilter-devel@vger.kernel.org, linux-nfs@vger.kernel.org Subject: [PATCH v29 15/28] LSM: Ensure the correct LSM context releaser Date: Fri, 24 Sep 2021 10:54:28 -0700 Message-Id: <20210924175441.7943-16-casey@schaufler-ca.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210924175441.7943-1-casey@schaufler-ca.com> References: <20210924175441.7943-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: Paul Moore 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 --- 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 d17a34445dcd..36e41b9e08fd 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 159a1ffa4f4b..c61a8432dac5 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c @@ -1375,12 +1375,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 e1214bb6b7ee..71004670455b 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 58c853eabcc9..580eec268138 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -134,6 +134,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 * @@ -551,7 +582,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); @@ -1415,7 +1446,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 b5807b9b8a4d..1b1ddd62de6c 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -1002,6 +1002,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; @@ -1019,7 +1020,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="); @@ -1232,6 +1234,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; @@ -1266,7 +1269,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) { @@ -1417,6 +1421,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)) { @@ -1425,7 +1430,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 cb10b5f03cf4..bf32ab6f81c7 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 daf554915e07..de223234963d 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -342,6 +342,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 @@ -362,7 +363,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 79c280d1efce..3fcf44342b14 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -179,6 +179,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); @@ -187,7 +188,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 bb97e8af8345..3603bd938b74 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 15b53fc4e83f..7cb6f27c8cb2 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; @@ -508,7 +512,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); @@ -545,6 +551,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; @@ -574,7 +581,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); @@ -1093,6 +1101,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; @@ -1163,7 +1172,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 863d6f77df2e..e9a56d44ab6e 100644 --- a/security/security.c +++ b/security/security.c @@ -2362,16 +2362,17 @@ int security_secctx_to_secid(const char *secdata, u32 seclen, } EXPORT_SYMBOL(security_secctx_to_secid); -void security_release_secctx(char *secdata, u32 seclen) +void security_release_secctx(struct lsmcontext *cp) { struct security_hook_list *hp; - int ilsm = lsm_task_ilsm(current); hlist_for_each_entry(hp, &security_hook_heads.release_secctx, list) - if (ilsm == LSMBLOB_INVALID || ilsm == hp->lsmid->slot) { - hp->hook.release_secctx(secdata, seclen); - return; + if (cp->slot == hp->lsmid->slot) { + hp->hook.release_secctx(cp->context, cp->len); + break; } + + memset(cp, 0, sizeof(*cp)); } EXPORT_SYMBOL(security_release_secctx); From patchwork Fri Sep 24 17:54:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12516497 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 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 56394C433FE for ; Fri, 24 Sep 2021 18:12:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 30EBB61107 for ; Fri, 24 Sep 2021 18:12:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347977AbhIXSOQ (ORCPT ); Fri, 24 Sep 2021 14:14:16 -0400 Received: from sonic308-15.consmr.mail.ne1.yahoo.com ([66.163.187.38]:41388 "EHLO sonic308-15.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344515AbhIXSOP (ORCPT ); Fri, 24 Sep 2021 14:14:15 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1632507162; bh=LOk57S4WyBhQ+vIEGjnsY7mT3pTnGeNhziu1rZh3gro=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=UGxIArw6fi+yL94QwX7qCCDDTfAntmDFgFUXeFYXUXfBDersiva+WGfuiGlUPnuWLW1EvPWCOp3Eq2RBeuOltQHLXGT8aMvLMu9WeW6NRGAfoPzAMFW8srd7OYg/U7ZpksqcM0ydIwgicUr/A1eS+CSdyXsUp2LGqsfVC7paPzyYbkx9obyXfOhW6hAKGFUNz2sjxOG4/6f8JfN/EVuY4MLVdraympp1CncCJ8xp3euvorqyjf8BJsd1XVzP3zPSxzz+WHD1KsuJvjdSLmB1a8mbW8DsiSegDLPQUPYHgm5T/i4JMMUqx5PONnnBMAc5EIhv5JXxD3JISd0eRizaTw== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1632507162; bh=I/WiJIcQm9F0+cA06wLJGlXkaWh0cyRXt8rjWpp+sau=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=W6T6u4FbO1LIoVTQtmvUatOcnx+xOFCalX1U7PBm02gC4rtw44NIIcritckLaIrejx9GtAxME9WNc+NEgaezEcCF8BXs9/BvpjNwZutntFzg20ur2MQQIDfE7mfiDE19bqHkP9OKoHOrIYK7VT5LJ4e/OsQ77PdAyr+MT4pvVtL8FXmsIeIeDTVQxITFesVQN241f6kn2UIVKdlmZgLBzB4HBaF6ztk6PLDEG1An7jkkEfCpv3FONDwIePKlqg7PhJqpvvdVeEtGmy3hkR72F5JEi/7NhjkXBbm9PsoSV9iJbppZLUDTlZttLttcH8sUj84QlZAdxQcMjyZEJSIxYQ== X-YMail-OSG: zUa5SHIVM1lwWV_rALGi0LPyKxvHr_KoZwyh4..LlZQem3wtLQHpGtmpWO8blne sWfV6j0owbQwM7haAw7vrj8QpD93hge2VXHIT4cg2P1Ud9HZNCPHkwUaVmVcmjFE7aeEZ8dNyFoQ Ukcy04dn1BhRnuNHVEnKpxULbp6TnAPgVB.UyzONbgMLRhuY1wC4o8ARKTvj0T6Si4Be3JQaJInB 6Q8xsrS2QW5XuqX97L7UlIbJ6wUOXfM4hCs9uj.mD3pdCBaaTBFFSpqexSIRfIzB7Y0hE_n1fpoC 5W0mRfXnqqsjjAyw6O21tUxQ2NWXq6JIXnFHPmn7pQAk6bFWUYjpYFwPg0pBgGlSwKsG_5A3MFtg tIV8iEWxKxv34_4ZqhqTCzJZjJtLX1iltZzLcS083GrPeb7BQ05wLo4IaF1jSyvTtDZEzjzp2pSs 0oHwZCUs0HEG2Oq5ldAjEggL_5htpfozDsjOxLu309OxpxZFUMJRvOHu3hwvnH4eqxIoWM5hKgmu WZaw0LB4m.S7Tbwi_iUDt0oQahVY022596EU7LaSNG48z6UixzSxdgBrchmBReyr93NnQlXv6oeT 1IuX7Pwzmzhyy11dR5vEzOE5fSyLQWum26nzgQUWRzhnMimxXi9RrUvlxODzlMjAoT6R277GYS1r hq5zFqqGI9KR_5yj2m7ZdIvxfObnErCqbQc1vdjKrI5TT_ZHzKtqH4rpVLnWGstDR4Y4Oyas.iFU cIxsL7vVQFmtKSuBjGHvZnip.LFXgKn9lSaMPL_zUMBjM44WbqFNj7kocdoHatk0Wf0oyBe_BNEE RF0NkuSQ6NogBGlRhURrircn8s75Ty0MhfOV6305X6Op3EgswJHwg0JEgEsQSu5n8RfCz.faj8hJ u1Bm.GFUon95OD6igHIJcBfGcyHvP3xIuC4_AsFExIBVTvcZOkbZS_AZktgonbRpYIV_W8k.6qSL 9MSGqvHca6y2OkI5gtTWyo9Esq5EuqT19Pxgjfrx4A3_MlGQwgxXe0Tx_L1ZMiZUNZolGmHcZWXG Wu3G76mCUQ_IhwtneMxPtVEu6ee.E96buosT9MCgoPqzju3tqI8iHiWX18SAUZItLwIH45CgAA3j QQerD7KvD4AIQWG06nPjhbB3eGH_FJoz_x17E6zKPSTFiHI3L_twV0TcPZiJ5eBi4QAr8PUKi71s uhIyGpA59udwzVLEE7vJQLGAde1nZCbt4sCz3Da0eh8K2u4FbxC4fipjo_7wKPv8cW47g0RisJNN lwGeYAQQAKg6j3hWXRdhZXW0Pt6eoW0L6VfLTHWdJKTp.wFANPc695xTLO6hqRm1NnnK3EI5YoK8 P90mIHMWkzikZlkjFFeobthlhuFInlaPRq3Mz3DwViEylN5PURSQOXC4Q34NMf0WpM6pgaORefwz 4rwqHLOXBAVIjNOl8MZ2sudDMr03DHW6xso9cdWagK62OOAF4O0pIBzv7ao5phzDgiEs8rJFhzX8 0vNmBtsLj4nYHUVhJ2RBEdOejEmeC54aRwLg8H8M4QVUI6d_Gxt7PGMMGjj7ZGqPj4KPEhDxXYIt Y6omgpejg7ClCeC6QV3tkMflVyKgbIpGyrKl0fKsTXDgK4g1UKMKTUquh__hK_fS5ym18QbOazYN pl5pD7qH7Hc8PnW.aF34_Xrc8FLQhjVjdQKj8B8kKY389aPUf0jjSNKM9S7b1TnApAi3Gco4nCLD DGeljXrgw.52qrrrltfAtcNIwhVT8melus7X6Jda.1yB76DrdHflhm8Pu6vwwE2Fh69H3dNOa99j Zm_9AdG.I8vojOlmutHREHf61_3uIH2tr0KVhAv0ekLP1RGgk2AELprK0_igp5FxrMMlapIYnea4 qJt_6sbYJ6CgzOHBArzl1.dU7sGi003q9vtSxntIUw31qDPNdmzRels01VJUeXHkROxNFGPmmQVn gVkT7fq6Oc9fQrRLtjdmALv5m8AUhMa2.PQ3LkLR7BNNvfoV.7fopGgKKlwVqE.83WwAVXpo6GC. bLLXKevQrPXBy6Pi0aKbGzpCvhjXrWUDgILQuZVHbVfWcnA7E0b.WmCV7T6WL.w1hHBf5O.C4IMT gj.RDxUMy_8KMzzlpnTe5zDM9l87Q6z1aHGOCglUjbEKgG1yCYWx.cd8kC5AmVtEXqjKBj04pifw Rbovi7dvOtGjrf_X9OknXL2RWXCbufgqXK7HWuo6YMIR1XszWla540Lrolvso0nZwcoiWmA39Qrk lPYFYqfNEWXFyxUHcs_cIUOguAzLl5PyH217zoSuCYV.RX5bZ.J1jkpEqcNZOQAnhOpCiDnJlUkr qe383jJPchUBFuLOKoP3XCOW__rfZGVo23rYMPwzZgsvebVFAGmzdeDe1R574 X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic308.consmr.mail.ne1.yahoo.com with HTTP; Fri, 24 Sep 2021 18:12:42 +0000 Received: by kubenode586.mail-prod1.omega.bf1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 1244745efe54fab898e04cd89ef13192; Fri, 24 Sep 2021 18:12:38 +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, Stephen Smalley , netdev@vger.kernel.org, netfilter-devel@vger.kernel.org Subject: [PATCH v29 16/28] LSM: Use lsmcontext in security_secid_to_secctx Date: Fri, 24 Sep 2021 10:54:29 -0700 Message-Id: <20210924175441.7943-17-casey@schaufler-ca.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210924175441.7943-1-casey@schaufler-ca.com> References: <20210924175441.7943-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 36e41b9e08fd..1159b4e44b28 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 580eec268138..eed281367895 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -579,7 +579,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); @@ -1434,7 +1434,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 1b1ddd62de6c..d198f307a4d8 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -1002,9 +1002,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); @@ -1015,13 +1013,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="); @@ -1234,7 +1231,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; @@ -1259,17 +1255,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); } } @@ -1418,20 +1412,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 bf32ab6f81c7..588e4d2dcd15 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 de223234963d..0c3e1a8aaf2b 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -339,8 +339,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; @@ -348,7 +347,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; @@ -357,13 +356,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; } @@ -658,15 +656,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 3fcf44342b14..c8825e89a21e 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -176,19 +176,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 3603bd938b74..4490bcb2a8b6 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 7cb6f27c8cb2..596a75814fbf 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); @@ -509,11 +502,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); @@ -552,8 +543,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); @@ -578,10 +567,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); @@ -1104,8 +1092,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, @@ -1165,15 +1151,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 e9a56d44ab6e..f8d306b0dfb8 100644 --- a/security/security.c +++ b/security/security.c @@ -2326,18 +2326,22 @@ int security_ismaclabel(const char *name) } EXPORT_SYMBOL(security_ismaclabel); -int security_secid_to_secctx(struct lsmblob *blob, char **secdata, u32 *seclen) +int security_secid_to_secctx(struct lsmblob *blob, struct lsmcontext *cp) { struct security_hook_list *hp; int ilsm = lsm_task_ilsm(current); + memset(cp, 0, sizeof(*cp)); + hlist_for_each_entry(hp, &security_hook_heads.secid_to_secctx, list) { if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) continue; - if (ilsm == LSMBLOB_INVALID || ilsm == hp->lsmid->slot) + if (ilsm == LSMBLOB_INVALID || ilsm == hp->lsmid->slot) { + cp->slot = hp->lsmid->slot; return hp->hook.secid_to_secctx( blob->secid[hp->lsmid->slot], - secdata, seclen); + &cp->context, &cp->len); + } } return LSM_RET_DEFAULT(secid_to_secctx); From patchwork Fri Sep 24 17:54:31 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12516523 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 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AD40BC4332F for ; Fri, 24 Sep 2021 18:14:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9364961251 for ; Fri, 24 Sep 2021 18:14:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348008AbhIXSQa (ORCPT ); Fri, 24 Sep 2021 14:16:30 -0400 Received: from sonic317-38.consmr.mail.ne1.yahoo.com ([66.163.184.49]:33538 "EHLO sonic317-38.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347987AbhIXSQ3 (ORCPT ); Fri, 24 Sep 2021 14:16:29 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1632507295; bh=sPePNFjY2Hg+Qwx1YxPQDr6XkSh5fD9D76yQuIRPlvY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=WHmzgIlQO5DxwYjLvjxspydmi/6c4syIqcTRZsephHcd+axbdtLZgTzLH0Z3swcoea8mBfk5OuTKyfyA8TM71ImcDmz3OkRfusRpe9Y9bGbKwxqqAhnkL2pwuPeadM6O7YsSzYNE6vpvjdQVBOA5pBFO19xt8A85WkhG3Lf5Xbei9Hs3n9n3uA9tk85BIIGpU1wk3/SU74KofsFitNcJ4wjo8jV4P5ZIwlCUzEkXbYsOO84jZygP9d3dIYox8oqtnSaKg4JbQsVlTVQWYTDQ0D7+Xc8BWJMD/FJanTIevnwHC9ijpmO6lIJkOxkhbQWVy18BUAMLHD+3Ue7mX+74jA== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1632507295; bh=bbVA5A5F3/m6qi9FShtU7Zd6OhjwtVlHBEB3dEGsvzq=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=XXaiaI9hSz9JLMPCG39ZQlUwLhE2tWNEUDoz2nRoycJ8J/n7GwYbNkDRB8QKMMqYDhEVpdjR2AS7KZqdCV8tNZx/Ik5MXMjSrdgFa95c/AMvc2CpksFsS5KXaxyCsCCv7ST1t8Kcj9LwquFb4UHsfwW8/oWN2IcQrlZsHtanBtx0ez4ikM/cZ+32zksMgR/Cnha8Wk2E8sDfCQFC+CUugVlF/c/sbWyEywWy/uTV/B0sPYOcHDtjz5cxPaWt9AzyhWqhonDvAf3rBP8zIVyQ1iO67VUmlZqpYF1Jv9NrssaptiR+Qczn3ikIBWsuVQyMvnOsMuAZN6ueQ7Wmtoetkg== X-YMail-OSG: ST2zd64VM1lCIiulQcsej982B9Y72ukKRweqY1xOP_UduLwwFbAg.Y3j1KEn3oQ Ke8i6aQ_4mckqePYEbstJ.ytW3wBfUtEIhUWxZGik75KQv1H7fiFZeGYxZAj2ifeYB8vjp4QChaf VssHzrXo5PwoE.7QGSFqBv8f6GUK162ABQBtaQZ6UOvRes.qoSBB.DvTtCVYN7xeWwWNKIGnN1Np wy_0_aAoNuWxqjKacU_uej5MPlnltU28..aKLrefXIf.UQ3Y.LQ65cnOFKSX6DBfzEQBGwdrfGGi znnIZa_8JvvmGQY3urE_T278A6Dsz.uJtCsbZV0SpwxxfGFRiDfI6NvPE95EgX9sTeqj2wGPQCbr aUGChQN.boZ8oodzob7EzklXzk0te8U.3BMSPXlfM7iTACJXldiAbIaAY0ttv1I1DdWtE8kD4VmH Wm9yvxEJlgWkP5FN8JtMq3nMouYbfxbEXUibzWYXh_s8wNHu_a0f.oMah8_NrpvrxWizPlxhqjJe J.2bGv1ze9zu_Fo5bqMrF_NpTonBpggIM2LJj37nwL9n0JANm1cT_tiYFaodBvUNqeFxLzfEPoET pWTlExRaaV_k2.QL37_ASplzoxVOEvXFSoeV67sjH_5VkWiqKmLsQcbJltUxdSCD7ywnwyzD687_ uY4prbAKR1rDvJ9QioLuJ1xta1.45kiWCUuwTntorVB9KoMR5Q6jgXe29R86E1XBuN42H4UT.7Sf u2KLmj11rSug5lsS1m.BJ5_WBs5ZTdC0e.oE.Udwp.NCqh54gabfCDXdJXr8gBkRVNA25UvyMZCH Pxxe7n78LrciF39ao8xHiGr.xDPiL1kB24AuJMFa_45G9FW00TZu3nsVpsLqFZzTgj8SoJ3woqrH g.pZZSP5CvSbGOQ67L9FcBf9xeQTjR82hBhe.kpJ9_GlnczSxgWVRwGsm7M9AkNmC4WcNL1h3G9l D6TxacNBr515UPfFOCb.OcUV9opCCwKv8sM.ZeA6e9L5UGWfAac.v48Jgj5GUybvTJYcq3L3RLwI FvJUmFF84wAgrW.RTNgRhBqeAr5ivPMO1y4oBBkYQFFOE3KYL0gkEFV8M1amIEmCUNYLV6YgnuFN Na6Y.mm1IVsdpB9zQEQjBRrk4flm1rmSz.d9wfKh3R0lxSxogh2.N2T8iy7EGdkM0bGAU.ycZDQ_ 03MYzzjRzyz3KpAV.Z9PjW7urYS_WAc3hPsA2ZhCEHrFDRPwMhAp53nsCIm_.IvZfkMMMptkK1q9 VmqiH_E83JfeWLKbFpxGnNfFH.0I6AaTbCxdzcmFiS.rBabRtDr5JKB52JOpapp.KSfVt2wWmKos z5ckpDm8qu3hCacl9_7KC2OGX8LzzrwG7ebxN6rNVK8dd5wM9Su_t.tsS7YmexSrX3UHyuxWUDnA KJjKfPgXJGOIKRprC1vioN8ThMy..8T_BIYJXJ1VPEFW8Oq2UW23UU78Y9EiOB1Q2cGajRv8q5O4 B2hhKFVE1vy2VMzQwbCF._BFJYCcagKfOTSbpjvDA0pyOMMWTh_IWqCPJx9nlGIwVIgJebMwXVuu ZKvHRd.cdZUIGSfUw9u6l_TPOTwlTzRauisu4m8eFJnd7G2W.WoPejsYEq8eYzwPoVrWsn6F.TDI ix2cuP3FrVYHplNcy3Lo6OUNBb9FcV6hTP0zZj_JWS91HBYw3LKizvlXx03ofFUJ1qhAdQ3HPz2l PyhGSHW1KDSZxvRpFuf3qwTOQEZIs8.nVOtbjUgwpPNKOGTusDf3tyqWI92YEh9DeW.aUDu0jrMl mJsWzINUJJ5vqoeCMRYYAA5Buz_RIZpQJ4AxrNSz4ebiCsNVSxOq29T80owAfnaJILliTwqnPxtF 2qvsyp91HavFL1OKo8P5noUgSMCRFu84UaE1XyuoOMfhsGyIV2nu30CEkVq7Er3ZJqfaTdmZMfeg 3az5fLfXv3DTgJTqkDPyMZFdQnwmtSXNTFKYlUFUQmLPBpDSGM2BmWKVzteNGscJX_LsJeR.yFyR N4T9jmHIMBzmN.Bx_jIZOQj_TUzqA5xQ6e2nhf9HsK4mgN2ce1tjJg3fIOwu2z2sE4R1JRN55JO7 d5XAN.j4.ib90NyY1s3U8Dzs0SSJ1R76YLyaVHDmUeTcQmToCnxaFcDS9muHhPzTNgVQYAmHZPnz YSyZ7jCp.O3wNpfuau9SX0CCsP1DwwC_EzvnBwTprlBMbcCHPQez7bR5tMN_DZqPsdqzTsb4Zae3 SvTIn4r7k6SZ8Y4.EfYOOekwms2FnodCfQSKPD5XtwAy3IGCAH1yQoDIUR5NasaRtfNDvadyP6GN 8J8UcYi8bvhQSDlon8VG0JIhnlhAhCHi5AfqmFGY7Kg8ZJkLcd1BKnFMcj5hCV2CLcFzLpPtYtq0 iD.lN_NYsXqG9PJAaAXhSepyW4EGGBFtLLS8p.g-- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic317.consmr.mail.ne1.yahoo.com with HTTP; Fri, 24 Sep 2021 18:14:55 +0000 Received: by kubenode520.mail-prod1.omega.gq1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 7dd4eebf105076a5d757483ac2549105; Fri, 24 Sep 2021 18:14:50 +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, Stephen Smalley , Pablo Neira Ayuso , netdev@vger.kernel.org, netfilter-devel@vger.kernel.org Subject: [PATCH v29 18/28] LSM: security_secid_to_secctx in netlink netfilter Date: Fri, 24 Sep 2021 10:54:31 -0700 Message-Id: <20210924175441.7943-19-casey@schaufler-ca.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210924175441.7943-1-casey@schaufler-ca.com> References: <20210924175441.7943-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: Paul Moore Acked-by: Stephen Smalley Acked-by: Pablo Neira Ayuso Signed-off-by: Casey Schaufler Cc: netdev@vger.kernel.org Cc: netfilter-devel@vger.kernel.org --- net/netfilter/nfnetlink_queue.c | 37 +++++++++++++-------------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 4490bcb2a8b6..b6922af82911 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 Fri Sep 24 17:54:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12516525 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 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id ED147C433F5 for ; Fri, 24 Sep 2021 18:16:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CE17C61164 for ; Fri, 24 Sep 2021 18:16:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348016AbhIXSRf (ORCPT ); Fri, 24 Sep 2021 14:17:35 -0400 Received: from sonic317-38.consmr.mail.ne1.yahoo.com ([66.163.184.49]:36996 "EHLO sonic317-38.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345054AbhIXSRe (ORCPT ); Fri, 24 Sep 2021 14:17:34 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1632507361; bh=6RRHAKMzwa9sJZk5WpDHWqq7PEFjTPKUpEz6QGMiD5k=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=WOfi4zuo5rzMwxOXMvdSX99jM2KG/8QwAjGzy878j4uWIfBkJipt3yB+XDtiqv8g///HVZpnm8cYb3lJOSINA6PWu66Bxrz7+f8INHOIn5xBS1QPS44NT8P8gp9Ycvsm36Wc3hsCCS4r1HktWRK507HCdq63vr5nVomKR26ZykN9Z38oih+0lklG8uvYZFF5LKJ9xWrIbcUaFMEVGFdU5qh7J4K8FOfRb+yp50NWajy6OkkyeCGPejipkmuiwqYd38KPmx0c8AyIlyMVj4JfD/qXzb4YBExLanXzWy361BYoQGhEiYGNnaiXgjQ5xaxI4ddHBd6ZlJriedxYlGDI6g== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1632507361; bh=+COx/HARcU/NIH5YuevT1+AkXh8FNu66gW8ogOFZsKn=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=CHdJM7QWX+JyOC9DGD4+k0Rldye4dwX8tErf7Fkm2j/r2p0avIPX3uq5uA/16tvOU7sHrlxN630dl5ixa/8MeiF1EpxztyYzfa58e+Aaxe/FEEsbqpGDkcQD6YAgtLNBMkE5PBubOrIHJ82z1rJymrRz6NYhHMXglhg4mPfjpusnTHPq5qjkmVs40/DDhPZnWY4SJFWiLscCY6uyIqXGynqvepQB3JRcB8PUEkgD9jbJ6I60xJT5mTOnBI7Es2Bia7eVacgKUZ67410pDV5Eh+iw/slY8jZEHLU52pHzbWd5Y/hMgr9s6YiCjNiz5zDYpiUoOaYHXpdCFh3GjZ2D7g== X-YMail-OSG: HS3JyFkVM1k0r7iTT1ScMzd6MZDJTOUzymKmjoQXwR0mQBFqlHHRQnxl5ASDCoI N8RyZhqMjSE.DpL8hizxW_GgcDaT2UNSkwfdb7Usc_xKYXfMa3ftwleCDFDb2bo.tK01z7X88MUP tIiMEmPpvAb2xn59ehk6sAMSwHzHWJ.dnwUVXkidFxPV_3g5KQT2Bvw7CTE0Pt7FgzyKab0KVX.9 cZgz7Ir3nYU4UcRae.wklCQROabYwTLmRfX.HXpFJr5Ukwd.t47D_01GGPcTWmVfD74znLGR4wIN FiYWRlVRahm0yVS0J_AhOGkUHRpl.huOUZ1kWVCdOwDBhCkVdcuDhGt6GohzjKxQUhECX1tOeKXj 0oqn_F6vbpNexCOGjm8mr8usMwSVNzWWvolLQ_NOvFkoepB27oMktkGO37UJOif4MKjQqxOrM5V9 zOXZyl_l17KbKL0.DTPQs7ApdjZx0F2YMETgdtBapvS0B223VX73MOxc72GSdXbSSX8STSQqTx71 8PwyiS4xw9M_DPAS9GK1jui70ovwFSmMLEmKFI.x07cslWw0aeQjG3z_qwA7U.WoF7gk.ZtWQ9cn xqdAyyJBA_AvT0Dt4RqT3gC8skMC_VSDtGrYYGZC_9q25MaM_zWiYBK1OffLZ7v2Lf60G8eholHz zvpYLyIJKdnz7uHGktLXpIYUfKArkbiNWF6FvwGEEtHqkn_JjyjjZp6_wkNiDO97DEsFkB7_elXr 625N6d.381f_YwrwbJu0J3GmqY4glx4ToniKfPjOGjPYGHTiLMjCDKUr7dj_btCId72Jz3uSjrQY 5JiMv8csO5cGXFrFdcMxnncSxWUbfeSONqOYD124JhnMxIxAB6f00htD6labyElRFpsHNCtpPCcx gpwGFHYa5_eQVbS1rRVPzzUmiUeLa168RgawR1x9VvLFGc5IL85sQWhCvBQWxZf.qZ.xl7Wk6H2a xSSJu6c87YydmTPmYTbGp3vwuKFOFbUtLipR8gAqmGpjjrSyaSvf139NOCQqh9jj4hBwy0shKr.B 49lLwWoytiwSkiKcS5k3KTVo5yKA8X8SnkfZ_gT2ZHaLoFuV26EA_db.6kieRRGKMJmhbGQzf1wR prxDJ.EBKhnP25ASljz43o.9_ce8_UpCVqo3vXVf7grCwmbe_ua6Wt7HS7vWdnnXcJT983e135Ni HvGyAbnCBwbvKSudStJW1KfaaAk2nxrSJ_2t8Rc8HEPHiaoT05.ubU8r.kf..mHWhuZjPBZWvhvW 40_jBtBLRcdzv__CYYiUfKWuvTyu8L5AOKNfP1fqCcI575ybtILhgrYumGKYV1qXZiJqH9slUbdX 7fhhvQ09Z9C5DUjc10MoTF93lnSJSrxYlbVF5qLfH1yvutxDhF4B6BH2uk8jKmtXyrdTYv5K5pgq PrwVHGrewi_nPl5hNaGElJZMaT6cAAdNC27NNE6UZnp7mhG7J_gX8aBfuqYofpEoGPxGVhiDctl. qilcRDgqaSURfDjzBTwsyOiDHPXuWO23rlt0yIACNOTjQdfhJKEXbQx9pKkZs0IWGcC8r3BE3nDp SGGpP2oOtnrmo6Yzb4jhNdVD.rUuSdKme02cjHlgDpxx5QdCY8WVo2yceUgHJ_H68BsnTk8Q1aES 6.i9frY23ETOV9pnkE_Z3ES2AR9KjCojE4S.B5Jasd1iDT1Ex8C4x3g3f_87JybtK7Qr0eMdT4xo a.6EZ7itMk_fGX24ErCBWnBDjktmvXgSiO.D3d9Af_Xp2zXmfOAOlWqzNPOp1ywWdvKUVhKXrb6q eRK6wgqvqkZDV4lbN7afrxdQVdAAqfiIu_NyxpKxQV.7tsRcN83rUxr7A3DbshqtxgkAR1UQMd.V ezFJrQTia3IQTp8JfMnBQ69O16AjL48XAdVm7DTGSLKdzTpVWQOjna.pROcLU_0K_z9fWTk1FDos xdcaTkxOXYjiQAgdrTuPWGH1dYDMb5lgtzyd8IbBJjAH2dg.JDgLYn_T2YF2NqPAebGyKNy2I_75 ZE5jnx5Tq6Uqklk964xCdKRljnSVppdRGgvIlYNjXoi2zB3J0J5Vfd3.zAD5A6WQen6QkOJ3hXaC ckdlx399k56TK14dXMaN3dGMmxxRvpaizJzoKA8Wm9W2FkPwpexUF79Rwr2x_T23DjxtMOWeHQV8 rBGfm3V115mXR4vZ1qwtVlxrAbIMzFqX4rtn5tu4UfnodQI4693yTasKz1lHqNMVtF7Y0cSoXqFr vNc3ZPGGNrMhLReDv68miOuQ_9kMz4e6_0uLLomty141j4qQvKvW6cDdKSFHIk0uhA7P3zqehXw. F8.eUnLt4UnpjbkbKDlC9nqY1MMSuDqhlYXE- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic317.consmr.mail.ne1.yahoo.com with HTTP; Fri, 24 Sep 2021 18:16:01 +0000 Received: by kubenode536.mail-prod1.omega.gq1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID ed781b7aa2dc5bb67ce9d484e3789b34; Fri, 24 Sep 2021 18:15:56 +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, Stephen Smalley , netdev@vger.kernel.org Subject: [PATCH v29 19/28] NET: Store LSM netlabel data in a lsmblob Date: Fri, 24 Sep 2021 10:54:32 -0700 Message-Id: <20210924175441.7943-20-casey@schaufler-ca.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210924175441.7943-1-casey@schaufler-ca.com> References: <20210924175441.7943-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 099259fc826a..9bd72ec01785 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 beb0e573266d..158bab993e32 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 596a75814fbf..60e36324568f 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, @@ -496,13 +490,8 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, (dev != NULL ? dev->name : NULL), addr->s_addr, mask->s_addr); 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); @@ -543,7 +532,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); @@ -561,13 +549,8 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, (dev != NULL ? dev->name : NULL), addr, mask); 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); @@ -921,14 +904,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); } /** @@ -975,11 +952,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); } /** @@ -1091,8 +1065,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, @@ -1130,7 +1103,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, @@ -1144,14 +1117,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, @@ -1510,7 +1479,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) @@ -1523,7 +1492,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 06974ad48b9d..c3e5fcedae0b 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -7118,7 +7118,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 e5f1b2757a83..404a573dd339 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -3901,7 +3901,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); @@ -3979,7 +3979,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 66b813e15196..44fd5bc8ba71 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 __initdata; +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 d2186e2757be..c6dcafe18912 100644 --- a/security/smack/smack_access.c +++ b/security/smack/smack_access.c @@ -524,7 +524,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 654b8a66df3c..711fb49b4d5f 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 3a75d2a8f517..9cda52f2ec31 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c @@ -1142,6 +1142,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; @@ -1273,10 +1274,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;