From patchwork Tue Jan 26 16:40:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12048539 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0062FC433DB for ; Tue, 26 Jan 2021 22:52:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B6BAE20679 for ; Tue, 26 Jan 2021 22:52:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727237AbhAZWwD (ORCPT ); Tue, 26 Jan 2021 17:52:03 -0500 Received: from sonic302-28.consmr.mail.ne1.yahoo.com ([66.163.186.154]:46693 "EHLO sonic302-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729924AbhAZRE5 (ORCPT ); Tue, 26 Jan 2021 12:04:57 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1611680613; bh=Lpq1c5WCCoZ9w1tBkBb+FVo1lvEp07/Zo19VzgwCE/0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=EeuXzN11rXuQsfrV6W3jz+u93PwGXyMXuL641zGxopjAjgP72G6Q29m3p6nPMZ/hg8qMAM1/i6q304Q1K7ahWAkqjglh7+dg3oZcn64TS7EBVKFCNonryhRTsgP1SXBEHgwthU5C4CggT7VPU/Dko+4cLm7nC0a9kFg5baGeZyvy2WgWWJI/YKqs8ows8kqiG3Fa/JYCNw4z8qOPITomNfrLWDE0j/QQG1nFtLXAEFI4MgJoKXTkDgjCpLwIV13UPRIPSnioiStvz1MxNeY6Uz7Wl4AJisLbnjcyKW+5pgV6va8gj7fiMV5loNltoGL6mf+s4Pvyr8nlzAjGZ2Mn5g== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1611680613; bh=LQx4TYLuw/DhhvH/W9FwEAxRsyP8kjuW8BG9V1THbCd=; h=From:To:Subject:Date:From:Subject:Reply-To; b=mFqK3zyQ16dFj3XUmy9rHqy2X8NlMcM+92rTuEPwX1Yn/dM0DFJZhJdfPZp9tvt1brbZB/apTV7/aCFaouHmsY4V/g0eqDgMTSqP0sGgQLyEf3/a0e62M58e9HC9rda5gEFCTQ7LqqXXUKCxp9ImNP77hiGP7MTbid/b/D8gnhQRCD1zkU+0Cl3EegkLIGbSD3yTNyGqyvl5f79QDsnng7GaAWmzZrWPO8Dsre48AE+4MrxTM3LKIitJuoroEhGUSklz3wpQ4FwIjsF67rSUtG2H/okAByasrzLsCUWwUKO6M0NTzEJcROJtBM6oZLmH4TFTaAN6DN1HnIINjk5AIg== X-YMail-OSG: Yq8f6kcVM1nGZdrvo7kl.gKq03KCBOvU44INIZxqlqyP3lQ2hJ9ktIXBsIdQGFu PA0KijOyuna1bdSsi0STFwdk08D8hp84K4wAm09SUARa2m9qbhxjQ9cAn1fQOTchBLwhlhuNAGxa HsCv6ItoZ1ru7iE4wGSGhR60y.83sMHuU7tmnHCpWQzY8TGDhr4Jlw67we7q1BjSyJbzzJVYbw8P mWmznACp.n9BVlm02DSR9WzUrJudi9s8qcIex3571JoKTC9L4zC.c.2Qlnm05U42mGjQPiiSWntq 8yczI6jsrGulX2VhhE6OFW6urbu3NtbyPXx_Oz9hcx6G08GNb8ap_2qqTOY2UyNTf6Oe89RGHTHR DFj4lR4Bm84dLza1iSfx._Fl5wfNAaH6eY_.P5B5XT.0TuhOoOXHO3LGkIrqw7cS4KRZqVXu.KI_ .0FwFUyG69TQkaEp7WWyJ69LlYyTfqlCOI7fBB4Mvs53zmkah7Y76qg2S78T.DcECkxqaUoHOcoV AYAj3zT__qwGgpYJrNhmFvafkwgCZteLtRWEGIy3HoOwjUdv68BY5.Zg4ZdLv_A.H1h.ZFqSKVw1 tlframUH9ye.bO_e3mpMk7RWNr_gtoHhW3ySuWy7yiSwdd6PQRuETZbVuM1IclNwlKHKyZoA3GJK 0mioowsFBaEHgDaejTV.2q6lFxl0Dewqs5_OH5Lv4sQOFlcIJS63e5ptt.gJdNEBAtnFk7nTtMRc HcycSIkz_IC_VaJ.G5_nf8kPykpyXzrB3UfiS8lTphND0SeVofZzIAoJSAZHweIPGUa2YmCXU5Kj chbhpr0rLBSEjfj3ZsTmdH3f9HHDJ80Dpkd3WEeFyRuGZfTB5YuEXKyoWD1YzBtmG0lVeiBPhY4X Q131JSzCRC2C3ji4BxTyL4.PmtbApGrDZsT5L5XCFbKVZ4891fiIfzxHDN2LgcA_lZDiegZNi8Zf pB4qZLIsOooatNFmgJlm_9TXlX..XBHkj5pXcXT8UgZ0tUBJ_5wKvCzr2QVi1JKSB4aYhgFmxPWV Zby0Ds6oAuWc0SitTplJ.BRC6klq2b4sQ0_1ATojujWwYf28JU0AsZAZOd9bYVmNdEzm2AxTTgv5 icuoOaiJIyL9PqmL2l18Ad.aGuVb1DBsdxGK3eoAxETf7Qu3NtxPT3OGy_V8RvZbXFYznRhxyhu5 ZdspQB6p1r7f0FAffnxU1CaepS0EAEstzdkbV400utcTtNtLChbDcJVoAh9.q.mLgtYGXg_Pow95 q7zxTHjqW0OQy0KaG35zIO6lMPQBJwJUv.g7gNZ.i6aDy8yVAM4iz9El5ysC7_b6WRJO2WGWwwTS CTPlJwMrvyMmM0bmVkMUUhI3GN9iofiJLDSuzcWG0LwP7cn8.L_zQnAkUNQoZTomtwqb0J8SoHEp a9Z5iWnxzgCaMygCGrjgpD_Qsu_qzDOHtiLki64omcaYF_EeEQ0q_9PhmRrG4cvoNBYuDnw9ZfLm GhIHgQe_7jCCD3K32pzh4lvG1H0cv1sEm7Gg0UDpGkub3.J44YSqK8Rswtmoieq5odzWQP6mJm9o tryIqAZhfmQx00cnviGg0dEydzA6K.2r9KkmfBI._dbBuSaE87v2omyqKaqEk_cMaf5g1E1urZtI qEftESySWIoA.L6OW.25MYjsem76AWjIFi5MD9_S5tm40L5e6TA_4qOkCXJdiY68e0sAlAeic0xK AYPWxJUEnFQDAfqavg3w3DnX4XV6EsGB1eBK02z8hulTJNBSJ9LR7IjD49Dk9OYLxgDjH6wu68DQ Xx9fsuR0BUsI4ISZ_DwjIvyYREW3CmUNAJTgwApQtWFJsPpiKW9vl076BOYV5U0BfGTCwTOIRFwE PXnIx43ZVKAgTqGF0adPuu6sitL4SL16XJLTz6yv5oMD2DjAW3YhPDaFrSzytud7rO6NiqawycI4 0R1Vh3MPY57fL1yJ6vCqM6NI6XFNaVi1CgKrj9cykUPPNp2zm2D849lvNpE4ssCoj7Tkk4nxLXEY sYjhxn08hvFzwQ6otcQbob0zLr5.UTGzwwq38rJh6PttTPLca.C5GLN.8764Jy9UviY4Aw_B7njh sNGx_SrrtNUdoo5c3OlxK1nlMQ86BU2Ff10cmw6_gpfQe8u_NSi.ku82F09t8Hqlhnd5U2gYmj2A r_09GfzVBSlMXINjnw0OEhTUqqMALbuqZovyWr.MbWZ5QCsqlwfoViBT6UBtkWguVqm7YjotxDYl jz2L25H2S1axtSLn2iYpN3R5quQ52VvRFUxgNT4glMQgtENdv7jrvyQ2V.aqtnY5BTG9J0R86vpq eTFsIans8UO9tVa3Mb7XflpCe0MLVvJ4vag3nNctApyoQ0obKJEjc.mtURAMrnoeIzp3mHb938OC HlymGN4D4BtDakyoJNCvmdSEv8HTwjJFAwFzDudg20V4Jmi6wdCTgiT61nHndLxAims3z6Yd30Qo mx1N7pt7FAUdgV2mxp.deJhDtx2vUYoYmsbFErkEE8h3iDExQ.DqnBQqCzD5_Fr4OI1fBYXHysKR 2Lx2_ltBdvPiPEV5wgBMa6_OJbtRc9.hCzMULJ.0eyTCITmqoXzVqHtzF7LISglSS_wL8lkXgrOf fVeRWiVGpmnyHVb44F9q4.RPg7jCtWAPrgP_1ylC8y9RDMkTV85dAEAaD8qT0CsI.8j74s7tFTOd r2RcmjnHPFfSiwDZ5FfizDomIfrbhn1Hh2BYiO54zSR42l7t5pxsv8oe5P4Kq1FN6VMfKZo6wPS6 Tm1zNktGm7uhOZvCzeg9jzhBYGJdAYJQETFN70SQQ0Xx4_7CVnzFMysOtVdkSv.dPEhRzxFPhsZc y9WadN6z2S8yYvK7rdjkHFOuv1diYPErPxjFjoxK8gbC92HjS6QqJaZ_TGZVKN22ixkW2hefEmDG 9yh6KGcBg9L8iJLZ63UmS1i0Eac4XfrWKoJPkJRBL5K8dlm0bpbXu5hDayQ.MXLM7MQPI9ALSiwa l4r1iTOKFsFvAXwJzhnGI935RyYm6mNy6obXu.5AxCyD0UOVi6vKP32dVaNT_IGKyTqW3llit3cK hAIoDYGZt6qobDnViUvUh8kTAMXWbENEPYGaOcv7iKRv1HUCbEXKUhDSX49QFgEc74e3GDT4ZXQt N Received: from sonic.gate.mail.ne1.yahoo.com by sonic302.consmr.mail.ne1.yahoo.com with HTTP; Tue, 26 Jan 2021 17:03:33 +0000 Received: by smtp411.mail.bf1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 65d04c97663aee87b05a9503446fa4ce; Tue, 26 Jan 2021 16:43:28 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov, linux-kernel@vger.kernel.org, bpf@vger.kernel.org Subject: [PATCH v24 02/25] LSM: Add the lsmblob data structure. Date: Tue, 26 Jan 2021 08:40:45 -0800 Message-Id: <20210126164108.1958-3-casey@schaufler-ca.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20210126164108.1958-1-casey@schaufler-ca.com> References: <20210126164108.1958-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 --- include/linux/audit.h | 4 +- include/linux/lsm_hooks.h | 12 ++++- include/linux/security.h | 67 +++++++++++++++++++++++++-- kernel/auditfilter.c | 24 +++++----- kernel/auditsc.c | 12 ++--- security/apparmor/lsm.c | 7 ++- security/bpf/hooks.c | 12 ++++- security/commoncap.c | 7 ++- security/integrity/ima/ima_policy.c | 40 +++++++++++----- security/loadpin/loadpin.c | 8 +++- security/lockdown/lockdown.c | 7 ++- security/safesetid/lsm.c | 8 +++- security/security.c | 72 ++++++++++++++++++++++++----- security/selinux/hooks.c | 8 +++- security/smack/smack_lsm.c | 7 ++- security/tomoyo/tomoyo.c | 8 +++- security/yama/yama_lsm.c | 7 ++- 17 files changed, 254 insertions(+), 56 deletions(-) diff --git a/include/linux/audit.h b/include/linux/audit.h index 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 f351863663b8..fb32b502080b 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -1545,6 +1545,14 @@ struct security_hook_heads { #undef LSM_HOOK } __randomize_layout; +/* + * Information that identifies a security module. + */ +struct lsm_id { + const char *lsm; /* Name of the LSM */ + int slot; /* Slot in lsmblob if one is allocated */ +}; + /* * Security module hook list structure. * For use with generic list macros for common operations. @@ -1553,7 +1561,7 @@ struct security_hook_list { struct hlist_node list; struct hlist_head *head; union security_list_options hook; - char *lsm; + struct lsm_id *lsmid; } __randomize_layout; /* @@ -1588,7 +1596,7 @@ extern struct security_hook_heads security_hook_heads; extern char *lsm_names; extern void security_add_hooks(struct security_hook_list *hooks, int count, - char *lsm); + struct lsm_id *lsmid); #define LSM_FLAG_LEGACY_MAJOR BIT(0) #define LSM_FLAG_EXCLUSIVE BIT(1) diff --git a/include/linux/security.h b/include/linux/security.h index c35ea0ffccd9..4a109092a8d7 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -133,6 +133,65 @@ enum lockdown_reason { extern const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1]; +/* + * Data exported by the security modules + * + * Any LSM that provides secid or secctx based hooks must be included. + */ +#define LSMBLOB_ENTRIES ( \ + (IS_ENABLED(CONFIG_SECURITY_SELINUX) ? 1 : 0) + \ + (IS_ENABLED(CONFIG_SECURITY_SMACK) ? 1 : 0) + \ + (IS_ENABLED(CONFIG_SECURITY_APPARMOR) ? 1 : 0) + \ + (IS_ENABLED(CONFIG_BPF_LSM) ? 1 : 0)) + +struct lsmblob { + u32 secid[LSMBLOB_ENTRIES]; +}; + +#define LSMBLOB_INVALID -1 /* Not a valid LSM slot number */ +#define LSMBLOB_NEEDED -2 /* Slot requested on initialization */ +#define LSMBLOB_NOT_NEEDED -3 /* Slot not requested */ + +/** + * lsmblob_init - initialize an lsmblob structure + * @blob: Pointer to the data to initialize + * @secid: The initial secid value + * + * Set all secid for all modules to the specified value. + */ +static inline void lsmblob_init(struct lsmblob *blob, u32 secid) +{ + int i; + + for (i = 0; i < LSMBLOB_ENTRIES; i++) + blob->secid[i] = secid; +} + +/** + * lsmblob_is_set - report if there is an value in the lsmblob + * @blob: Pointer to the exported LSM data + * + * Returns true if there is a secid set, false otherwise + */ +static inline bool lsmblob_is_set(struct lsmblob *blob) +{ + struct lsmblob empty = {}; + + return !!memcmp(blob, &empty, sizeof(*blob)); +} + +/** + * lsmblob_equal - report if the two lsmblob's are equal + * @bloba: Pointer to one LSM data + * @blobb: Pointer to the other LSM data + * + * Returns true if all entries in the two are equal, false otherwise + */ +static inline bool lsmblob_equal(struct lsmblob *bloba, struct lsmblob *blobb) +{ + return !memcmp(bloba, blobb, sizeof(*bloba)); +} + /* These functions are in security/commoncap.c */ extern int cap_capable(const struct cred *cred, struct user_namespace *ns, int cap, unsigned int opts); @@ -1839,8 +1898,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 @@ -1856,12 +1915,12 @@ static inline int security_audit_rule_known(struct audit_krule *krule) } static inline int security_audit_rule_match(u32 secid, u32 field, u32 op, - void *lsmrule) + void **lsmrule) { return 0; } -static inline void security_audit_rule_free(void *lsmrule) +static inline void security_audit_rule_free(void **lsmrule) { } #endif /* CONFIG_SECURITY */ diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 333b3bcfc545..45da229f9f1f 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -74,7 +74,7 @@ static void audit_free_lsm_field(struct audit_field *f) case AUDIT_OBJ_LEV_LOW: case AUDIT_OBJ_LEV_HIGH: kfree(f->lsm_str); - security_audit_rule_free(f->lsm_rule); + security_audit_rule_free(f->lsm_rules); } } @@ -519,9 +519,10 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, goto exit_free; } entry->rule.buflen += f_val; + f->lsm_isset = true; f->lsm_str = str; err = security_audit_rule_init(f->type, f->op, str, - (void **)&f->lsm_rule); + f->lsm_rules); /* Keep currently invalid fields around in case they * become valid after a policy reload. */ if (err == -EINVAL) { @@ -774,7 +775,7 @@ static int audit_compare_rule(struct audit_krule *a, struct audit_krule *b) return 0; } -/* Duplicate LSM field information. The lsm_rule is opaque, so must be +/* Duplicate LSM field information. The lsm_rules is opaque, so must be * re-initialized. */ static inline int audit_dupe_lsm_field(struct audit_field *df, struct audit_field *sf) @@ -788,9 +789,9 @@ static inline int audit_dupe_lsm_field(struct audit_field *df, return -ENOMEM; df->lsm_str = lsm_str; - /* our own (refreshed) copy of lsm_rule */ + /* our own (refreshed) copy of lsm_rules */ ret = security_audit_rule_init(df->type, df->op, df->lsm_str, - (void **)&df->lsm_rule); + df->lsm_rules); /* Keep currently invalid fields around in case they * become valid after a policy reload. */ if (ret == -EINVAL) { @@ -842,7 +843,7 @@ struct audit_entry *audit_dupe_rule(struct audit_krule *old) new->tree = old->tree; memcpy(new->fields, old->fields, sizeof(struct audit_field) * fcount); - /* deep copy this information, updating the lsm_rule fields, because + /* deep copy this information, updating the lsm_rules fields, because * the originals will all be freed when the old rule is freed. */ for (i = 0; i < fcount; i++) { switch (new->fields[i].type) { @@ -1358,10 +1359,11 @@ int audit_filter(int msgtype, unsigned int listtype) case AUDIT_SUBJ_TYPE: case AUDIT_SUBJ_SEN: case AUDIT_SUBJ_CLR: - if (f->lsm_rule) { + if (f->lsm_isset) { security_task_getsecid(current, &sid); result = security_audit_rule_match(sid, - f->type, f->op, f->lsm_rule); + f->type, f->op, + f->lsm_rules); } break; case AUDIT_EXE: @@ -1388,7 +1390,7 @@ int audit_filter(int msgtype, unsigned int listtype) return ret; } -static int update_lsm_rule(struct audit_krule *r) +static int update_lsm_rules(struct audit_krule *r) { struct audit_entry *entry = container_of(r, struct audit_entry, rule); struct audit_entry *nentry; @@ -1420,7 +1422,7 @@ static int update_lsm_rule(struct audit_krule *r) return err; } -/* This function will re-initialize the lsm_rule field of all applicable rules. +/* This function will re-initialize the lsm_rules field of all applicable rules. * It will traverse the filter lists serarching for rules that contain LSM * specific filter fields. When such a rule is found, it is copied, the * LSM field is re-initialized, and the old rule is replaced with the @@ -1435,7 +1437,7 @@ int audit_update_lsm_rules(void) for (i = 0; i < AUDIT_NR_FILTERS; i++) { list_for_each_entry_safe(r, n, &audit_rules_list[i], list) { - int res = update_lsm_rule(r); + int res = update_lsm_rules(r); if (!err) err = res; } diff --git a/kernel/auditsc.c b/kernel/auditsc.c index ce8c9e2279ba..9eea55525480 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -665,14 +665,14 @@ static int audit_filter_rules(struct task_struct *tsk, match for now to avoid losing information that may be wanted. An error message will also be logged upon error */ - if (f->lsm_rule) { + if (f->lsm_isset) { if (need_sid) { security_task_getsecid(tsk, &sid); need_sid = 0; } result = security_audit_rule_match(sid, f->type, f->op, - f->lsm_rule); + f->lsm_rules); } break; case AUDIT_OBJ_USER: @@ -682,21 +682,21 @@ static int audit_filter_rules(struct task_struct *tsk, case AUDIT_OBJ_LEV_HIGH: /* The above note for AUDIT_SUBJ_USER...AUDIT_SUBJ_CLR also applies here */ - if (f->lsm_rule) { + if (f->lsm_isset) { /* Find files that match */ if (name) { result = security_audit_rule_match( name->osid, f->type, f->op, - f->lsm_rule); + f->lsm_rules); } else if (ctx) { list_for_each_entry(n, &ctx->names_list, list) { if (security_audit_rule_match( n->osid, f->type, f->op, - f->lsm_rule)) { + f->lsm_rules)) { ++result; break; } @@ -707,7 +707,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 41778ff0c67c..1dfb8648136e 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -1152,6 +1152,11 @@ struct lsm_blob_sizes apparmor_blob_sizes __lsm_ro_after_init = { .lbs_sock = sizeof(struct aa_sk_ctx), }; +static struct lsm_id apparmor_lsmid __lsm_ro_after_init = { + .lsm = "apparmor", + .slot = LSMBLOB_NEEDED +}; + static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check), LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme), @@ -1852,7 +1857,7 @@ static int __init apparmor_init(void) goto buffers_out; } security_add_hooks(apparmor_hooks, ARRAY_SIZE(apparmor_hooks), - "apparmor"); + &apparmor_lsmid); /* Report that AppArmor successfully initialized */ apparmor_initialized = 1; diff --git a/security/bpf/hooks.c b/security/bpf/hooks.c index 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 bacc1111d871..e85237ecb290 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -1340,6 +1340,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), @@ -1364,7 +1369,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 823a0c1379cb..8002683003e6 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -79,7 +79,7 @@ struct ima_rule_entry { bool (*fowner_op)(kuid_t, kuid_t); /* uid_eq(), uid_gt(), uid_lt() */ int pcr; struct { - void *rule; /* LSM file metadata specific */ + void *rules[LSMBLOB_ENTRIES]; /* LSM file metadata specific */ char *args_p; /* audit value */ int type; /* audit type */ } lsm[MAX_LSM_RULES]; @@ -88,6 +88,22 @@ struct ima_rule_entry { struct ima_template_desc *template; }; +/** + * ima_lsm_isset - Is a rule set for any of the active security modules + * @rules: The set of IMA rules to check + * + * If a rule is set for any LSM return true, otherwise return false. + */ +static inline bool ima_lsm_isset(void *rules[]) +{ + int i; + + for (i = 0; i < LSMBLOB_ENTRIES; i++) + if (rules[i]) + return true; + return false; +} + /* * Without LSM specific knowledge, the default policy can only be * written in terms of .action, .func, .mask, .fsmagic, .uid, and .fowner @@ -326,9 +342,11 @@ static void ima_free_rule_opt_list(struct ima_rule_opt_list *opt_list) static void ima_lsm_free_rule(struct ima_rule_entry *entry) { int i; + int r; for (i = 0; i < MAX_LSM_RULES; i++) { - ima_filter_rule_free(entry->lsm[i].rule); + for (r = 0; r < LSMBLOB_ENTRIES; r++) + ima_filter_rule_free(entry->lsm[i].rules[r]); kfree(entry->lsm[i].args_p); } } @@ -379,8 +397,8 @@ static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry) ima_filter_rule_init(nentry->lsm[i].type, Audit_equal, nentry->lsm[i].args_p, - &nentry->lsm[i].rule); - if (!nentry->lsm[i].rule) + &nentry->lsm[i].rules[0]); + if (!ima_lsm_isset(nentry->lsm[i].rules)) pr_warn("rule for LSM \'%s\' is undefined\n", nentry->lsm[i].args_p); } @@ -545,7 +563,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode, int rc = 0; u32 osid; - if (!rule->lsm[i].rule) { + if (!ima_lsm_isset(rule->lsm[i].rules)) { if (!rule->lsm[i].args_p) continue; else @@ -558,14 +576,14 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode, security_inode_getsecid(inode, &osid); rc = ima_filter_rule_match(osid, rule->lsm[i].type, Audit_equal, - rule->lsm[i].rule); + rule->lsm[i].rules); break; case LSM_SUBJ_USER: case LSM_SUBJ_ROLE: case LSM_SUBJ_TYPE: rc = ima_filter_rule_match(secid, rule->lsm[i].type, Audit_equal, - rule->lsm[i].rule); + rule->lsm[i].rules); default: break; } @@ -952,7 +970,7 @@ static int ima_lsm_rule_init(struct ima_rule_entry *entry, { int result; - if (entry->lsm[lsm_rule].rule) + if (ima_lsm_isset(entry->lsm[lsm_rule].rules)) return -EINVAL; entry->lsm[lsm_rule].args_p = match_strdup(args); @@ -962,8 +980,8 @@ static int ima_lsm_rule_init(struct ima_rule_entry *entry, entry->lsm[lsm_rule].type = audit_type; result = ima_filter_rule_init(entry->lsm[lsm_rule].type, Audit_equal, entry->lsm[lsm_rule].args_p, - &entry->lsm[lsm_rule].rule); - if (!entry->lsm[lsm_rule].rule) { + &entry->lsm[lsm_rule].rules[0]); + if (!ima_lsm_isset(entry->lsm[lsm_rule].rules)) { pr_warn("rule for LSM \'%s\' is undefined\n", entry->lsm[lsm_rule].args_p); @@ -1733,7 +1751,7 @@ int ima_policy_show(struct seq_file *m, void *v) } for (i = 0; i < MAX_LSM_RULES; i++) { - if (entry->lsm[i].rule) { + if (ima_lsm_isset(entry->lsm[i].rules)) { switch (i) { case LSM_OBJ_USER: seq_printf(m, pt(Opt_obj_user), diff --git a/security/loadpin/loadpin.c b/security/loadpin/loadpin.c index b12f7d986b1e..b569f3bc170b 100644 --- a/security/loadpin/loadpin.c +++ b/security/loadpin/loadpin.c @@ -192,6 +192,11 @@ static int loadpin_load_data(enum kernel_load_data_id id, bool contents) return loadpin_read_file(NULL, (enum kernel_read_file_id) id, contents); } +static struct lsm_id loadpin_lsmid __lsm_ro_after_init = { + .lsm = "loadpin", + .slot = LSMBLOB_NOT_NEEDED +}; + static struct security_hook_list loadpin_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(sb_free_security, loadpin_sb_free_security), LSM_HOOK_INIT(kernel_read_file, loadpin_read_file), @@ -239,7 +244,8 @@ static int __init loadpin_init(void) pr_info("ready to pin (currently %senforcing)\n", enforce ? "" : "not "); parse_exclude(); - security_add_hooks(loadpin_hooks, ARRAY_SIZE(loadpin_hooks), "loadpin"); + security_add_hooks(loadpin_hooks, ARRAY_SIZE(loadpin_hooks), + &loadpin_lsmid); return 0; } diff --git a/security/lockdown/lockdown.c b/security/lockdown/lockdown.c index 87cbdc64d272..4e24ea3f7b7e 100644 --- a/security/lockdown/lockdown.c +++ b/security/lockdown/lockdown.c @@ -75,6 +75,11 @@ static struct security_hook_list lockdown_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(locked_down, lockdown_is_locked_down), }; +static struct lsm_id lockdown_lsmid __lsm_ro_after_init = { + .lsm = "lockdown", + .slot = LSMBLOB_NOT_NEEDED +}; + static int __init lockdown_lsm_init(void) { #if defined(CONFIG_LOCK_DOWN_KERNEL_FORCE_INTEGRITY) @@ -83,7 +88,7 @@ static int __init lockdown_lsm_init(void) lock_kernel_down("Kernel configuration", LOCKDOWN_CONFIDENTIALITY_MAX); #endif security_add_hooks(lockdown_hooks, ARRAY_SIZE(lockdown_hooks), - "lockdown"); + &lockdown_lsmid); return 0; } diff --git a/security/safesetid/lsm.c b/security/safesetid/lsm.c index 8a176b6adbe5..7c7ac9bfe5cd 100644 --- a/security/safesetid/lsm.c +++ b/security/safesetid/lsm.c @@ -244,6 +244,11 @@ static int safesetid_task_fix_setgid(struct cred *new, return -EACCES; } +static struct lsm_id safesetid_lsmid __lsm_ro_after_init = { + .lsm = "safesetid", + .slot = LSMBLOB_NOT_NEEDED +}; + static struct security_hook_list safesetid_security_hooks[] = { LSM_HOOK_INIT(task_fix_setuid, safesetid_task_fix_setuid), LSM_HOOK_INIT(task_fix_setgid, safesetid_task_fix_setgid), @@ -253,7 +258,8 @@ static struct security_hook_list safesetid_security_hooks[] = { static int __init safesetid_security_init(void) { security_add_hooks(safesetid_security_hooks, - ARRAY_SIZE(safesetid_security_hooks), "safesetid"); + ARRAY_SIZE(safesetid_security_hooks), + &safesetid_lsmid); /* Report that SafeSetID successfully initialized */ safesetid_initialized = 1; diff --git a/security/security.c b/security/security.c index 4b456b5f8096..39dce9eb3bcd 100644 --- a/security/security.c +++ b/security/security.c @@ -342,6 +342,7 @@ static void __init ordered_lsm_init(void) init_debug("msg_msg blob size = %d\n", blob_sizes.lbs_msg_msg); init_debug("sock blob size = %d\n", blob_sizes.lbs_sock); init_debug("task blob size = %d\n", blob_sizes.lbs_task); + init_debug("lsmblob size = %zu\n", sizeof(struct lsmblob)); /* * Create any kmem_caches needed for blobs @@ -469,21 +470,36 @@ static int lsm_append(const char *new, char **result) return 0; } +/* + * Current index to use while initializing the lsmblob secid list. + */ +static int lsm_slot __lsm_ro_after_init; + /** * security_add_hooks - Add a modules hooks to the hook lists. * @hooks: the hooks to add * @count: the number of hooks to add - * @lsm: the name of the security module + * @lsmid: the identification information for the security module * * Each LSM has to register its hooks with the infrastructure. + * If the LSM is using hooks that export secids allocate a slot + * for it in the lsmblob. */ void __init security_add_hooks(struct security_hook_list *hooks, int count, - char *lsm) + struct lsm_id *lsmid) { int i; + if (lsmid->slot == LSMBLOB_NEEDED) { + if (lsm_slot >= LSMBLOB_ENTRIES) + panic("%s Too many LSMs registered.\n", __func__); + lsmid->slot = lsm_slot++; + init_debug("%s assigned lsmblob slot %d\n", lsmid->lsm, + lsmid->slot); + } + for (i = 0; i < count; i++) { - hooks[i].lsm = lsm; + hooks[i].lsmid = lsmid; hlist_add_tail_rcu(&hooks[i].list, hooks[i].head); } @@ -492,7 +508,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__); } } @@ -2006,7 +2022,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); } @@ -2019,7 +2035,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); } @@ -2512,7 +2528,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) @@ -2520,14 +2553,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 d500a09c8cbd..49f721511b55 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -6941,6 +6941,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, @@ -7252,7 +7257,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 6468fe4ad755..010f97c703aa 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -4692,6 +4692,11 @@ struct lsm_blob_sizes smack_blob_sizes __lsm_ro_after_init = { .lbs_sock = sizeof(struct socket_smack), }; +static struct lsm_id smack_lsmid __lsm_ro_after_init = { + .lsm = "smack", + .slot = LSMBLOB_NEEDED +}; + static struct security_hook_list smack_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(ptrace_access_check, smack_ptrace_access_check), LSM_HOOK_INIT(ptrace_traceme, smack_ptrace_traceme), @@ -4891,7 +4896,7 @@ static __init int smack_init(void) /* * Register with LSM */ - security_add_hooks(smack_hooks, ARRAY_SIZE(smack_hooks), "smack"); + security_add_hooks(smack_hooks, ARRAY_SIZE(smack_hooks), &smack_lsmid); smack_enabled = 1; pr_info("Smack: Initializing.\n"); diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c index 1f3cd432d830..22f62c67f2ec 100644 --- a/security/tomoyo/tomoyo.c +++ b/security/tomoyo/tomoyo.c @@ -523,6 +523,11 @@ static void tomoyo_task_free(struct task_struct *task) } } +static struct lsm_id tomoyo_lsmid __lsm_ro_after_init = { + .lsm = "tomoyo", + .slot = LSMBLOB_NOT_NEEDED +}; + /* * tomoyo_security_ops is a "struct security_operations" which is used for * registering TOMOYO. @@ -575,7 +580,8 @@ static int __init tomoyo_init(void) struct tomoyo_task *s = tomoyo_task(current); /* register ourselves with the security framework */ - security_add_hooks(tomoyo_hooks, ARRAY_SIZE(tomoyo_hooks), "tomoyo"); + security_add_hooks(tomoyo_hooks, ARRAY_SIZE(tomoyo_hooks), + &tomoyo_lsmid); pr_info("TOMOYO Linux initialized\n"); s->domain_info = &tomoyo_kernel_domain; atomic_inc(&tomoyo_kernel_domain.users); diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c index 06e226166aab..a9639ea541f7 100644 --- a/security/yama/yama_lsm.c +++ b/security/yama/yama_lsm.c @@ -421,6 +421,11 @@ static int yama_ptrace_traceme(struct task_struct *parent) return rc; } +static struct lsm_id yama_lsmid __lsm_ro_after_init = { + .lsm = "yama", + .slot = LSMBLOB_NOT_NEEDED +}; + static struct security_hook_list yama_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(ptrace_access_check, yama_ptrace_access_check), LSM_HOOK_INIT(ptrace_traceme, yama_ptrace_traceme), @@ -477,7 +482,7 @@ static inline void yama_init_sysctl(void) { } static int __init yama_init(void) { pr_info("Yama: becoming mindful.\n"); - security_add_hooks(yama_hooks, ARRAY_SIZE(yama_hooks), "yama"); + security_add_hooks(yama_hooks, ARRAY_SIZE(yama_hooks), &yama_lsmid); yama_init_sysctl(); return 0; } From patchwork Tue Jan 26 16:40:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12048581 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BE131C433E0 for ; Tue, 26 Jan 2021 22:57:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 815E82065D for ; Tue, 26 Jan 2021 22:57:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729024AbhAZW5b (ORCPT ); Tue, 26 Jan 2021 17:57:31 -0500 Received: from sonic302-27.consmr.mail.ne1.yahoo.com ([66.163.186.153]:45343 "EHLO sonic302-27.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731421AbhAZRAI (ORCPT ); Tue, 26 Jan 2021 12:00:08 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1611680361; bh=Lzjaij8NdsHuYdkpeUzszfcOi0xA6IMY+POeXrHp2Uc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=FIP+wBo3Qld2lq3ByEiDJ0eioTm+HK8Cp/MDJTZjrD+T38RCO0T9hLslEZh/yFmLUe9XhSAVkOi1ZJPghleUOWQ7OyLtxJL8kuCLbTBMteZdqAAmSHacoG7ThEcJtn6Eo0zWkhmgEV87FdBLcW4xfwWSb3m4b+gGY0BMJ3+V4TAa7GsJrTS8Ve1klipgmejmMXg7vV3u/CA/Up9tF0D3Eaikuz7+08cDmL9srn+z8R2I3du706AL3ME7oG3miet9RnLFh56XxUI7JBkrxV3/F7XyUsNQEJyJmJ+FkgBnOLf6VBwdEfekorXWDADjKTQneHl1vAlxeJyHq4UlvTVw1A== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1611680361; bh=+QusOqr/5P/x1/1Gtn/bcgpceHesDZjtUyXPdN2sM2R=; h=From:To:Subject:Date:From:Subject:Reply-To; b=MJRMaQZ3xAbH1BPzzg04slvl/Ki6c+IJGAzybT8RFL5LT80IP5aOZ8EjUJSy9CLXdyCxd9hZOQnan77hkQfxmG0Uk23xjVaIhIbDv9jlXT+6BUJkvfjTQYAaRYJM3oguMcQ4Xy6TNSvjNQMvGnM6AbELfXmPNNgyw3CFu3M4lkfyzL8m88xtyTBBgd271GzWO/t6EdP0RbQpTbXszTWWi06ZkZgEvn027mrfEQpS/ongTEgKSbwoDsmsCNskTQn1BwQiTuIDe02Jn43992vqe96OJ59nkhTPShJR2ZheyTr7joslM3Vd3ZfQOhkj9u7vH8ytGZeHwgVvuKWFS3B5eg== X-YMail-OSG: fo4cTyEVM1nQ.Qsg_dniimdiFtWEG9fCIirVE9t3NZiSYNX9xLnKyopW91Mhs2Y Jh.bho9c7_AgW9OL8uVSFsCcdp8xY.3Ki3fnaLqW1CVx6TGsk_dJ3pH2UAkjhkD4iH8KiLOklIm3 QRSIp05TI6.av6oOJdLVIWlzGRuIG_Yje0j8PkHz9vMzonzkdmGkYYE8RxX3fuaMktciek8kVeUz tOAQJMwIIOEQjxXaxtWWmP9Hz3nVqb.hi44KliEIABXGeu9dwjxTpaDncSsrLwpn4hl.VN3SWTEE Ohl0FfU4ARJJ5PP4XxYyp8OhLmqQQ7nCjFzi.XIJZvzOrNgjV94_yW1sVamsTvsIEmRXoX0CJyoI NJlTWI_8ng0q1OlE0qRS2pehmnMDXy9Zxw.qu_QeV6lbRNetJA0E.c12xy8J8Bm.eZ6drh_b06GT NnwAwRk4oVdLqCvIowDdK7S7f2llqbOwE_0JxfFUxlO9wL4qyjq_OgpSo9GyBJfr7QcG8GrMjPFA d5_5J2oyjLIWfGBlqL6pdk_XTOctqOgNqKO0l4PVdUru0ygQzR5iGZVx3H3o0jNtip12QjcsiLIw jKHsVmyXWeQxy2FaBF37O4znm.gyohWNybZc17mVEr8SM01m_K.MerzUveq5tpssf5gA_ukzAxzS 6Zf0W9X4dgBC97dDWI2reqsCCCiVmBaXGVe7AXZ6sgOFAJRCBzi1y6W6Y5o5X7P7ucfKO5FPaujV feREEPOT.SdNTobFKVI16NY0DPeFR_wV3iwVwzjh2e0yinlBBVCOX0odcLtN_g3y.uBqTKsATZhU G0bJBDq.dtxIMnCvJmPbH6ktkPUtEWoHSieB3crcbqHg8tY55OvRX57qf3XeE3Cy14uRjPtqQZ23 DzvvNiKKyEzKsH1yxY.NEZ74Cc5j6hCv.56lBmpkKKTIKZjV1.U_Xk43SCkkJdINj_PXab8Qr_0W zk7XxkBKwpTl3OqeZmExZh58NWQtj4Sbm4mXxELf4EHXwggmcyu4JuiFov.wTAspvJeOs.pJ7qAG PocIhXs7Oyvfys.R8SvdF5RNMRUsS3MW7DIz3ydxraJ98o7vm8zRysatLOeT6s2i2TPIFt2KMvR5 dGE.IpRa_WaPm8y6oPaCG1NUS9338JinIOYyCULpJ3yvciUGRVml0PuNskc6FQ_PA52LCz96M36e bsYnY9FD_ikgZvRoohEOlwv1tekkmK9w2Ds9.ax4bKqZDHbCh5SDMWGtoyWl9lQjXb4cb_jdX9l6 ED2i5SzfkArKPwl71VZQgBYeOqMPqAs3w3f2gCTxGS.Y8a3bJjBhGvCXf.kwaml4Mbzee4W31ChG dBTkjLGSbNkShtXgICLCjMhuHCelt16x0qSewzReoLgR7pwbi5jJb4ZIYaMRpqsPOyGXebaSC5b8 w6Syjelwq9nILFkIYxczLhv3H1yLOPuEP7Fv3JX31dYFefRufa5VLnUZeJmbCoogeX6KUPN2y8xL EMMCuffE4U_CpTNAXR5pDHTjq7IMTeySiGOeW.pFjAh.cka1zsCwEDNbqqgaKG.GZVMKwNfmI5jy X6K0kQQvDSE871mqE3Dh96KPlc88AkxnOXq.HV1PQo52uErNrfyt0NPHcGxCeZynSGQgyQpWFxla sXts0zqMFuRdXxvfqfxLWx6YkOX9AIEfPezbMrJYB5euAF.K938ej_I5bSHzC3QdqWQHeLfdJQ8P zAvzCe_eEYPpwwUto1BKti1T.PHOSQoWCtBlhZVd1H.pE2heG2ERxIiKTTqkJHp8R6ZtSHEvhxqz HVZpTkt5pLpIYkkcvd_ExgNkFNJv5cyG1Bj0sTtIOwRNcaAbg_RENn.d.VGsMRICaGnUMDPm16yQ B98vcr6eJXxs0YWUg80CpGy3VfIt8f7ZPASF_wSyulQcC4YXanzEZ7zWosu4k70QJID90Asq_KKD sUmsqW.z0lsHGT7Oetawmwyo0.mGZViTpXmw02DAI7KS_Zrrw5B6KC2u7VjEMy.Zf3QRy_BDxiQy hG8gHujRTyexoUmW8PZSBBff9KpvA8ictmtwWrKDDjiWmuh32hU56.5TLcqmwnGU.931uy6X_5h3 sT8NkuI75d.G6iSRanppYFNEVoZwRRgFHwUmEmTwM3gwoGQffnyMJsQ.Xn9sNII39pxc58XivXO. 9PjaXP8erSm2B_fbNz9Z5IvY9A_3o4JZnAKfxuqn1j1gIyqVHXdriCpcVMVPR.L6dqqsWJNtQXPV yDmxHOFqWsgz56KOv2VBbMixknyMbr._G2Gq_WBD0BZOWuEpj35AcAo5JZgAKrxyyZqK_ci6gkR1 YraEHuc_5hyk9maZGiImabW_0YvGCknlMz_8yzFtMFd63LVUh0.qwUw1X5sAK69EG6XbfgCRMxDf BISJRphxcmWF2HeJvGIrYp2R8SlXRjLNNv8VPqjDTzMEqRUsDGreZqoI95R.QkinRwky__Tx9MX3 mO4k_lZICx4tM5wasL8br62123eKHbQD5HH7vhhNoZ8wJAzIJqJtIjd7DlDdTteb5PRWBMljiyji 53Om9c7vrUU5w7ldho4kqLzx6QrIS3EX3BiI6cWlaAIcwbKh4NxuurPN1gYkjp2e744My6OtphUp DJDuYQXIG1I_bcCtiOPk.7Qp_edkSiEDkhGJ5rpeSTnMeJ8aky..OR42S3LuWPYSIsKKRSlwqAZ. Gh9JWArb4w8JuEtiVVslkc7ClQg.9NX4hBi4D9R0g_z1Q4.TZeajK5xkNtIDRrBFAoR6xuDxrBD_ 2wNEdVkjcpLq3uynjJmc_9vBZ7xNvglhreBYm4TcW9z8h417hEDQaDmCMUH35TcIl80lOaWmgeBQ XH8mONWk6HHRe.iJq.jIOfXPTPBAuwihjR2jNyXAWWq5iEA3GcRHyq.nULKrYqaH7t7SpnLX1unq PM5us4Mw0EKg8uvVUC.RwnA8706T5vkUuZPRITEDiON153eUK4MT9D5X_ZcIWRn93G.29Fdl_4pp _nNPggk_6oQysartdxaEovYKc.2Bq34cij3AlaYguQ7IV.dJhHQO11hs2ascR4dbnY2_1oSKDwJp ppuF6UZOqTHp5mss9.C9EwVqBgY3IJ.ERcedT.6pth4MTLwfgrfXwj67iTcq6ol7_vPodU1mBLp4 .3UQOF9lFWqsj16Tt84WftyfPglX_LdQvMQjkFjYwpveV5k6oDk97vtuWiy0Z_eBvg1R_rPJNful qFpfzgimxdVKSFcfXjIJY Received: from sonic.gate.mail.ne1.yahoo.com by sonic302.consmr.mail.ne1.yahoo.com with HTTP; Tue, 26 Jan 2021 16:59:21 +0000 Received: by smtp409.mail.gq1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID ed6776a7f79f77301f8cce1a4603f7ea; Tue, 26 Jan 2021 16:49:00 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, netfilter-devel@vger.kernel.org Subject: [PATCH v24 07/25] LSM: Use lsmblob in security_secctx_to_secid Date: Tue, 26 Jan 2021 08:40:50 -0800 Message-Id: <20210126164108.1958-8-casey@schaufler-ca.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20210126164108.1958-1-casey@schaufler-ca.com> References: <20210126164108.1958-1-casey@schaufler-ca.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Change the security_secctx_to_secid interface to use a lsmblob structure in place of the single u32 secid in support of module stacking. Change its callers to do the same. The security module hook is unchanged, still passing back a secid. The infrastructure passes the correct entry from the lsmblob. Signed-off-by: Casey Schaufler Cc: netdev@vger.kernel.org Cc: netfilter-devel@vger.kernel.org To: Pablo Neira Ayuso --- include/linux/security.h | 26 ++++++++++++++++++-- kernel/cred.c | 4 +--- net/netfilter/nft_meta.c | 10 ++++---- net/netfilter/xt_SECMARK.c | 7 +++++- net/netlabel/netlabel_unlabeled.c | 23 +++++++++++------- security/security.c | 40 ++++++++++++++++++++++++++----- 6 files changed, 85 insertions(+), 25 deletions(-) diff --git a/include/linux/security.h b/include/linux/security.h index 5d8dbfb1dabb..af1d69b41f1c 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -196,6 +196,27 @@ static inline bool lsmblob_equal(struct lsmblob *bloba, struct lsmblob *blobb) extern int lsm_name_to_slot(char *name); extern const char *lsm_slot_to_name(int slot); +/** + * lsmblob_value - find the first non-zero value in an lsmblob structure. + * @blob: Pointer to the data + * + * This needs to be used with extreme caution, as the cases where + * it is appropriate are rare. + * + * Return the first secid value set in the lsmblob. + * There should only be one. + */ +static inline u32 lsmblob_value(const struct lsmblob *blob) +{ + int i; + + for (i = 0; i < LSMBLOB_ENTRIES; i++) + if (blob->secid[i]) + return blob->secid[i]; + + return 0; +} + /* These functions are in security/commoncap.c */ extern int cap_capable(const struct cred *cred, struct user_namespace *ns, int cap, unsigned int opts); @@ -513,7 +534,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); @@ -1340,7 +1362,7 @@ static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 *secle static inline int security_secctx_to_secid(const char *secdata, u32 seclen, - u32 *secid) + struct lsmblob *blob) { return -EOPNOTSUPP; } diff --git a/kernel/cred.c b/kernel/cred.c index 22e0e7cbefde..848306c7d823 100644 --- a/kernel/cred.c +++ b/kernel/cred.c @@ -757,14 +757,12 @@ EXPORT_SYMBOL(set_security_override); int set_security_override_from_ctx(struct cred *new, const char *secctx) { struct lsmblob blob; - u32 secid; int ret; - ret = security_secctx_to_secid(secctx, strlen(secctx), &secid); + ret = security_secctx_to_secid(secctx, strlen(secctx), &blob); if (ret < 0) return ret; - lsmblob_init(&blob, secid); return set_security_override(new, &blob); } EXPORT_SYMBOL(set_security_override_from_ctx); diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c index bf4b3ad5314c..58a994db0069 100644 --- a/net/netfilter/nft_meta.c +++ b/net/netfilter/nft_meta.c @@ -811,21 +811,21 @@ static const struct nla_policy nft_secmark_policy[NFTA_SECMARK_MAX + 1] = { static int nft_secmark_compute_secid(struct nft_secmark *priv) { - u32 tmp_secid = 0; + struct lsmblob blob; int err; - err = security_secctx_to_secid(priv->ctx, strlen(priv->ctx), &tmp_secid); + err = security_secctx_to_secid(priv->ctx, strlen(priv->ctx), &blob); if (err) return err; - if (!tmp_secid) + if (!lsmblob_is_set(&blob)) return -ENOENT; - err = security_secmark_relabel_packet(tmp_secid); + err = security_secmark_relabel_packet(lsmblob_value(&blob)); if (err) return err; - priv->secid = tmp_secid; + priv->secid = lsmblob_value(&blob); return 0; } diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c index 75625d13e976..9845d98e6b77 100644 --- a/net/netfilter/xt_SECMARK.c +++ b/net/netfilter/xt_SECMARK.c @@ -43,13 +43,14 @@ secmark_tg(struct sk_buff *skb, const struct xt_action_param *par) static int checkentry_lsm(struct xt_secmark_target_info *info) { + struct lsmblob blob; int err; info->secctx[SECMARK_SECCTX_MAX - 1] = '\0'; info->secid = 0; err = security_secctx_to_secid(info->secctx, strlen(info->secctx), - &info->secid); + &blob); if (err) { if (err == -EINVAL) pr_info_ratelimited("invalid security context \'%s\'\n", @@ -57,6 +58,10 @@ static int checkentry_lsm(struct xt_secmark_target_info *info) return err; } + /* xt_secmark_target_info can't be changed to use lsmblobs because + * it is exposed as an API. Use lsmblob_value() to get the one + * value that got set by security_secctx_to_secid(). */ + info->secid = lsmblob_value(&blob); if (!info->secid) { pr_info_ratelimited("unable to map security context \'%s\'\n", info->secctx); diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index ccb491642811..df9448af23dd 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -882,7 +882,7 @@ static int netlbl_unlabel_staticadd(struct sk_buff *skb, void *addr; void *mask; u32 addr_len; - u32 secid; + struct lsmblob blob; struct netlbl_audit audit_info; /* Don't allow users to add both IPv4 and IPv6 addresses for a @@ -906,13 +906,18 @@ static int netlbl_unlabel_staticadd(struct sk_buff *skb, ret_val = security_secctx_to_secid( nla_data(info->attrs[NLBL_UNLABEL_A_SECCTX]), nla_len(info->attrs[NLBL_UNLABEL_A_SECCTX]), - &secid); + &blob); if (ret_val != 0) return ret_val; + /* netlbl_unlhsh_add will be changed to pass a struct lsmblob * + * instead of a u32 later in this patch set. security_secctx_to_secid() + * will only be setting one entry in the lsmblob struct, so it is + * safe to use lsmblob_value() to get that one value. */ + return netlbl_unlhsh_add(&init_net, - dev_name, addr, mask, addr_len, secid, - &audit_info); + dev_name, addr, mask, addr_len, + lsmblob_value(&blob), &audit_info); } /** @@ -933,7 +938,7 @@ static int netlbl_unlabel_staticadddef(struct sk_buff *skb, void *addr; void *mask; u32 addr_len; - u32 secid; + struct lsmblob blob; struct netlbl_audit audit_info; /* Don't allow users to add both IPv4 and IPv6 addresses for a @@ -955,13 +960,15 @@ static int netlbl_unlabel_staticadddef(struct sk_buff *skb, ret_val = security_secctx_to_secid( nla_data(info->attrs[NLBL_UNLABEL_A_SECCTX]), nla_len(info->attrs[NLBL_UNLABEL_A_SECCTX]), - &secid); + &blob); if (ret_val != 0) return ret_val; + /* security_secctx_to_secid() will only put one secid into the lsmblob + * so it's safe to use lsmblob_value() to get the secid. */ return netlbl_unlhsh_add(&init_net, - NULL, addr, mask, addr_len, secid, - &audit_info); + NULL, addr, mask, addr_len, + lsmblob_value(&blob), &audit_info); } /** diff --git a/security/security.c b/security/security.c index a3e162c4c0d3..1039f8a8ed09 100644 --- a/security/security.c +++ b/security/security.c @@ -2127,10 +2127,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); @@ -2281,10 +2293,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 Tue Jan 26 16:40:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12048583 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A927AC433E0 for ; Tue, 26 Jan 2021 22:58:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5A9F62065D for ; Tue, 26 Jan 2021 22:58:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729724AbhAZW6I (ORCPT ); Tue, 26 Jan 2021 17:58:08 -0500 Received: from sonic302-28.consmr.mail.ne1.yahoo.com ([66.163.186.154]:35543 "EHLO sonic302-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727738AbhAZRA6 (ORCPT ); Tue, 26 Jan 2021 12:00:58 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1611680411; bh=P7N+rQcdh6yEckjA7iA6fQBZGODg+ayV5pcDDqXwZu4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=DeaoAUitTIC78nope14DYh3dje7JQSB9e/Dhe/dWnFb51YhjtTmupHg0VnKu0Lr3gft1DLbx5kpCWMqIQLI99DmVMmhk3LMbqB5SXTKLwSYfkNxWx6w0IXdIVuo9hFC294qUinl7ulSGeMDbqQ6zH8qppaVLtsE7IIqKkSvI5WyCBA9Vb+70dA5BN92rm98+ieC1CgNlM6vBfIVxH++E+n8F9Od1+NQEMteJpipboO33gbGCteYCPwPo1Cl7Og4vzSYJXqPliAPFQAnKbKzA+uYGOzz8SD86IagnCcJb0DPdPITWxKSlxqXHRc7ss7EsFwRfqJwOtJ/nKgNgJU5GfQ== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1611680411; bh=Zc3vL/ibOAbY/nNgHEt4ka7nXNA1oI7m6W9Jz9NV+yT=; h=From:To:Subject:Date:From:Subject:Reply-To; b=DJ/xRztiw/rUzENfIo1Ocn/chk0EVtOsNHyrkVhlZ4G5QtH1R1QbphX3089MVAC2VkG97m0Far23vJDY6vxQVLG8e1x85Odp7ry0YYuol/wggrPWq7kf9vlhRh3oqvD4pml+umWilW0sxB5SQ0F4xuO7M/qWhdmbsUpfCF+oSFcleysrCUOqSnFi7W6qjlieaVXmO8slUQnNElNgHarQ/GuQuyxcCTdD5Q1+dvGsRYKsuTbyRkm3O3UnIe02RrGjCIX5nRhfLri7MDmnZkYu9JNryd7eN/Z2vEDoqI2NrnKbhIFN034SB/pTRWzoCXoztsDlMp9mCnrbLBoDvL0IiQ== X-YMail-OSG: 3rH4F8oVM1k8djWWlPMpmK_TyV4LMnGrbw2cj1VN2P6voX5UbYAREjZkeOT9dk7 aMFvWIohKsMxLQMyxtF.M8_AzVJ8CHJhmgrBI6qaQSLFswdvAF6qZwfgS6MNl025Y_NfixN7.y9g POSIy4xFA4Mderrop77fHNdfp7r_MikIDFFkM.sEXhux8wSCKIZ8kpUW2d2PNNUrcWVOZ409JBqJ YtrIm94xHjxRfu4o2AsPdiEdQTCoFLvmokOPMPV4IcegoYV6kLNZfVqp.iA6Xp4ivHxM8Xx2Dmec NWksER5vOUtLRe0TpSXD8ssVOl7gCCEuueEPHOCch62.ba6x6bbVbimMi5pGqLN3CoTcpc15LrdW S7K89dsb13hPgRwHkuflPHVpZFeI3QZDE2KKegJRAAWrctHUKzDWaMd280IRjDkS1D2owdf7ojkU XZNzLWlYpsG5LGpXo41iSxqA95MJ_a4_p6d1w4bugZPQoR1iIPqBAfd0prp35utI.QUk6dEjOdVh cRQ4xyuSIzzWs.Aqt8zCAgrnNbiAF7SULJoV.grau.HFHg8PaW05kExtcDFQQtAdQbnRQMtHjkYk yr.mTsYlO0K78oMeCjQxwIEZIa1yDA4SU5WT._DCmDlog3qKgPRgY9Q_j_w6lyDEEIoZ52Ev0awM 0ZDNil9LxLXQ5VHpo8Js8Kg3CJPjCYiKV15sujjDrIYaT5pigpeADXjMw.3hpOwoTXi4.QX14lvt z.K1O4grlWrdvpeQGMrTk.Eol9tv2UGsz_D7qfU0cBOAUVpjYp3nE9RMKGyDOtMlgUDxCEHa4qoX t2zl5G7awObOk6NWHGylKirAwHfi.eo7ijv92jxwz5s2jHO9IFuJd4oRDlV3l3gkpurxKg1Ug7k7 2I1wdct9rkcooRQKifiLxYCTuowSTuZn3fNyinTBu6kd9DkNBO7coAcWpsPA35Na4oFlXHsUZr_U lFjihA6Lw6grUcQwrzmTJnzATNNsdU9FpiWjQYKYNF_QmaYTvAzC8yYPkBnBr_6i0RVYppCp4tx1 9StcgxjrRqUBXARkvcoLkotkv1tRn.3xlca3Sl.CTNPQZ_3Xxhidu4_VqCr09X79cD4eXyt7NR.D bVwoP7xJoXvIhcyd0HfaOAyDv8DuPQN_WrQtmWcS9UO1wTDUMrClWNlgu.Yaq7OQBUB9VXYin60c bJ.9ysQnsshsDmhDiS02XFfCcWOGsYYDQj_TKr95BxKby8F6qdgmm4bmjcMnhgNPAXPdTi7TlPE8 Ytg9M704d38njcZ_xl0oke53dAtFBC59hJkL.XbREB_Z32ydtFp.EGM4skrR8Qqij9X2NcX76dzK NFEaF.y2Apu6QQwL1GFI7i7ekqhgH0iYYA9hH7hQ_xakfKwjhvgrDzxrY8xqwLEh.Ka6Bu7rcSPB FfDn9qvl2Z2OYgDxl7MdcZ8tzLhbONZt0LjoHl_wToHSb6F6hAftfXs.7n3CEGgr1._pZDIjgAqs jUXxSRNTcksLpzEi2E5KdcwQOTjeWVGp_U5XKlucyMfWcBsC0FCOAvqdfMdm0PZ4iHiaq1qJ6aV0 czOMqHrzRGm5wod.gRSUkks22JyXiawxPcmvNhRR0u_02ZdZWhpVKr8L7_.S15rQ3LZQGnh6x80V WaTLcwBR1igyP2PEtP4z.A2Pb7LM4Bz22Xfp2MeZkjhA5UaaPznQ131Ee9OxuDc68oZDzkZ2EnKD 28rgPUEi227wyFakrgIf.bAaudPKTbHgR6JS5H722SYGRa7POrk_AV0oBoym6oSTCm4epGPfHMVl LmfTnr0Zo4EMcdC9PVwZcGQBEYC6X_f1Fbj3n4vaZ.cuo2hMgih464aSRwk7.8U2XWad16xk7Mxm afg.svZN2mFt7Xun4XhoxaQQH6RtY.wZnPdSFmd.qaOU7YMWP0lUJSfwiey_h6Yc4v6_pjPZT6lt rv3CCzdR0Y7iauYxGPuqsI7kSMktzoHVOqNgDNiDqXH1lLDJ8huxGcUCvdMhlS7N4Wy8Hey_wdMn V1R_A2JUEVPHB2rNlCFrywBvARONvfG.uxu2fkuG9.E9_CLys4Cl6neXxySmb6vJI7Jg5r_2SoWg TUVZ3Abj7c2RvTzFsUKJ9juIG1WkaJPImxRK2zW0Le_2gYZnURV7Hb5AgjN.LCVLYQv7SC0iQKIl ffGUs7gGXq3Hu4CuovpbYaF9BpC4EDM9C52XSKL31PvIoEXdUVh7XghR3fRVxf_4yohwh3Xjfiy2 u75ircTfUVIiHsewDxiQRQT61Md4D_STe5IrPuJPStklV7T44olQCZfx9Znh5pZvxFt_DjicoAXI Pe3Rr4GIOeqlCY9q6d3KZxAawGhOHqFmLnyDPKL.Shsv7kET7msH4WQhyvRR.B5wuyZvkBVSrXGP IH7sUtMpKbC3dSyHGLpaXtxTuVUO5uX1N9OChVTTMP_b_aDwXTRbTjMFsc7XxCTV2uY03VgIYhHo ddKTTdzRz2rkPTNarX9WPClc4DF_egHsuDNjNzbirRFPFGGlcppbtOOMFyP9eUb.0KNGqsVxrbKz Y3Ee0o4arA6ure6T32GOmneNXbaAIZdgXLg2.7bkrgmofecghUwIOl0g5SIFJCJ1lzN73ZM.F4m0 eJi0ryP9hOevyZrbv0OEMoK.D54IC4hqZC4cKs8EwoEcPNL6RZeXzdjkhOUvy5MYOwcXOfvlg1sw SyGuqlwwZSF.41Obw3q2PgH8dTILWWaFvZJPJWJKuJX.pNwQ8DFA0JBvsR0XB3HLEZEI98rWRDKB _vRcn7xqQYPDGEz66WBLKMrmJC5uM3xrkZooaPhUb7ZQKYQ6.SkADF_PbFmh8y2SrWn7wg506dx7 UVNzQBwU63dxw8jJxLGlU9dkBgb1cx4KKuIW31v9pKHZzq_SdZTe1pgf5qicqdQ3sk2LsI5d8a2N sthFMXyLl0Jse8DixAlIZ0khqQW1hPVFmBoPn_KZeggbguu6DBKUDb_7OEi4iqzpGLsTxGZSmcJe _.gf_O0sxAdst7CSZ6tJh4FoOV98lSpScA9NjtIhyBGcrcd8kHGUQ_HjnBsXnpjPe7n5YS44yLWD o0bSkT5TutT1hg.JY_TgIaOsMHDdegZAQxTG4jkV6I.4zKzCxjW8AdqGYnQaZmeoVVxCGZqNtDx6 CutUkIKYQAsJUd6oREqQY8a_ID8zM4wrOoki8hgraisvHnw1.dyc6wOkWTmlQT9dwjqi88_MmFRV LQ3IBIjneRN_ixY2D27q.IedA Received: from sonic.gate.mail.ne1.yahoo.com by sonic302.consmr.mail.ne1.yahoo.com with HTTP; Tue, 26 Jan 2021 17:00:11 +0000 Received: by smtp420.mail.ne1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 4d3ec7bb1b8474480809fc15e7b8ec0c; Tue, 26 Jan 2021 16:50:07 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, netfilter-devel@vger.kernel.org Subject: [PATCH v24 08/25] LSM: Use lsmblob in security_secid_to_secctx Date: Tue, 26 Jan 2021 08:40:51 -0800 Message-Id: <20210126164108.1958-9-casey@schaufler-ca.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20210126164108.1958-1-casey@schaufler-ca.com> References: <20210126164108.1958-1-casey@schaufler-ca.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Change security_secid_to_secctx() to take a lsmblob as input instead of a u32 secid. It will then call the LSM hooks using the lsmblob element allocated for that module. The callers have been updated as well. This allows for the possibility that more than one module may be called upon to translate a secid to a string, as can occur in the audit code. Signed-off-by: Casey Schaufler Cc: netdev@vger.kernel.org Cc: linux-audit@redhat.com Cc: netfilter-devel@vger.kernel.org To: Pablo Neira Ayuso To: Paul Moore --- drivers/android/binder.c | 12 +++++++++- include/linux/security.h | 5 +++-- include/net/scm.h | 7 +++++- kernel/audit.c | 20 +++++++++++++++-- kernel/auditsc.c | 28 +++++++++++++++++++---- net/ipv4/ip_sockglue.c | 4 +++- net/netfilter/nf_conntrack_netlink.c | 14 ++++++++++-- net/netfilter/nf_conntrack_standalone.c | 4 +++- net/netfilter/nfnetlink_queue.c | 11 +++++++-- net/netlabel/netlabel_unlabeled.c | 30 +++++++++++++++++++++---- net/netlabel/netlabel_user.c | 6 ++--- security/security.c | 11 +++++---- 12 files changed, 123 insertions(+), 29 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index c119736ca56a..5fb8555ce166 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2698,10 +2698,20 @@ static void binder_transaction(struct binder_proc *proc, if (target_node && target_node->txn_security_ctx) { u32 secid; + struct lsmblob blob; size_t added_size; security_task_getsecid(proc->tsk, &secid); - ret = security_secid_to_secctx(secid, &secctx, &secctx_sz); + /* + * Later in this patch set security_task_getsecid() will + * provide a lsmblob instead of a secid. lsmblob_init + * is used to ensure that all the secids in the lsmblob + * get the value returned from security_task_getsecid(), + * which means that the one expected by + * security_secid_to_secctx() will be set. + */ + lsmblob_init(&blob, secid); + ret = security_secid_to_secctx(&blob, &secctx, &secctx_sz); if (ret) { return_error = BR_FAILED_REPLY; return_error_param = ret; diff --git a/include/linux/security.h b/include/linux/security.h index af1d69b41f1c..f786d8833e7d 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -533,7 +533,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); @@ -1355,7 +1355,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 1ffc2e059027..72f6672a445e 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(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 a8335cbe0091..220b3a7ed326 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -671,6 +671,13 @@ static int audit_filter_rules(struct task_struct *tsk, security_task_getsecid(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, @@ -688,6 +695,13 @@ static int audit_filter_rules(struct task_struct *tsk, if (f->lsm_isset) { /* Find files that match */ if (name) { + /* + * lsmblob_init sets all values in the + * lsmblob to sid. This is temporary + * until name->osid is converted to a + * lsmblob, which happens later in + * this patch set. + */ lsmblob_init(&blob, name->osid); result = security_audit_rule_match( &blob, @@ -995,6 +1009,7 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, char *ctx = NULL; u32 len; int rc = 0; + struct lsmblob blob; ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID); if (!ab) @@ -1004,7 +1019,8 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, from_kuid(&init_user_ns, auid), from_kuid(&init_user_ns, uid), sessionid); if (sid) { - if (security_secid_to_secctx(sid, &ctx, &len)) { + lsmblob_init(&blob, sid); + if (security_secid_to_secctx(&blob, &ctx, &len)) { audit_log_format(ab, " obj=(none)"); rc = 1; } else { @@ -1247,7 +1263,10 @@ static void show_special(struct audit_context *context, int *call_panic) if (osid) { char *ctx = NULL; u32 len; - if (security_secid_to_secctx(osid, &ctx, &len)) { + struct lsmblob blob; + + lsmblob_init(&blob, osid); + if (security_secid_to_secctx(&blob, &ctx, &len)) { audit_log_format(ab, " osid=%u", osid); *call_panic = 1; } else { @@ -1400,9 +1419,10 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n, if (n->osid != 0) { char *ctx = NULL; u32 len; + struct lsmblob blob; - if (security_secid_to_secctx( - n->osid, &ctx, &len)) { + lsmblob_init(&blob, n->osid); + if (security_secid_to_secctx(&blob, &ctx, &len)) { audit_log_format(ab, " osid=%u", n->osid); if (call_panic) *call_panic = 2; diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index ec6036713e2c..2f089733ada7 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -130,6 +130,7 @@ static void ip_cmsg_recv_checksum(struct msghdr *msg, struct sk_buff *skb, static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) { + struct lsmblob lb; char *secdata; u32 seclen, secid; int err; @@ -138,7 +139,8 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) if (err) return; - err = security_secid_to_secctx(secid, &secdata, &seclen); + lsmblob_init(&lb, secid); + err = security_secid_to_secctx(&lb, &secdata, &seclen); if (err) return; diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 84caf3316946..d4902d120799 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -338,8 +338,13 @@ static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct) struct nlattr *nest_secctx; int len, ret; char *secctx; + struct lsmblob blob; - ret = security_secid_to_secctx(ct->secmark, &secctx, &len); + /* lsmblob_init() puts ct->secmark into all of the secids in blob. + * security_secid_to_secctx() will know which security module + * to use to create the secctx. */ + lsmblob_init(&blob, ct->secmark); + ret = security_secid_to_secctx(&blob, &secctx, &len); if (ret) return 0; @@ -652,8 +657,13 @@ static inline int ctnetlink_secctx_size(const struct nf_conn *ct) { #ifdef CONFIG_NF_CONNTRACK_SECMARK int len, ret; + struct lsmblob blob; - ret = security_secid_to_secctx(ct->secmark, NULL, &len); + /* lsmblob_init() puts ct->secmark into all of the secids in blob. + * security_secid_to_secctx() will know which security module + * to use to create the secctx. */ + lsmblob_init(&blob, ct->secmark); + ret = security_secid_to_secctx(&blob, NULL, &len); if (ret) return 0; diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index 46c5557c1fec..54da1a3e8cb1 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -175,8 +175,10 @@ static void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) int ret; u32 len; char *secctx; + struct lsmblob blob; - ret = security_secid_to_secctx(ct->secmark, &secctx, &len); + lsmblob_init(&blob, ct->secmark); + ret = security_secid_to_secctx(&blob, &secctx, &len); if (ret) return; diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index d1d8bca03b4f..a6dbef71fc32 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -305,13 +305,20 @@ static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata) { u32 seclen = 0; #if IS_ENABLED(CONFIG_NETWORK_SECMARK) + struct lsmblob blob; + if (!skb || !sk_fullsock(skb->sk)) return 0; read_lock_bh(&skb->sk->sk_callback_lock); - if (skb->secmark) - security_secid_to_secctx(skb->secmark, secdata, &seclen); + if (skb->secmark) { + /* lsmblob_init() puts ct->secmark into all of the secids in + * blob. security_secid_to_secctx() will know which security + * module to use to create the secctx. */ + lsmblob_init(&blob, skb->secmark); + security_secid_to_secctx(&blob, secdata, &seclen); + } read_unlock_bh(&skb->sk->sk_callback_lock); #endif diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index df9448af23dd..0e5d03c228e7 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -376,6 +376,7 @@ int netlbl_unlhsh_add(struct net *net, struct audit_buffer *audit_buf = NULL; char *secctx = NULL; u32 secctx_len; + struct lsmblob blob; if (addr_len != sizeof(struct in_addr) && addr_len != sizeof(struct in6_addr)) @@ -438,7 +439,11 @@ int netlbl_unlhsh_add(struct net *net, unlhsh_add_return: rcu_read_unlock(); if (audit_buf != NULL) { - if (security_secid_to_secctx(secid, + /* lsmblob_init() puts secid into all of the secids in blob. + * security_secid_to_secctx() will know which security module + * to use to create the secctx. */ + lsmblob_init(&blob, secid); + if (security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " sec_obj=%s", secctx); @@ -475,6 +480,7 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, struct net_device *dev; char *secctx; u32 secctx_len; + struct lsmblob blob; spin_lock(&netlbl_unlhsh_lock); list_entry = netlbl_af4list_remove(addr->s_addr, mask->s_addr, @@ -494,8 +500,13 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, addr->s_addr, mask->s_addr); if (dev != NULL) dev_put(dev); + /* lsmblob_init() puts entry->secid into all of the secids + * in blob. security_secid_to_secctx() will know which + * security module to use to create the secctx. */ + if (entry != NULL) + lsmblob_init(&blob, entry->secid); if (entry != NULL && - security_secid_to_secctx(entry->secid, + security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " sec_obj=%s", secctx); security_release_secctx(secctx, secctx_len); @@ -537,6 +548,7 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, struct net_device *dev; char *secctx; u32 secctx_len; + struct lsmblob blob; spin_lock(&netlbl_unlhsh_lock); list_entry = netlbl_af6list_remove(addr, mask, &iface->addr6_list); @@ -555,8 +567,13 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, addr, mask); if (dev != NULL) dev_put(dev); + /* lsmblob_init() puts entry->secid into all of the secids + * in blob. security_secid_to_secctx() will know which + * security module to use to create the secctx. */ + if (entry != NULL) + lsmblob_init(&blob, entry->secid); if (entry != NULL && - security_secid_to_secctx(entry->secid, + security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " sec_obj=%s", secctx); security_release_secctx(secctx, secctx_len); @@ -1082,6 +1099,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, u32 secid; char *secctx; u32 secctx_len; + struct lsmblob blob; data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).portid, cb_arg->seq, &netlbl_unlabel_gnl_family, @@ -1136,7 +1154,11 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, secid = addr6->secid; } - ret_val = security_secid_to_secctx(secid, &secctx, &secctx_len); + /* lsmblob_init() secid into all of the secids in blob. + * security_secid_to_secctx() will know which security module + * to use to create the secctx. */ + lsmblob_init(&blob, secid); + ret_val = security_secid_to_secctx(&blob, &secctx, &secctx_len); if (ret_val != 0) goto list_cb_failure; ret_val = nla_put(cb_arg->skb, diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c index 3ed4fea2a2de..893301ae0131 100644 --- a/net/netlabel/netlabel_user.c +++ b/net/netlabel/netlabel_user.c @@ -86,6 +86,7 @@ struct audit_buffer *netlbl_audit_start_common(int type, struct audit_buffer *audit_buf; char *secctx; u32 secctx_len; + struct lsmblob blob; if (audit_enabled == AUDIT_OFF) return NULL; @@ -98,10 +99,9 @@ struct audit_buffer *netlbl_audit_start_common(int type, from_kuid(&init_user_ns, audit_info->loginuid), audit_info->sessionid); + lsmblob_init(&blob, audit_info->secid); if (audit_info->secid != 0 && - security_secid_to_secctx(audit_info->secid, - &secctx, - &secctx_len) == 0) { + security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " subj=%s", secctx); security_release_secctx(secctx, secctx_len); } diff --git a/security/security.c b/security/security.c index 1039f8a8ed09..271584938404 100644 --- a/security/security.c +++ b/security/security.c @@ -2108,17 +2108,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 Tue Jan 26 16:40:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12049651 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 50C12C433DB for ; Wed, 27 Jan 2021 10:34:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id F15B520731 for ; Wed, 27 Jan 2021 10:34:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S314151AbhAZW7u (ORCPT ); Tue, 26 Jan 2021 17:59:50 -0500 Received: from sonic302-28.consmr.mail.ne1.yahoo.com ([66.163.186.154]:36313 "EHLO sonic302-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727723AbhAZRDL (ORCPT ); Tue, 26 Jan 2021 12:03:11 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1611680543; bh=dFxn+XstgtjQ2XuQtuYIDEUl9oT83QnnSfCL65X5xww=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=eh8vxoj9xUpXpVNGlhpo3g2oV4OHqXZFkxqI8J8Hml4Ul7qPDVypfwD4Rq8q9Oo6MwGvqFb4Sww3dQchEa7HEFkGwgu+Km+5iinY9HUCNiqRbTUxN9NW0OtupBnsTjxaf8XK+/mzVaBeDum14+9HqE6dwvvz6fxD1Z71MLJWuaYKbhEaGJBPwQsDKP9MfYeVsfkj0ZlmoFGwKlGPfc7FP5iNWLSPOWOZC/PLqXhRd39n2aaGkCzko/2Z0leh7ZgUGlAGjSPgzKH+cEU2a2inUjwzANBe6NQzxgcE96eD7hpez/j/Znf6e6vukXYqkJhl1lPZ+DbQ0sOdlE/GTBtSyA== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1611680543; bh=rgioX4APgl+z4swDFpM+Lsb7j+bofddUMPDl3luMqZ9=; h=From:To:Subject:Date:From:Subject:Reply-To; b=ibvOQGjDRSzCpHvtgWSqDT6cguggAYF9jgtFnhxTfUJ9B1350ib7IuzzP3OaEgMjBFO4V4+xci/WEzG+ngwnxjTJjTUIhNb6lnCp46USxnrke7voB8NZUmIvZNL4+cgaantB1vgqISKGyRUJmQkjX0mNx7LWA8jmiaJNN4gQu1F9EsXI4cwqRQN4ho4nCSCkuOLnBi/NFmX2zgP/yecmrs1H1YW6WLPSgRFSxOuU5JpCY8JFWNsqjDx3r3MIB99pwna4P5rO+GjvcqFDrDLxSy3fMEJ9B57D6kCTlndmDSXVE2ieyEKtZ99483js6n4DgEMg1v0gmMT+erSdhH9yBA== X-YMail-OSG: GdA.bgMVM1kOalMoQXcSuHW7qF.N0PpMzfV_qVFedodKgPWEl11dovAlTHyj6Xe H1hA0SU5ME3_LtPj3b_Z6SAgQaqMciNTwcMXHe1qqz9V0qXxLwntDiZsIhlJCOtw0Fl3LtDVPFGm E0nxc1Wh2SxovUgEPhmPPl39EwebPlI9Qt.ngd..k2GmSHoQIraeTV7dwli2USseTKFD8W3m6QtF dfdBawxlIH2xIEryhjKxT5bxN1MOWPPbhI4QS8bz_1PtypXCqMvDmtcJNpVXNeOoSVgKz2XPXHru rym6fhLtB79yLIl4GaHTr8KL1ikDGAAwuBF3eNNw0zlHuir4eqepZRvvBQWS_u6P_z5OzKpOu9mi xyDbDKynMi8SUMl9EQcMwEjbYAgS0r1h1eTrsAcDMa4ZGkPIrphBFY9W6ywXAO.fsYej6Fi2klzl eUnAfqxkJYckyJgIJ.iu2Y9KWRvSGdCBw7GnV3ohL1JnDB1qK32zRS_Eekwxry3yXf5rsW2AKoFP xRrm9Pr69IJZmue74iPotq.B4XnjvhYaDs6BrpRTJ_t7o9GAZaYLsXYGBHobKKi607k.nCfkRNka jXQe9AXCptxuFhlxSLCSvERuycfNPVel6XudBQRjWTrQnOJRa15SPJsiU63RMDmZubAmmCePU6vG xK97sB.ZMOcoP1cIrZbB5Z10zxiTTD5Dddd9LJYa2h6Z9tha9AnA1H8zkqKBPlm8p1zQfMewKaG6 KWQFU_8cxHuLWocVpmz0XmwlljDp_swtPr2dgzDpUcEbrt.5wCi5Tz79EN_3ucZY5ZyoP2XJjTHV 2DVr9TPzo7dnyPXJStbjAQRY4orFKZ6vHY6tr_sCF0i3K8JkIVQ8oNTtS11mmL6RVRJoR6TCoHjt v7lDy6cy9C0YDx8nVuVbBcVtI4RHihQG1gcm1J6Gcvss6.ICUZ7e34dLZsIo2fFCmuVtekO50Y3_ lE38IKDTEAluEShD2lLOEMS7L1tS9ir8nfsZOmSSmnuf3VwMw1F5pIGkZCOTqTzi6xX6vEiz0l2p ZLR5UOCpW_fvv6JQYHiuDanQh4rzpEZt2SOT63RMDkpthcU9n8rOIZUV1_fLlF8s7gVrJ_miZkAE 1TPRg4_5BTcPRqRvNwtUGYNG3otz10.w8Z1jWiLsIBbrkiN_FtXIVNh1qNLx3ql3BOBd9oIjzh2l u49oZtVK2YrKyleSOzdkdP709zQDIoK0c.rcf3mrE13gIi7h.4xQfic4UP7fpQpl_69MChq0IRXF wnUmI_1iU85IWvrGhK_XN4oNvCZOI_i3rPKCMV.BrBG0TgOpRZw8U2c96n5tEWlnuyq0rYfwdwJA dhvNvP0bS0BZUkjMgANt4sGG_pdPQ4tJoW6gw6pDcZEeK457sa8M3Peq7a6hYbEcfaP4e7IuXgO3 SpW3u04jl_VmupWWGWW9nyfi75DrjFCzeb.uTqgyTX154QAMCJQGmD1OXtjgBdwPZMe7pC2EX1qe 8duxr3REQgmrmFhszjhaYjV.fRv.pvWal7skC4lAIAumQRhBv0cI8mDIandUs9QOmr5K.8A9JL8x cur_lWV6EpVk9JXefReWl0j7h3m5BUo0UrGFRe.Uf4_6BvPGv7aW1Ie.47jDseiqHRFfFDgRyZhX K4rFpZjvIKURJViA1Z8dhqxmQ9fWOhnOVj5dCg2fRFxNlCLzA9gBMQAUghEDgIEhLBsqJY16ZvZn IJuQPY9ve7HbCqGUp_cr3DWnb.HhbLZXgznv3kUvCy1BCUpLxhy6wC..2tzHCj4sHEK6oPWkn0L7 exp0SNbOttXh8twYVxK_n6c3cABHAXX1Ep24Gbqh8dTCDOL4PnHf_ahQ3iBqsysqb0lmN4xxLnHk .xUXZlVqS3pGqrm2qvCt9MoLoHO5UtcX3_Aki_nJYdkKF1bYnjCwyd3xn5GonEtLysEaIwA8eyiv ITXfCldZ.TjaUmcjQ1zijlHujXeOoC2hO8MSFZLFAuL0SQf_qNMESQaBSp8h5gHxF51tQUt6MY1B hxLaBWgemqNHoNu1QyzqNx863G7XOna2uHQtPrpNUVVtQGmcBHOfZTQX40KgS6jZKYarWwvYYwEs H3694GRKCOZfyW3zZCBJUeB4ttka2u6SN_Op0NpKzp9LFp.5fUiiPgavq5BVguRHKfOnGa9D4GFo 9FUcC4ftiS7lWCBXwZpM.VWS5YpT8Z31MDuS_MePGdSoay018J.36U0VJj_Q5V7CE1EFTo_Zkbnh xWSORmLPtaBMkNURG_HArwa8KDINLguxiTEHaNuPVWkYqZs5JMQ0flabiPY38XfHM91jnBMQOUgk LyLEqyVmIIDTUl60eWIgUzg0FX0p2bMQYT5ctS2T7xJsnpfNFHk4sHZepPjCFIXQpCXPbm7ZTN4A 1UG_O6QorP4PSgUuNamFkju02X1lC.YVo4jjWr88x3xf.QMLn9HYV5.mpT.pIZE8O_tHi_Zukngb QsnCM1D60wU6e1ef4CqgIt2gUBjFuLrR3fUEHtRTzXm0tv37XCZW23R6J.1ntI8HQs.OKqEad75A QY_4T659b.Z.SuyaCBZSS8_CKvMz5uKi_usnZzHSC078_G6b1iCVGgdsLIFwzxfOCjCxD6tXEksb 37fmcmHnK8BxsicKZW5rVtc08mxCV4YMjca_COepJTYmxJ0IOuz0D88EuHMGimOZkrOS_5aYIe.g HmVgrD2qVJHhLnyxJoNCA.pImmnl7vfT7oRPTIT3edbwXFYOqnDyHBNXSh41WutnnoB0c_CanXia GxthjFqrz6AW0.7zJRislARX2JPt6bM6BgcRZljvGCVoO4Ru28Cb_VQ.zt2DcJT1LZqVFSn6q2R3 J0wm85aXS8BNBQ.5Fpj8tZDNvBP0M5Qm51XDJ2kXrwtuSlSHTtz0uMDol8XO8NblQADvjodlxfA2 dURf85B7M28Aa5LYdv98xGdgGGHUQWwCO5IcIAMG.zws7TY0_zCsxP3HKy2oPxP3ruCuP5wutuIL FDvIodE_aTUgUj5WfBn8zAW4ywXDw6VShWBZoLRpsKmhGuzNy1hbpxM0ubsUYJjdYB86ecDT50cv ugvQMV1qpQFAtzDf3qJA22ZnR7F6Ut3CNzzDRHTDxBfnfZ2xJ5u.IgHYzFL.NvfUxjp6kPQal8pq .xZimiRYrMf66iXz32eF2vvjV2DSfqCWQNtelWNd9m94DIN.trsf2kWR4dD7EriyijbPxBFjwm84 G8KcA3VTmW1c9R3k4GvLTrtcb Received: from sonic.gate.mail.ne1.yahoo.com by sonic302.consmr.mail.ne1.yahoo.com with HTTP; Tue, 26 Jan 2021 17:02:23 +0000 Received: by smtp409.mail.gq1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 8a206ee65e60eda6fcd8c0233148fc12; Tue, 26 Jan 2021 16:52:17 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov, linux-kernel@vger.kernel.org, linux-integrity@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH v24 10/25] LSM: Use lsmblob in security_task_getsecid Date: Tue, 26 Jan 2021 08:40:53 -0800 Message-Id: <20210126164108.1958-11-casey@schaufler-ca.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20210126164108.1958-1-casey@schaufler-ca.com> References: <20210126164108.1958-1-casey@schaufler-ca.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Change the security_task_getsecid() interface to fill in a lsmblob structure instead of a u32 secid in support of LSM stacking. Audit interfaces will need to collect all possible secids for possible reporting. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley Acked-by: Paul Moore Signed-off-by: Casey Schaufler Cc: linux-integrity@vger.kernel.org Cc: linux-audit@redhat.com Cc: netdev@vger.kernel.org --- drivers/android/binder.c | 12 +----- include/linux/security.h | 7 ++-- kernel/audit.c | 16 +++----- kernel/auditfilter.c | 4 +- kernel/auditsc.c | 25 ++++++------ net/netlabel/netlabel_unlabeled.c | 5 ++- net/netlabel/netlabel_user.h | 6 ++- security/integrity/ima/ima_appraise.c | 10 +++-- security/integrity/ima/ima_main.c | 56 +++++++++++++++------------ security/security.c | 12 ++++-- 10 files changed, 80 insertions(+), 73 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 5fb8555ce166..1a15e9e19e22 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2697,20 +2697,10 @@ static void binder_transaction(struct binder_proc *proc, t->priority = task_nice(current); if (target_node && target_node->txn_security_ctx) { - u32 secid; struct lsmblob blob; size_t added_size; - security_task_getsecid(proc->tsk, &secid); - /* - * Later in this patch set security_task_getsecid() will - * provide a lsmblob instead of a secid. lsmblob_init - * is used to ensure that all the secids in the lsmblob - * get the value returned from security_task_getsecid(), - * which means that the one expected by - * security_secid_to_secctx() will be set. - */ - lsmblob_init(&blob, secid); + security_task_getsecid(proc->tsk, &blob); ret = security_secid_to_secctx(&blob, &secctx, &secctx_sz); if (ret) { return_error = BR_FAILED_REPLY; diff --git a/include/linux/security.h b/include/linux/security.h index 20a47bd3930b..9fc245c1f739 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -487,7 +487,7 @@ int security_task_fix_setgid(struct cred *new, const struct cred *old, int security_task_setpgid(struct task_struct *p, pid_t pgid); int security_task_getpgid(struct task_struct *p); int security_task_getsid(struct task_struct *p); -void security_task_getsecid(struct task_struct *p, u32 *secid); +void security_task_getsecid(struct task_struct *p, struct lsmblob *blob); int security_task_setnice(struct task_struct *p, int nice); int security_task_setioprio(struct task_struct *p, int ioprio); int security_task_getioprio(struct task_struct *p); @@ -1160,9 +1160,10 @@ static inline int security_task_getsid(struct task_struct *p) return 0; } -static inline void security_task_getsecid(struct task_struct *p, u32 *secid) +static inline void security_task_getsecid(struct task_struct *p, + struct lsmblob *blob) { - *secid = 0; + lsmblob_init(blob, 0); } static inline int security_task_setnice(struct task_struct *p, int nice) diff --git a/kernel/audit.c b/kernel/audit.c index 72f6672a445e..e70bbd6b91c4 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(current, &sid); - if (!sid) + security_task_getsecid(current, &blob); + if (!lsmblob_is_set(&blob)) return 0; - /* - * lsmblob_init sets all values in the lsmblob to sid. - * This is temporary until security_task_getsecid is converted - * to use a lsmblob, which happens later in this patch set. - */ - lsmblob_init(&blob, sid); error = security_secid_to_secctx(&blob, &ctx, &len); if (error) { if (error != -EINVAL) @@ -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(current, &audit_sig_sid); + security_task_getsecid(current, &blob); + /* scaffolding until audit_sig_sid is converted */ + audit_sig_sid = blob.secid[0]; } return audit_signal_info_syscall(t); diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index e27424216159..9e73a7961665 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -1330,7 +1330,6 @@ int audit_filter(int msgtype, unsigned int listtype) for (i = 0; i < e->rule.field_count; i++) { struct audit_field *f = &e->rule.fields[i]; pid_t pid; - u32 sid; struct lsmblob blob; switch (f->type) { @@ -1361,8 +1360,7 @@ int audit_filter(int msgtype, unsigned int listtype) case AUDIT_SUBJ_SEN: case AUDIT_SUBJ_CLR: if (f->lsm_isset) { - security_task_getsecid(current, &sid); - lsmblob_init(&blob, sid); + security_task_getsecid(current, &blob); result = security_audit_rule_match( &blob, f->type, f->op, f->lsm_rules); diff --git a/kernel/auditsc.c b/kernel/auditsc.c index b3ad40787740..62e2e6de5486 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -471,7 +471,6 @@ static int audit_filter_rules(struct task_struct *tsk, { const struct cred *cred; int i, need_sid = 1; - u32 sid; struct lsmblob blob; unsigned int sessionid; @@ -668,17 +667,9 @@ static int audit_filter_rules(struct task_struct *tsk, logged upon error */ if (f->lsm_isset) { if (need_sid) { - security_task_getsecid(tsk, &sid); + security_task_getsecid(tsk, &blob); need_sid = 0; } - /* - * lsmblob_init sets all values in the lsmblob - * to sid. This is temporary until - * security_task_getsecid() is converted to - * provide a lsmblob, which happens later in - * this patch set. - */ - lsmblob_init(&blob, sid); result = security_audit_rule_match(&blob, f->type, f->op, @@ -2426,12 +2417,15 @@ int __audit_sockaddr(int len, void *a) void __audit_ptrace(struct task_struct *t) { struct audit_context *context = audit_context(); + struct lsmblob blob; context->target_pid = task_tgid_nr(t); context->target_auid = audit_get_loginuid(t); context->target_uid = task_uid(t); context->target_sessionid = audit_get_sessionid(t); - security_task_getsecid(t, &context->target_sid); + security_task_getsecid(t, &blob); + /* scaffolding - until target_sid is converted */ + context->target_sid = blob.secid[0]; memcpy(context->target_comm, t->comm, TASK_COMM_LEN); } @@ -2447,6 +2441,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; @@ -2458,7 +2453,9 @@ int audit_signal_info_syscall(struct task_struct *t) ctx->target_auid = audit_get_loginuid(t); ctx->target_uid = t_uid; ctx->target_sessionid = audit_get_sessionid(t); - security_task_getsecid(t, &ctx->target_sid); + security_task_getsecid(t, &blob); + /* scaffolding until target_sid is converted */ + ctx->target_sid = blob.secid[0]; memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN); return 0; } @@ -2479,7 +2476,9 @@ int audit_signal_info_syscall(struct task_struct *t) axp->target_auid[axp->pid_count] = audit_get_loginuid(t); axp->target_uid[axp->pid_count] = t_uid; axp->target_sessionid[axp->pid_count] = audit_get_sessionid(t); - security_task_getsecid(t, &axp->target_sid[axp->pid_count]); + security_task_getsecid(t, &blob); + /* scaffolding until target_sid is converted */ + axp->target_sid[axp->pid_count] = blob.secid[0]; memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN); axp->pid_count++; diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 0e5d03c228e7..93240432427f 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -1564,11 +1564,14 @@ int __init netlbl_unlabel_defconf(void) int ret_val; struct netlbl_dom_map *entry; struct netlbl_audit audit_info; + struct lsmblob blob; /* Only the kernel is allowed to call this function and the only time * it is called is at bootup before the audit subsystem is reporting * messages so don't worry to much about these values. */ - security_task_getsecid(current, &audit_info.secid); + security_task_getsecid(current, &blob); + /* scaffolding until audit_info.secid is converted */ + audit_info.secid = blob.secid[0]; audit_info.loginuid = GLOBAL_ROOT_UID; audit_info.sessionid = 0; diff --git a/net/netlabel/netlabel_user.h b/net/netlabel/netlabel_user.h index 3c67afce64f1..438b5db6c714 100644 --- a/net/netlabel/netlabel_user.h +++ b/net/netlabel/netlabel_user.h @@ -34,7 +34,11 @@ static inline void netlbl_netlink_auditinfo(struct sk_buff *skb, struct netlbl_audit *audit_info) { - security_task_getsecid(current, &audit_info->secid); + struct lsmblob blob; + + security_task_getsecid(current, &blob); + /* scaffolding until secid is converted */ + audit_info->secid = blob.secid[0]; audit_info->loginuid = audit_get_loginuid(current); audit_info->sessionid = audit_get_sessionid(current); } diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index 8361941ee0a1..afcf715de585 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c @@ -70,14 +70,16 @@ bool is_ima_appraise_enabled(void) */ int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func) { - u32 secid; + struct lsmblob blob; if (!ima_appraise) return 0; - security_task_getsecid(current, &secid); - return ima_match_policy(inode, current_cred(), secid, func, mask, - IMA_APPRAISE | IMA_HASH, NULL, NULL, NULL); + security_task_getsecid(current, &blob); + /* scaffolding the .secid[0] */ + return ima_match_policy(inode, current_cred(), blob.secid[0], func, + mask, IMA_APPRAISE | IMA_HASH, NULL, NULL, + NULL); } static int ima_fix_xattr(struct dentry *dentry, diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index f87cb29329e9..175a79076569 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -388,12 +388,13 @@ static int process_measurement(struct file *file, const struct cred *cred, */ int ima_file_mmap(struct file *file, unsigned long prot) { - u32 secid; + struct lsmblob blob; if (file && (prot & PROT_EXEC)) { - security_task_getsecid(current, &secid); - return process_measurement(file, current_cred(), secid, NULL, - 0, MAY_EXEC, MMAP_CHECK); + security_task_getsecid(current, &blob); + /* scaffolding - until process_measurement changes */ + return process_measurement(file, current_cred(), blob.secid[0], + NULL, 0, MAY_EXEC, MMAP_CHECK); } return 0; @@ -419,9 +420,9 @@ int ima_file_mprotect(struct vm_area_struct *vma, unsigned long prot) char *pathbuf = NULL; const char *pathname = NULL; struct inode *inode; + struct lsmblob blob; int result = 0; int action; - u32 secid; int pcr; /* Is mprotect making an mmap'ed file executable? */ @@ -429,9 +430,10 @@ int ima_file_mprotect(struct vm_area_struct *vma, unsigned long prot) !(prot & PROT_EXEC) || (vma->vm_flags & VM_EXEC)) return 0; - security_task_getsecid(current, &secid); + security_task_getsecid(current, &blob); inode = file_inode(vma->vm_file); - action = ima_get_action(inode, current_cred(), secid, MAY_EXEC, + /* scaffolding */ + action = ima_get_action(NULL, current_cred(), blob.secid[0], 0, MMAP_CHECK, &pcr, &template, 0); /* Is the mmap'ed file in policy? */ @@ -468,10 +470,12 @@ int ima_bprm_check(struct linux_binprm *bprm) { int ret; u32 secid; + struct lsmblob blob; - security_task_getsecid(current, &secid); - ret = process_measurement(bprm->file, current_cred(), secid, NULL, 0, - MAY_EXEC, BPRM_CHECK); + security_task_getsecid(current, &blob); + /* scaffolding until process_measurement changes */ + ret = process_measurement(bprm->file, current_cred(), blob.secid[0], + NULL, 0, MAY_EXEC, BPRM_CHECK); if (ret) return ret; @@ -492,10 +496,11 @@ int ima_bprm_check(struct linux_binprm *bprm) */ int ima_file_check(struct file *file, int mask) { - u32 secid; + struct lsmblob blob; - security_task_getsecid(current, &secid); - return process_measurement(file, current_cred(), secid, NULL, 0, + security_task_getsecid(current, &blob); + /* scaffolding until process_measurement changes */ + return process_measurement(file, current_cred(), blob.secid[0], NULL, 0, mask & (MAY_READ | MAY_WRITE | MAY_EXEC | MAY_APPEND), FILE_CHECK); } @@ -659,7 +664,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 @@ -679,8 +684,9 @@ int ima_read_file(struct file *file, enum kernel_read_file_id read_id, /* Read entire file for all partial reads. */ func = read_idmap[read_id] ?: FILE_CHECK; - security_task_getsecid(current, &secid); - return process_measurement(file, current_cred(), secid, NULL, + security_task_getsecid(current, &blob); + /* scaffolding - until process_measurement changes */ + return process_measurement(file, current_cred(), blob.secid[0], NULL, 0, MAY_READ, func); } @@ -709,7 +715,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) @@ -722,9 +728,10 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size, } func = read_idmap[read_id] ?: FILE_CHECK; - security_task_getsecid(current, &secid); - return process_measurement(file, current_cred(), secid, buf, size, - MAY_READ, func); + security_task_getsecid(current, &blob); + /* scaffolding until process_measurement changes */ + return process_measurement(file, current_cred(), blob.secid[0], buf, + size, MAY_READ, func); } /** @@ -839,7 +846,7 @@ void process_buffer_measurement(struct inode *inode, const void *buf, int size, } hash = {}; int violation = 0; int action = 0; - u32 secid; + struct lsmblob blob; if (!ima_policy_flag) return; @@ -859,9 +866,10 @@ void process_buffer_measurement(struct inode *inode, const void *buf, int size, * buffer measurements. */ if (func) { - security_task_getsecid(current, &secid); - action = ima_get_action(inode, current_cred(), secid, 0, func, - &pcr, &template, keyring); + security_task_getsecid(current, &blob); + /* scaffolding */ + action = ima_get_action(inode, current_cred(), blob.secid[0], + 0, func, &pcr, &template, keyring); if (!(action & IMA_MEASURE)) return; } diff --git a/security/security.c b/security/security.c index 197f69780783..3f0a3aedad19 100644 --- a/security/security.c +++ b/security/security.c @@ -1845,10 +1845,16 @@ int security_task_getsid(struct task_struct *p) return call_int_hook(task_getsid, 0, p); } -void security_task_getsecid(struct task_struct *p, u32 *secid) +void security_task_getsecid(struct task_struct *p, struct lsmblob *blob) { - *secid = 0; - call_void_hook(task_getsecid, p, secid); + struct security_hook_list *hp; + + lsmblob_init(blob, 0); + hlist_for_each_entry(hp, &security_hook_heads.task_getsecid, list) { + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + hp->hook.task_getsecid(p, &blob->secid[hp->lsmid->slot]); + } } EXPORT_SYMBOL(security_task_getsecid); From patchwork Tue Jan 26 16:40:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12048585 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4F1AAC433E6 for ; Tue, 26 Jan 2021 23:01:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1C414206A1 for ; Tue, 26 Jan 2021 23:01:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731491AbhAZXBJ (ORCPT ); Tue, 26 Jan 2021 18:01:09 -0500 Received: from sonic307-15.consmr.mail.ne1.yahoo.com ([66.163.190.38]:43949 "EHLO sonic307-15.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387535AbhAZRLd (ORCPT ); Tue, 26 Jan 2021 12:11:33 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1611681045; bh=QikK5FDa9ha7K4Pey08ED+rnanltyysxQB2wrUvqcV0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=GjMtAVKB02q4nFFSnOmhdjYMGe5lqIPzwYojSlfYjSDTiu0fK2XKrgS+TtGtTaYibV4WGXfTzeo7BreyDtW+V3EUU/0aFkGrKzdVwEgJuJByQ17ey8K27pSpoOGNHRii0C/DnkAAMhw15j13ZeX6TR8bCedN4FlVkI6AU8xQXl2G2MG8jZVzonDAHAyEtqnBuOsr5BT/THIq3qbvy0tINV58AHNpEtxSbOukGzS00ZpcPKPm0weokbkX4WcgTJxOhUtkW4yhYQ59HrXx3Jb4heIpa0AbhVuz6poWajjCrGqNhQyT+9P5wijPZ64LuwtZ7UIfzgdfEDRCmsgYXNvMcQ== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1611681045; bh=mIeYpe96uog47inFM7rOo54QLnt+oY2W1sj/Wv254jU=; h=From:To:Subject:Date:From:Subject:Reply-To; b=Wixw6+xm6rANZ4IQpghncoAnWrXukdcYiHRzzkLsmQW9IsOuB7McGluBn4EaTFytwr3Zlt7lut3bQge2soc+p9AsgYiyMxn5GRuuBuypHnfbCtSVDcP7wvkQXYrfG/GtbIN/g8CxxC/uKYoNssmNNmza/kJHOCrcunaURLpwZQAj5FBLXwj2LWy1gXETMxYnzKWGAPXWq8JyuwpCjS1JVTFKHCT/E4BFhT4g1Bq/4gLOM9rCk4KxciPW0Xt3hHbj31pKdydpDKK8ZgCjRNcRD69F1sJueU8G3ElMr6gA39DsRiKmj239QCOP4iC3okeGY+/rFcUWEpAa4+GaCuy4aQ== X-YMail-OSG: JjBztuwVM1mkQQIU0PiQJj9zaECOXd_1WsXXmVMEfcFeyjY3Ng2tXACP78ghX68 TA9SkZxeoy00TL5kWE9LvdjvK5AAa41ur2EO3QkiQR3qERCiJiiDg2B2LaM4VjFwpC3Gt3td8jKd 7oHWof7EApS93MNptVu8pUjoB4_lLeiEU_sCsVDdmG0SBHlD7XS2T5sg_iJBmaezqav_QDuCHf9L AbFnts4I0g1hpf7VssE9gmO.N6UAqvB5DkBuprI2NY2.fQ3rv0bSHsi9SyjOsed1oDV.Dw9l7tTI ZzlGye64Jzqj9IM118SFgpjlZ84ATT._ZOFx.gPspukzga96MbeuG6aTUAb0WrwMkJRKe.UV52fH LAGTbcHzWkpYa4SLtpe3m4_h0QWtBtJGYT_09yIlWfs6kdQ395opJdXzBBUivvOtMe73Pyfo3vUE lC.69rEEvBotuz.nonLRet2vOw1NIWe_VEhnHeZqxZRIzYuJcNtwMm63rJtctiroRHda2axAMxa_ FDTPokwgI3KacSe8US0NhP3J6w8PQe22Dmuw3gt0BlFchtwW3KWAWCAhvy8gQVgz4AMsmM1BE8Y5 04DVNDNuXvL.2kMgI0tID6W30Z8KtNOaCj.OITWu9hapWFLmFEvWTIkCRTE94RJCj9bpDASVEgrK 4OM5GEAnw6HCsWDn53vfWxNAtdFZni2fYTF155a5plCXj.odTbTLGwJttxDwa4.Gce1rZfWkntoo nSLuZLz_DGVlVbTVHdycxQy2IlrcXZnLq6ujMDDrharPdrZs4cM_fO_qA2nhUxb4TYUQ5kczbGiM 8l6VONuOv9gcQTcf8gEQHAT0279Rv0YGHEUNjPfbCpOh5VzqhPpICOplPcKJkohfoiSCriIB.CA0 kguPvaKZBYeBblz6ZopGOppZ6u36xeFyvwhT8YxCuM2ay.21xIaRQkkqugdrzwyy8Ft2olPxFWSM NAI4gOvHMSMG2R6sHs5fVbq2PeMEEIgBIc9Izick2hURvJwqisdTuHmvtdWQOibqTyTay9moxzIe Onz1cnn_fqn7ej7WbXeQfbNCo2cu7QSwrc_bS.rDkbTEmqBsflthaM.31x7CoquDM1qCuY0nttCx VJHHNjIn_yuqTz6KaeCchxwe0u6REi_uhSU0rgf.NBhr8F6pCr1hHOClJBM35MmiGVBN5phGHwVt 7QmYbHG54ydN7wwPHi2Mdg0y7Kut3.byXSl7C8TH1BbHAB42zvAd3_TUhys3mapc_IHfFEudxBL4 qsEnbLZIpoP3DSVluEWZJu6MOgFIO0dFTiZzJaU7HyyeB09YRhhR6ccSzCN8saiDqw1R9pP623dl zZFpyT6tNjrqZYfct2qxt.0v0dsqpasZpNfPx5_rWCk6jJodj4flgDax5698HaOnWmDDaXlUTq6L Z5oSWaHFsCN_SniICXZOJTw30WVS1zJHDrpQY2OQMH8hl_Et3f2bzNWv1vDtRSieRwiK7v0jl1fp lo31d_L6.atm3.epkqWR4wPAp.H7AhFCiBSu_u6P.wFFu5DGkWRCjehAzLtrG9pNxM8A23.Mi9jV gA8DTq_SdBGgtcqYjbWNe3WMlKpNoe9m6eS9i867VD1w6xFJdOGoMyGjVLBoSr4EMHt1uB.vbqLH nWgUT8FY68g2TFRezmB0h2mcr67jtgjKPEpnh_UWDJwk8lxOV50x1ZUB3voIalwoEsrJCGj9nj6. mYae4DUGF.pTqs0aXM22b_zGm1NcDrjOv0y3CtEKbqtL1P4Isr5quWy91dJwTIY5mkPlAzFdTx2w zeFQ0cUtEKvvIVE1Qj7YXCrA2UsJDU2oXPoLRPQM67TnI6ser4F3M_zqdS7_Hg8dlpB42P45AE7C Xaou.41LIcILE7dXyNEmqox3C.577Q_aCmM_7Xno7toB1fPVPBLG.RwBUz8vvHmGfEYN7PyAO.Ap J4EoEfsVGH1ijlT0I0U21AWRPVwWl_5OHqV5kWZKgtgLnI8EX4lRgze079dHaRvmS8.UTzkuToaG .tnI1_bYQzCv76HNmykZeLhA.zC1EDB1SIgB92m_DIaK8B1Gvmda7QfCQkhXUPnArghyakEtLsmX AmqSZ2sFy5XpnPy5ANPXvvg1XiFT4eo6y9OX.fUiAZ19J2BZAThUf7Pli1PUMnqZBAjUliRKXhjT p.LBRnpbLLiwVgcMxF5j.xIGnHMMxXamJw86nGbBBtOn97Lv7k05qa7SbvderagDbFVvzN6HdTmc 82DBWETMh6V09JeqhwnGTOML1d8EUpgcLpPzqlv3AxFZloTjjHG4Dcnhe5WIhI5gXcFVXX66QwTB fq5XatYgM6pgjj4PRmzkXgq2PPBNLvh7orcU3.DPEvmhTE91rzQG3ayEsLoBKwS6VjPceIYw79xY UJpDozxwLTvYsPscRmSpgsVWUkT7jifRUySdABP4TUdngnYJrN3g2zcPGhsg12o7AvyGk6pY1km4 dB2wSi6mgrkKLgS6qyUAxJR0C31V5sSZhZPiF9O56elauLqMr2qvsnlBwn3rh2RBnwN2S0HF49jn NQe4G8DhDAV0W0W0zNcwa_iL4EFXRbIX8BdsGXmgAIzKWmOfHeC.8bHOOXpKirQG5k1VH_26n6JN 7LrCiqhL.rWYiNwmqAeiaT8Io51XslAZ13GArhSlEc9WnL4emay8QsPwx09vIHDrkU.yPAzzrzKo jfbSSX9NFwWBzUs1rTSSQPtF.tuk_Dex1qGaSx0H_LnjfsEWylqUE9bYmmkuED_WgVul0SQxtG3D eONd8ZZDP8AqdejMDz4199wJhJDpBZ4oQVcBQoGe66ucRDwL30UJJzqH9plP8BAwtkEQmBxIhGe2 51yNOTEXlmSxv11gCuA98zdS7Ra8dJUWgLHTDy.EzCAp4Q8IMqn27GK_hwQrsWDhEcI_mUZbXHfv jU3Ezg2DrRAmhcgd2fUhn_p3loprVCQzkh86_cPBNUeTWG0R2P8uQwXuAG52ktYgEZgOsVisUB.l Jcb2vSfB4pjSB6jojqJ8md_AhtDaDSQgB9UMISZLrMZx8B0wH_mClysEOWQdR.WMOWArGmEgp7BQ tMqAvyW30K5.mOhSucatRS__JXCfpcJOzlhkHDpH27feNWhTozvBW.4j0_cDuK1R9kYBBz4L2j.8 nPdCOtQU4L6TSJdDjpyrj7w3TtI_tuJexjsjHe9RpAlzncpCREmRold7FdpKMHh_9p3SO6pBgAHx YtX8aGSNEq678OFruSxfQhIoC3cWZgFOfRLsuoXy7HpMGyL0Kgz0kZMfDRjJ9w4CosyDWEDso4cx csQgHGQ3El0EcnvidP84jJuojFpbn1yTFah42p5jVbIcBbGgmXPkHIbpjJhbml.O3Kpa_gbXIIwx 370N1KHUz9YsL4_kDg0H6TOs8OxmKbLQKK_0- Received: from sonic.gate.mail.ne1.yahoo.com by sonic307.consmr.mail.ne1.yahoo.com with HTTP; Tue, 26 Jan 2021 17:10:45 +0000 Received: by smtp405.mail.gq1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 14a20754c00469ce98c71e55bb16a4d7; Tue, 26 Jan 2021 16:57: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, linux-integrity@vger.kernel.org, netdev@vger.kernel.org, netfilter-devel@vger.kernel.org, linux-nfs@vger.kernel.org Subject: [PATCH v24 15/25] LSM: Ensure the correct LSM context releaser Date: Tue, 26 Jan 2021 08:40:58 -0800 Message-Id: <20210126164108.1958-16-casey@schaufler-ca.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20210126164108.1958-1-casey@schaufler-ca.com> References: <20210126164108.1958-1-casey@schaufler-ca.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Add a new lsmcontext data structure to hold all the information about a "security context", including the string, its size and which LSM allocated the string. The allocation information is necessary because LSMs have different policies regarding the lifecycle of these strings. SELinux allocates and destroys them on each use, whereas Smack provides a pointer to an entry in a list that never goes away. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley Signed-off-by: Casey Schaufler Cc: linux-integrity@vger.kernel.org Cc: netdev@vger.kernel.org Cc: linux-audit@redhat.com Cc: netfilter-devel@vger.kernel.org To: Pablo Neira Ayuso Cc: linux-nfs@vger.kernel.org --- drivers/android/binder.c | 10 ++++--- fs/ceph/xattr.c | 6 ++++- fs/nfs/nfs4proc.c | 8 ++++-- fs/nfsd/nfs4xdr.c | 7 +++-- include/linux/security.h | 35 +++++++++++++++++++++++-- include/net/scm.h | 5 +++- kernel/audit.c | 14 +++++++--- kernel/auditsc.c | 12 ++++++--- net/ipv4/ip_sockglue.c | 4 ++- net/netfilter/nf_conntrack_netlink.c | 4 ++- net/netfilter/nf_conntrack_standalone.c | 4 ++- net/netfilter/nfnetlink_queue.c | 13 ++++++--- net/netlabel/netlabel_unlabeled.c | 19 +++++++++++--- net/netlabel/netlabel_user.c | 4 ++- security/security.c | 11 ++++---- 15 files changed, 121 insertions(+), 35 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 1a15e9e19e22..f74a72867ec9 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2448,6 +2448,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; @@ -2750,7 +2751,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; @@ -3084,8 +3086,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 24997982de01..cc4f911f0d74 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c @@ -1348,12 +1348,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 0ce04e0e5d82..d3c29eb2e9dd 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -139,8 +139,12 @@ nfs4_label_init_security(struct inode *dir, struct dentry *dentry, static inline void nfs4_label_release_security(struct nfs4_label *label) { - if (label) - security_release_secctx(label->label, label->len); + struct lsmcontext scaff; /* scaffolding */ + + if (label) { + lsmcontext_init(&scaff, label->label, label->len, 0); + security_release_secctx(&scaff); + } } static inline u32 *nfs4_bitmask(struct nfs_server *server, struct nfs4_label *label) { diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 45ee6b12ce5b..43698f15a52b 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -2834,6 +2834,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 @@ -3335,8 +3336,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 e4a4816f1b94..cfa19eb9533b 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -133,6 +133,37 @@ enum lockdown_reason { extern const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1]; +/* + * A "security context" is the text representation of + * the information used by LSMs. + * This structure contains the string, its length, and which LSM + * it is useful for. + */ +struct lsmcontext { + char *context; /* Provided by the module */ + u32 len; + int slot; /* Identifies the module */ +}; + +/** + * lsmcontext_init - initialize an lsmcontext structure. + * @cp: Pointer to the context to initialize + * @context: Initial context, or NULL + * @size: Size of context, or 0 + * @slot: Which LSM provided the context + * + * Fill in the lsmcontext from the provided information. + * This is a scaffolding function that will be removed when + * lsmcontext integration is complete. + */ +static inline void lsmcontext_init(struct lsmcontext *cp, char *context, + u32 size, int slot) +{ + cp->slot = slot; + cp->context = context; + cp->len = size; +} + /* * Data exported by the security modules * @@ -536,7 +567,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); @@ -1371,7 +1402,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 f6af7b27a6fa..902962ea9be6 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(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 c766502b58f2..a73253515bc9 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -998,6 +998,7 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, struct lsmblob *blob, char *comm) { struct audit_buffer *ab; + struct lsmcontext lsmcxt; char *ctx = NULL; u32 len; int rc = 0; @@ -1015,7 +1016,8 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, rc = 1; } else { audit_log_format(ab, " obj=%s", ctx); - security_release_secctx(ctx, len); + lsmcontext_init(&lsmcxt, ctx, len, 0); /*scaffolding*/ + security_release_secctx(&lsmcxt); } } audit_log_format(ab, " ocomm="); @@ -1228,6 +1230,7 @@ static void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name) static void show_special(struct audit_context *context, int *call_panic) { + struct lsmcontext lsmcxt; struct audit_buffer *ab; int i; @@ -1261,7 +1264,8 @@ static void show_special(struct audit_context *context, int *call_panic) *call_panic = 1; } else { audit_log_format(ab, " obj=%s", ctx); - security_release_secctx(ctx, len); + lsmcontext_init(&lsmcxt, ctx, len, 0); + security_release_secctx(&lsmcxt); } } if (context->ipc.has_perm) { @@ -1410,6 +1414,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)) { @@ -1418,7 +1423,8 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n, *call_panic = 2; } else { audit_log_format(ab, " obj=%s", ctx); - security_release_secctx(ctx, len); + lsmcontext_init(&lsmcxt, ctx, len, 0); /* scaffolding */ + security_release_secctx(&lsmcxt); } } diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 2f089733ada7..a7e4c1b34b6c 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -130,6 +130,7 @@ static void ip_cmsg_recv_checksum(struct msghdr *msg, struct sk_buff *skb, static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) { + struct lsmcontext context; struct lsmblob lb; char *secdata; u32 seclen, secid; @@ -145,7 +146,8 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) return; put_cmsg(msg, SOL_IP, SCM_SECURITY, seclen, secdata); - security_release_secctx(secdata, seclen); + lsmcontext_init(&context, secdata, seclen, 0); /* scaffolding */ + security_release_secctx(&context); } static void ip_cmsg_recv_dstaddr(struct msghdr *msg, struct sk_buff *skb) diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index d4902d120799..3b9cf2a1fed7 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -339,6 +339,7 @@ static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct) int len, ret; char *secctx; struct lsmblob blob; + struct lsmcontext context; /* lsmblob_init() puts ct->secmark into all of the secids in blob. * security_secid_to_secctx() will know which security module @@ -359,7 +360,8 @@ static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct) ret = 0; nla_put_failure: - security_release_secctx(secctx, len); + lsmcontext_init(&context, secctx, len, 0); /* scaffolding */ + security_release_secctx(&context); return ret; } #else diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index 54da1a3e8cb1..e2bdc851a477 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -176,6 +176,7 @@ static void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) u32 len; char *secctx; struct lsmblob blob; + struct lsmcontext context; lsmblob_init(&blob, ct->secmark); ret = security_secid_to_secctx(&blob, &secctx, &len); @@ -184,7 +185,8 @@ static void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) seq_printf(s, "secctx=%s ", secctx); - security_release_secctx(secctx, len); + lsmcontext_init(&context, secctx, len, 0); /* scaffolding */ + security_release_secctx(&context); } #else static inline void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index a6dbef71fc32..dcc31cb7f287 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -398,6 +398,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, enum ip_conntrack_info ctinfo; struct nfnl_ct_hook *nfnl_ct; bool csum_verify; + struct lsmcontext scaff; /* scaffolding */ char *secdata = NULL; u32 seclen = 0; @@ -628,8 +629,10 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, } nlh->nlmsg_len = skb->len; - if (seclen) - security_release_secctx(secdata, seclen); + if (seclen) { + lsmcontext_init(&scaff, secdata, seclen, 0); + security_release_secctx(&scaff); + } return skb; nla_put_failure: @@ -637,8 +640,10 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, kfree_skb(skb); net_err_ratelimited("nf_queue: error creating packet message\n"); nlmsg_failure: - if (seclen) - security_release_secctx(secdata, seclen); + if (seclen) { + lsmcontext_init(&scaff, secdata, seclen, 0); + security_release_secctx(&scaff); + } return NULL; } diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 93240432427f..32b6eea7ba0c 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -374,6 +374,7 @@ int netlbl_unlhsh_add(struct net *net, struct net_device *dev; struct netlbl_unlhsh_iface *iface; struct audit_buffer *audit_buf = NULL; + struct lsmcontext context; char *secctx = NULL; u32 secctx_len; struct lsmblob blob; @@ -447,7 +448,9 @@ int netlbl_unlhsh_add(struct net *net, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " sec_obj=%s", secctx); - security_release_secctx(secctx, secctx_len); + /* scaffolding */ + lsmcontext_init(&context, secctx, secctx_len, 0); + security_release_secctx(&context); } audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0); audit_log_end(audit_buf); @@ -478,6 +481,7 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, struct netlbl_unlhsh_addr4 *entry; struct audit_buffer *audit_buf; struct net_device *dev; + struct lsmcontext context; char *secctx; u32 secctx_len; struct lsmblob blob; @@ -509,7 +513,9 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " sec_obj=%s", secctx); - security_release_secctx(secctx, secctx_len); + /* scaffolding */ + lsmcontext_init(&context, secctx, secctx_len, 0); + security_release_secctx(&context); } audit_log_format(audit_buf, " res=%u", entry != NULL ? 1 : 0); audit_log_end(audit_buf); @@ -546,6 +552,7 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, struct netlbl_unlhsh_addr6 *entry; struct audit_buffer *audit_buf; struct net_device *dev; + struct lsmcontext context; char *secctx; u32 secctx_len; struct lsmblob blob; @@ -576,7 +583,8 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " sec_obj=%s", secctx); - security_release_secctx(secctx, secctx_len); + lsmcontext_init(&context, secctx, secctx_len, 0); + security_release_secctx(&context); } audit_log_format(audit_buf, " res=%u", entry != NULL ? 1 : 0); audit_log_end(audit_buf); @@ -1095,6 +1103,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, int ret_val = -ENOMEM; struct netlbl_unlhsh_walk_arg *cb_arg = arg; struct net_device *dev; + struct lsmcontext context; void *data; u32 secid; char *secctx; @@ -1165,7 +1174,9 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, NLBL_UNLABEL_A_SECCTX, secctx_len, secctx); - security_release_secctx(secctx, secctx_len); + /* scaffolding */ + lsmcontext_init(&context, secctx, secctx_len, 0); + security_release_secctx(&context); if (ret_val != 0) goto list_cb_failure; diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c index 893301ae0131..ef139d8ae7cd 100644 --- a/net/netlabel/netlabel_user.c +++ b/net/netlabel/netlabel_user.c @@ -84,6 +84,7 @@ struct audit_buffer *netlbl_audit_start_common(int type, struct netlbl_audit *audit_info) { struct audit_buffer *audit_buf; + struct lsmcontext context; char *secctx; u32 secctx_len; struct lsmblob blob; @@ -103,7 +104,8 @@ struct audit_buffer *netlbl_audit_start_common(int type, if (audit_info->secid != 0 && security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " subj=%s", secctx); - security_release_secctx(secctx, secctx_len); + lsmcontext_init(&context, secctx, secctx_len, 0);/*scaffolding*/ + security_release_secctx(&context); } return audit_buf; diff --git a/security/security.c b/security/security.c index 517623ba81dc..904ae6c46be0 100644 --- a/security/security.c +++ b/security/security.c @@ -2288,16 +2288,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 Tue Jan 26 16:40:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12048561 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.9 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNWANTED_LANGUAGE_BODY, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 61F9DC4332B for ; Tue, 26 Jan 2021 22:56:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2FE9F206A1 for ; Tue, 26 Jan 2021 22:56:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731059AbhAZW4b (ORCPT ); Tue, 26 Jan 2021 17:56:31 -0500 Received: from sonic302-27.consmr.mail.ne1.yahoo.com ([66.163.186.153]:38754 "EHLO sonic302-27.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729159AbhAZRAB (ORCPT ); Tue, 26 Jan 2021 12:00:01 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1611680353; bh=YuN+vLavAomDIwCV+0bu+wUx+9A2og5OAA8ID4nFGbY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=jY4Y5g0SuKZzJhwk6au7u7l8Hj9q1RNJnKXSMg8M38aA6gO7fXSveMZLgFwaHTmmZM6aIJyynLmYJPeWoa7PJ43D59OtuH2RgVMp4tMxT9KQ0BGbu1rKYXCr9aMwTv+LHNiW0qFy2Oa9o9BUJC+d5Ww6DLCJpXtlhobadnQUz2o9AK9y1vu1Q3zcysXVtCzPtnaPY08zW2RtMWEkakfL8BFyOyXQMMzQ7ZpJt3Xxn1EftALA89UIS7EwwajHYfi9aNFSSjLumCZ96LkAfBH2adlxW+jn3xgfUq19lDYgjxOmWSrMC1c3oLOonLZwCi7LfUronh4gbEgH8BnFtb8Q7Q== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1611680353; bh=cG3EePbFNYbI1mPTEo7clgAfpVbSk8QzkBfbcODAzzo=; h=From:To:Subject:Date:From:Subject:Reply-To; b=DsmPdpepj8yhruYMbQBFlXBRi4QHAQFoZ2KR4aLc0ad79laMBr0YyDYmu8u6Ye4w+eAhwCYhv0apisuP5ObyAFRITkCkCOsSzYL/eha08KS/bfHrey76WkXtB/xX4Zeb4VyYfb8GcD6nDiPPeKOhzRAWMODYduIr5G1F5Bw5fpmLyNgL6Qg01CC0XxH/seuQehsX/6QqJfEDcfaNVv1eNI1RVG+PEkhbmVKp3s9PoxaM2sJAOCBwOALJbcmzj54985+e/ppGcYeKGXFMArcwszWtWk5a0dRQEM/tpIl1m6kot+OQLO44qPWF2iSmdCzFEKWsIF+mMVDxeBEwFtKhfA== X-YMail-OSG: Hbtmn0MVM1lEPjW.sr6AjcxWIdLg8bKLPwcOmauLl3uJBDU1GIZ9MupFhtA1tT7 PBkU3vbunswujG_Iofp_sSnspbG6xiOCSzFnYSLHanhCSFfSuaVXxJUyl4zUiv.2rPFTGH5Q1Tls jq6.wZhhjZjeMWM.VLHnsAjnDqoQJICoA0h5LNG6gZCJYPouc.ckm4HQtjqWm2GrtuTIPbKS5KeY zGEhGcq055DXfpBI3CtzxUJPeRR_zBhq9GnFgjtMQDuIJLMUdXHdBY5ZheyESfnJqWCDQlS15lOv zYB4sAixs0tUiOz2SBy3xdVmItbf7iJTh8ghkSR.aP.yR1vavUz_YNsPfgG8DusqDNJj1GsitWGy O6LNET312kRrWUP16tayQlm6RIbOu8ypkuTtPDP3Fr4QfpC2JBDc1BM4aVGVQbwOXQR8BOJkl.x7 3ZU9uFaEi6I1T.6OF5XdjwDwJDEKbVfUOTXrw3Fw4QoJ.S1gf_hUxziuTcWfpCxzx2_l2mwxKu.7 KBFuCP4oU_r313yvkBEa0N4zRctuVuGX.CkmYeDmOcNLiR0dXQ0n3K7TSQA4EkFx_oyV9qLfBewY 1imbnJVU3jyMq_mXPvnubWr27AH65TEG3hRi7I.sBge.8x11bhs_Eo1u74D_9FKbtr7l.bMQRqSe qlKs9YRYqP1RHNESnewjD3LmEwqTD9LdKlhGbKReTb3Iah3h_Y6O587RR8qEqAeWbq0MkyHZ2DSF aIqecK9VFBBM.ZA85eZGDcleEYOHUA0w4nG_pGNjNqyLlsUz0RFTx2jjQMu_wgL5L7JegBa2HbYs D88nvNXgbpJMgSW9JgLCYnbGGcxyDy8d2jZszq_uuZMdu6ys4p9NBFKIEu.oEv8lGzcHtI258OlB qahqTck_AKSDHUcH9v8QC8tHG40vvEHDGCq.p_wCVP.bdL276s3zw0gdJwqYWaoqxisf9mAjcsva r4thk9jMJGORi1ZRvHAaD_goNbEwow62HFSdU3JOyJOXk_ITuGRlwEPEeb3E7TRJD7P27Sq8j2xb 9GBkPhNaq7PpqyOJO4uxB2dpcv68X6t3hUrBiinMFIUCHaFEJZzaD0IomI4Df_WBq7dmqT.AjAx2 .kMx2tDbmXhOlNSMhoSkpLiUND3E8IVT_mnTM0CXjUa6KfM0o9lT8IAStM_ijK5EXK4ZlBGDv5t5 AVPrWM.m5rMXSTbelaI.8GJL_jW_KvWvj1Vl4W.G.4T_mCLpojIbCC_J73L8o535TXRTwkQF7LoJ aY6mEBLSTlg_LVbM96PcmHzs8lKKdogjJA3PtbiZeTBTJIwELo12vzwBBd6.YX3ftq3.RgKxB1Wp DDFWgFii5HYW4iiYx_r3dAgWSNYA5ZHrN9bNo.ELESm_368VK.rEo7TDTz9jLZnZrq_SU2s0Z76T v90i.veb7AJc_jvgXd1S2zZMVDAWXqgmMuLGU9rtMYHtm66wuQlzOaZUF_7uXKU7xRs_ZTnpFZgn brzhieOJ.jxdIpqVC3A3uKVMEKZuwuSYcTp7pyJc4GRlUVmwDP3V9ZTTCt0GxeoUx.d3Pd5mbOOZ Aeo5a4Q.33WB3pUyEqmrnevveGGWLBI4ttlTDQLRY9GR8BoqVbe5GbbMOlakV6k4jsHNtlllNOXv qt.1xAd0D_VovgghGptLnVKA2R_nOeQ9IRX5oA4pJuguKtf5VC0NGd6.WbrdAIQl6au_b7wU6U_w t3EadGPblLAR6.PW.KJB0ieKYQWMKeyaj3870J4y1VBZHDVOVY3CsBtS2ahDzurmGH4ABFtwAURv dKmJQ8AWlrSxFVCUwEU633TIvpg48NC5_R4uBXRujldh3daPWqHZwvrOrrJLIudpLfy07dCK51a2 EZmA6r58UexSf5sAuxn3qdzW6rlN8Zm2jBORgaY6djJv9V6xeX3CMb0ofmr9Vu4_5JWWhJvaFus9 492e0ht5urdczLiPKeH6iWf7k03Bl08UEMV4iY2YG9nFoFxjoT9B2TQbJpHziya5C4Sf0DTPg8Fu 417cNuBMZpoEIAh9ZqhxV1NguPUyGhJNIDV0EBq1ZAzy9TDWJiSx0wwca5mt_ohdegD1vzM61jPS RTb.tQrrGDlCGO30.P7tKpeGT1QCQIMsCVJqE62CDlnxkKI.Hq0PCONVVTNpgM3CYULBE_r9D2Xe BaGrmaubhYhb0JeooGqHGp5BRKbhrgu5OqrnSlgmK1bPaZ6SR8wBL_xRGooGUMYAYn0_rM7ZgnZi kUMho7691sMHZTTc7zEWonX2mt5DPDGXhBxx4D8_fgXUSgDsyCV9I9h2vgBxCIV5h.ouXh_ri4rg h0OXq9dAs.9e9tfhsluOY4I4BoecXyOf4_6jHvzsnMnLtQrk9.N0ZiTIB4sRsFMWljxZ7F.PLJLw OLKAh9Wv.fQ6gTIpaOI3L4YBgjwCfmWkzqYNjoS1tvheJGmCz7N88n7s7TPnUhlqXQ7mBjSFBTWm S7dMP.LjWHJ3EGxjpVNX3AKaOAUnoNScG6529DFNnFnUXsJPS1ptp0Cy1HADDdOapiSrMic40waC iVQmAeeNUGBMOKC9ZU6j3Vkkw1kwf8uC6ks8bE1blqgwbHDcZfJUgPPvolBu79cn32GyilAfP18q F_lClXz88MLBcieqvHQLBjmGGbB2DWcgrqDlR.b21isQ4nACe2RAviZfQB45yayxw2z06qF0h4Gx 85A28qZdm4N9geEmpjER1BamENJjc1XZiuns3ViizDX3Oau67mlVSL5QtbytrkDNzlmPq4i6okGX MtVOB2TDl8IWYe15OpFZJnykpHY96o4l8FHxkPXNYdxkR9j82iN8FzysJhmGA8ZhdMA1AA8WOPAL aq1qLnsugJWal.XtKKEUSylnyJgdxv7txQ8pHCrdPAM8VJYBpuvE63BcTIgyoWF1AykKiRvGMset g4IUDv2TeG.VPAzXmGOzTT2gmItMhTkeKxwzyQAQNXZMg9GrUX2sSl_GeCHBH3XB2Gu_QAwloybJ gQwNaq9QHFixDbbw7g9OLbBM0gBtH1C.yrZoKnCo11NbwetyKREzt50tgh6q5p00oriDVL4fza3V ffKpaA19F3VAOFmKsrjLwtq5SvNfQT4Sw0WhIgdLd4VsrJPDXdMizU_jwajsQKvqYi8XklLEnBMu O5pA6c22hlUz2wJoddE5xi7wsavkwfOv2yCJlIWOOr8o77qxiLL1iOz._i.do8pv7XcpPS29r8Ok 5SSoSFQPSY5INarPOLxiqvGbXXZ44HkzydixL Received: from sonic.gate.mail.ne1.yahoo.com by sonic302.consmr.mail.ne1.yahoo.com with HTTP; Tue, 26 Jan 2021 16:59:13 +0000 Received: by smtp405.mail.bf1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 42412721e9fbd801a0cc07a7395f0bf0; Tue, 26 Jan 2021 16:59:06 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, netfilter-devel@vger.kernel.org Subject: [PATCH v24 16/25] LSM: Use lsmcontext in security_secid_to_secctx Date: Tue, 26 Jan 2021 08:40:59 -0800 Message-Id: <20210126164108.1958-17-casey@schaufler-ca.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20210126164108.1958-1-casey@schaufler-ca.com> References: <20210126164108.1958-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 f74a72867ec9..4c810ea52ab7 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2446,9 +2446,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; @@ -2702,14 +2700,14 @@ static void binder_transaction(struct binder_proc *proc, size_t added_size; security_task_getsecid(proc->tsk, &blob); - ret = security_secid_to_secctx(&blob, &secctx, &secctx_sz); + ret = security_secid_to_secctx(&blob, &lsmctx); if (ret) { return_error = BR_FAILED_REPLY; return_error_param = ret; return_error_line = __LINE__; goto err_get_secctx_failed; } - added_size = ALIGN(secctx_sz, sizeof(u64)); + added_size = ALIGN(lsmctx.len, sizeof(u64)); extra_buffers_size += added_size; if (extra_buffers_size < added_size) { /* integer overflow of extra_buffers_size */ @@ -2736,24 +2734,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; @@ -2810,7 +2806,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)) { @@ -3086,10 +3082,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 cfa19eb9533b..ead44674cea2 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -564,7 +564,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); @@ -1390,7 +1390,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 902962ea9be6..ce90ea8373d3 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(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 a73253515bc9..de2b2ecb3aea 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -998,9 +998,7 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, struct lsmblob *blob, char *comm) { struct audit_buffer *ab; - struct lsmcontext lsmcxt; - char *ctx = NULL; - u32 len; + struct lsmcontext lsmctx; int rc = 0; ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID); @@ -1011,13 +1009,12 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, from_kuid(&init_user_ns, auid), from_kuid(&init_user_ns, uid), sessionid); if (lsmblob_is_set(blob)) { - if (security_secid_to_secctx(blob, &ctx, &len)) { + if (security_secid_to_secctx(blob, &lsmctx)) { audit_log_format(ab, " obj=(none)"); rc = 1; } else { - audit_log_format(ab, " obj=%s", ctx); - lsmcontext_init(&lsmcxt, ctx, len, 0); /*scaffolding*/ - security_release_secctx(&lsmcxt); + audit_log_format(ab, " obj=%s", lsmctx.context); + security_release_secctx(&lsmctx); } } audit_log_format(ab, " ocomm="); @@ -1230,7 +1227,6 @@ static void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name) static void show_special(struct audit_context *context, int *call_panic) { - struct lsmcontext lsmcxt; struct audit_buffer *ab; int i; @@ -1254,17 +1250,15 @@ static void show_special(struct audit_context *context, int *call_panic) from_kgid(&init_user_ns, context->ipc.gid), context->ipc.mode); if (osid) { - char *ctx = NULL; - u32 len; + struct lsmcontext lsmcxt; struct lsmblob blob; lsmblob_init(&blob, osid); - if (security_secid_to_secctx(&blob, &ctx, &len)) { + if (security_secid_to_secctx(&blob, &lsmcxt)) { audit_log_format(ab, " osid=%u", osid); *call_panic = 1; } else { - audit_log_format(ab, " obj=%s", ctx); - lsmcontext_init(&lsmcxt, ctx, len, 0); + audit_log_format(ab, " obj=%s", lsmcxt.context); security_release_secctx(&lsmcxt); } } @@ -1411,20 +1405,17 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n, MAJOR(n->rdev), MINOR(n->rdev)); if (n->osid != 0) { - char *ctx = NULL; - u32 len; struct lsmblob blob; - struct lsmcontext lsmcxt; + struct lsmcontext lsmctx; lsmblob_init(&blob, n->osid); - if (security_secid_to_secctx(&blob, &ctx, &len)) { + if (security_secid_to_secctx(&blob, &lsmctx)) { audit_log_format(ab, " osid=%u", n->osid); if (call_panic) *call_panic = 2; } else { - audit_log_format(ab, " obj=%s", ctx); - lsmcontext_init(&lsmcxt, ctx, len, 0); /* scaffolding */ - security_release_secctx(&lsmcxt); + audit_log_format(ab, " obj=%s", lsmctx.context); + security_release_secctx(&lsmctx); } } diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index a7e4c1b34b6c..ae073b642fa7 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -132,8 +132,7 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) { struct lsmcontext context; struct lsmblob lb; - char *secdata; - u32 seclen, secid; + u32 secid; int err; err = security_socket_getpeersec_dgram(NULL, skb, &secid); @@ -141,12 +140,11 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) return; lsmblob_init(&lb, secid); - err = security_secid_to_secctx(&lb, &secdata, &seclen); + err = security_secid_to_secctx(&lb, &context); if (err) return; - put_cmsg(msg, SOL_IP, SCM_SECURITY, seclen, secdata); - lsmcontext_init(&context, secdata, seclen, 0); /* scaffolding */ + put_cmsg(msg, SOL_IP, SCM_SECURITY, context.len, context.context); security_release_secctx(&context); } diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 3b9cf2a1fed7..42570b8da17a 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -336,8 +336,7 @@ static int ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct) static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct) { struct nlattr *nest_secctx; - int len, ret; - char *secctx; + int ret; struct lsmblob blob; struct lsmcontext context; @@ -345,7 +344,7 @@ static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct) * security_secid_to_secctx() will know which security module * to use to create the secctx. */ lsmblob_init(&blob, ct->secmark); - ret = security_secid_to_secctx(&blob, &secctx, &len); + ret = security_secid_to_secctx(&blob, &context); if (ret) return 0; @@ -354,13 +353,12 @@ static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct) if (!nest_secctx) goto nla_put_failure; - if (nla_put_string(skb, CTA_SECCTX_NAME, secctx)) + if (nla_put_string(skb, CTA_SECCTX_NAME, context.context)) goto nla_put_failure; nla_nest_end(skb, nest_secctx); ret = 0; nla_put_failure: - lsmcontext_init(&context, secctx, len, 0); /* scaffolding */ security_release_secctx(&context); return ret; } @@ -660,15 +658,15 @@ static inline int ctnetlink_secctx_size(const struct nf_conn *ct) #ifdef CONFIG_NF_CONNTRACK_SECMARK int len, ret; struct lsmblob blob; + struct lsmcontext context; - /* lsmblob_init() puts ct->secmark into all of the secids in blob. - * security_secid_to_secctx() will know which security module - * to use to create the secctx. */ - lsmblob_init(&blob, ct->secmark); - ret = security_secid_to_secctx(&blob, NULL, &len); + ret = security_secid_to_secctx(&blob, &context); if (ret) return 0; + len = context.len; + security_release_secctx(&context); + return nla_total_size(0) /* CTA_SECCTX */ + nla_total_size(sizeof(char) * len); /* CTA_SECCTX_NAME */ #else diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index e2bdc851a477..c6112960fc73 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -173,19 +173,16 @@ static void ct_seq_stop(struct seq_file *s, void *v) static void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) { int ret; - u32 len; - char *secctx; struct lsmblob blob; struct lsmcontext context; lsmblob_init(&blob, ct->secmark); - ret = security_secid_to_secctx(&blob, &secctx, &len); + ret = security_secid_to_secctx(&blob, &context); if (ret) return; - seq_printf(s, "secctx=%s ", secctx); + seq_printf(s, "secctx=%s ", context.context); - lsmcontext_init(&context, secctx, len, 0); /* scaffolding */ security_release_secctx(&context); } #else diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index dcc31cb7f287..84be5a49a157 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -306,6 +306,7 @@ static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata) u32 seclen = 0; #if IS_ENABLED(CONFIG_NETWORK_SECMARK) struct lsmblob blob; + struct lsmcontext context = { }; if (!skb || !sk_fullsock(skb->sk)) return 0; @@ -317,10 +318,12 @@ static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata) * blob. security_secid_to_secctx() will know which security * module to use to create the secctx. */ lsmblob_init(&blob, skb->secmark); - security_secid_to_secctx(&blob, secdata, &seclen); + security_secid_to_secctx(&blob, &context); + *secdata = context.context; } read_unlock_bh(&skb->sk->sk_callback_lock); + seclen = context.len; #endif return seclen; } diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 32b6eea7ba0c..aa53a94115f4 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -375,8 +375,6 @@ int netlbl_unlhsh_add(struct net *net, struct netlbl_unlhsh_iface *iface; struct audit_buffer *audit_buf = NULL; struct lsmcontext context; - char *secctx = NULL; - u32 secctx_len; struct lsmblob blob; if (addr_len != sizeof(struct in_addr) && @@ -444,12 +442,9 @@ int netlbl_unlhsh_add(struct net *net, * security_secid_to_secctx() will know which security module * to use to create the secctx. */ lsmblob_init(&blob, secid); - if (security_secid_to_secctx(&blob, - &secctx, - &secctx_len) == 0) { - audit_log_format(audit_buf, " sec_obj=%s", secctx); - /* scaffolding */ - lsmcontext_init(&context, secctx, secctx_len, 0); + if (security_secid_to_secctx(&blob, &context) == 0) { + audit_log_format(audit_buf, " sec_obj=%s", + context.context); security_release_secctx(&context); } audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0); @@ -482,8 +477,6 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, struct audit_buffer *audit_buf; struct net_device *dev; struct lsmcontext context; - char *secctx; - u32 secctx_len; struct lsmblob blob; spin_lock(&netlbl_unlhsh_lock); @@ -510,11 +503,9 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, if (entry != NULL) lsmblob_init(&blob, entry->secid); if (entry != NULL && - security_secid_to_secctx(&blob, - &secctx, &secctx_len) == 0) { - audit_log_format(audit_buf, " sec_obj=%s", secctx); - /* scaffolding */ - lsmcontext_init(&context, secctx, secctx_len, 0); + security_secid_to_secctx(&blob, &context) == 0) { + audit_log_format(audit_buf, " sec_obj=%s", + context.context); security_release_secctx(&context); } audit_log_format(audit_buf, " res=%u", entry != NULL ? 1 : 0); @@ -553,8 +544,6 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, struct audit_buffer *audit_buf; struct net_device *dev; struct lsmcontext context; - char *secctx; - u32 secctx_len; struct lsmblob blob; spin_lock(&netlbl_unlhsh_lock); @@ -580,10 +569,9 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, if (entry != NULL) lsmblob_init(&blob, entry->secid); if (entry != NULL && - security_secid_to_secctx(&blob, - &secctx, &secctx_len) == 0) { - audit_log_format(audit_buf, " sec_obj=%s", secctx); - lsmcontext_init(&context, secctx, secctx_len, 0); + security_secid_to_secctx(&blob, &context) == 0) { + audit_log_format(audit_buf, " sec_obj=%s", + context.context); security_release_secctx(&context); } audit_log_format(audit_buf, " res=%u", entry != NULL ? 1 : 0); @@ -1106,8 +1094,6 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, struct lsmcontext context; void *data; u32 secid; - char *secctx; - u32 secctx_len; struct lsmblob blob; data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).portid, @@ -1167,15 +1153,13 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, * security_secid_to_secctx() will know which security module * to use to create the secctx. */ lsmblob_init(&blob, secid); - ret_val = security_secid_to_secctx(&blob, &secctx, &secctx_len); + ret_val = security_secid_to_secctx(&blob, &context); if (ret_val != 0) goto list_cb_failure; ret_val = nla_put(cb_arg->skb, NLBL_UNLABEL_A_SECCTX, - secctx_len, - secctx); - /* scaffolding */ - lsmcontext_init(&context, secctx, secctx_len, 0); + context.len, + context.context); security_release_secctx(&context); if (ret_val != 0) goto list_cb_failure; diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c index ef139d8ae7cd..951ba0639d20 100644 --- a/net/netlabel/netlabel_user.c +++ b/net/netlabel/netlabel_user.c @@ -85,8 +85,6 @@ struct audit_buffer *netlbl_audit_start_common(int type, { struct audit_buffer *audit_buf; struct lsmcontext context; - char *secctx; - u32 secctx_len; struct lsmblob blob; if (audit_enabled == AUDIT_OFF) @@ -102,9 +100,8 @@ struct audit_buffer *netlbl_audit_start_common(int type, lsmblob_init(&blob, audit_info->secid); if (audit_info->secid != 0 && - security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { - audit_log_format(audit_buf, " subj=%s", secctx); - lsmcontext_init(&context, secctx, secctx_len, 0);/*scaffolding*/ + security_secid_to_secctx(&blob, &context) == 0) { + audit_log_format(audit_buf, " subj=%s", context.context); security_release_secctx(&context); } diff --git a/security/security.c b/security/security.c index 904ae6c46be0..aab6d3f86e4a 100644 --- a/security/security.c +++ b/security/security.c @@ -2252,18 +2252,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 Tue Jan 26 16:41:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12049633 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.9 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNWANTED_LANGUAGE_BODY, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 59302C433DB for ; Wed, 27 Jan 2021 10:24:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1D7912064B for ; Wed, 27 Jan 2021 10:24:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S313137AbhAZXB7 (ORCPT ); Tue, 26 Jan 2021 18:01:59 -0500 Received: from sonic307-15.consmr.mail.ne1.yahoo.com ([66.163.190.38]:46630 "EHLO sonic307-15.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389507AbhAZRO5 (ORCPT ); Tue, 26 Jan 2021 12:14:57 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1611681250; bh=9YoXmcR9GfEUUKOi9Heh7nYvpBpiCcLdyEdcPUGrvg8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=I7zFX8zwEHt+OaJ+VotHtds1BryupXIQQqLgjjTZBLImW5H9kKW9FTv2HjKT+fi14EeEuBv4jc8MN28ZGhvzZ8SOEO/me+6ayQ9ZbmyyxUmb0S1IA222g3XNzbxWKSQXfBYVzra6g8W7qxMfIBGrT4JgTQQJEXPBtZnyRwbpKI5eGHBLroweXA0v3tC/7zdmEKAJ5rpWOwa4ECRjP6H5YyfMYBGFZX8QYCP9m6moE6Ufy2kDzc50GS4ktXwpJxYFx6mrIrqYhKiQSAYiepjK+RRSl+uwilHNxcey5fRoPIzsn01YrbnpWRzluZWc7H60PK6CcB9Td7FWv+CVI4lr9g== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1611681250; bh=ui2nnxnCoPJ7ZbdXTaYsSexm6qVx+01HTFEQGbE4fNP=; h=From:To:Subject:Date:From:Subject:Reply-To; b=GvISRg+SPs/V74LHdW5+fa8ah28zQ758duGMGOP8pwmlRfwJMADefy5s66NWpSPtsWFl0fZdVsBB3A2SRrZDDk3J60tiEAqPbYkb3AbMyVeCmF/++0CVh2gm9SfNcvuBGVNKjPKlPJ71X31NBr7+5ThYbkEMKP94xuFLeEHoVi3HVMfnlKmWDeBdodTozf/8YHZGsoSEWWlBl75QHzdhk9v516+diaUzNqgmTNfs83pAmynNAPHmqFwiAf6F7FGGQkYbvqA+83zokYgG8oFF3kRuinW6EXveZsKwioiBE0wlMgtCOJldy30Y1MiRXu4kjyIoXqsQK/HQQnXgIlz0Pw== X-YMail-OSG: iyNXdgMVM1l5kVouslgwArlYw_zQUwYhnjGiVNgegINh71EjMeP6nBim2DQHaQn mrPBuQCiT595uHdwCAgFEUjwvaIy573GdC_VwgtjyMQKK6eKCGIeNq2xjsJcvrE82ZDWwmIGt6Mw LshpITZ3KfjsIxt4l75SI7HT1_N99.SfCEAuu_uxYXKbbjotmEiwO5qKmajbcWvTyaPbATPXpFzG jbBweaV5x9SZqylU7t6U9GM6dq4uDpp0tVjlOYtvK9iHf_U6wait.1.fAFz2eFo_j01sjUOP91wn P.ujPJpOH9TXCzNvDfO8xwRRAbBCkl1TATU0IWPeorZ90cq5wMYNXhQhfj8tExD3Gmn8IfDVX_bx 75Cypv_AemvzXQ4sEon8ZirkLBVNtHZopGA66PfZPwGLor2.I7lQZ.mbTVZf4diwCczPRnc3Qfwi QWOSdfPYv16RByCaKujEXvr_I5vItVEblV_pgcw7EdkBLLJDar1skC5txxyAY9gPUONelZmPsH9_ ZN_UCW4SdXItrY1VDcwkbWL6VLL3iZ0q4hc6NQ026lS40VaW0aAexEUvgeNyw2LDvgZ_HE1L5joI 200XNHLQvvIeKMea1K7bzEj0LPLIQi5ITTMfc6wrf68GjUJU93D2.GBaNVfj9.WGl786A5Xe_QrI dhyNIl8qzDNiGF_b.KECjHfaqwuT9wMXqUmv_kYQW0Z2kokflldmgHW1ORkqbincjJIEfL.iHidQ _5DOYJ1B48iGRoWw5VOmHhGEZ.HZD9Q7lJLMxzuehpGXEdOusMKzKKJXFcJ0LPLrytKUe9.q1O_2 qO.xNXJKFyPl5YXxm1unN.8PzL.8.vxnl8UU4ZFxfeQHZK6ZVhgDLgDeVIu.P4S3FhM62P2ppSl2 q_WLlyIHPaQzj3pf75ZquiyaVI6ynq99_REDySB24h83Q7gbaMnx3TE6w8OPq_V02IizduuZGs_S If_ibaIpYaWzgRAVisy5_v6feR7H6uY5DrtEb5JO2TJS.57CEjofKhJX_FP7NsCvq4NGN6WucIsj kRxqPgDs7QlwFDYCSsddZCIuke_bBvzy2ZMw0XZYmSXcT7m1ic9cO6dFDCu81Y4A_3b40dGiY8Qd KlHOn9vwtiBdfMXbMvnW7FPWZLivVm_wr4kbicAw9VR7BanJpU4nhHBR03lBofOQR75gA5aZUiUJ FH5Ra5jLNwxS5uuPYcpCKytVGytaO9Zj1atoy0zGlh95t9PrF9WgqAJ7TnKktir0NuyqYkEKt6R1 KJolTQqCv_0EzCECyjKyzT0jbDrwqQhongr9DYgjwqr_Qw.Dwyp8cF_248f9bEpwBSSDjpe4w2vn P1lbIMtnGGi7WIRorncBqZYFofQa0ORSJGHkdLUt7KFBA.DWM7cUO36yyo9CsLHA3tFvc.6WH3Rq BzRdTn1tuj1J4hxkpWU8CkV.ejbVCsJOFogjpquGsyEZ7T7YvVFHc6r8.D3wdyfKIaIh7wClDN8s 7f04EkKVSTvTYNMm1Oj8Yg2ON6ljCe0LLGXxNP5zIw5dhxUjhxfZCCHfrJWS6V30SdpKrbatBglU uorp11tqBMSvh1P8nupoJq6tI3yYxVxEmusnHWHIt0X2e.ntgchDLkKzprxN7ekQajzJGtA34FEy tXd6s.b9BzlqUz0CYUCxHPcrVL_jgIvTjqHdub2sT1GAKFDOwHL3rIA8N6Hf.Im76eeySbmOXioq fEw6dx_H1RdMuB0yb1ss6OoRJrWbpSMmSQro95QEZjrfeMvau_s2qB8o9pQ1BOQ101znya1iTq7L u09eVKpZPgetMxzBmL2_6MfqFShjOhLRuFa7ujpUe9qYgGi5QD_0Y4gt7bYYQsFhNvQIEMCIg4XE POO1NUJB1BwL9mlMOCdMsQHOMNGqdj2hWyVt5x0y4BIAEvviSdc57vZ3JzPycpPz5IUpexXYfKVQ h1Jrim3g7SvZUxxCdzv0VcEnTICfNhu3DN4Rz_7TZxQxtnkOW2X3iZ.QeyiaRmQXElCIhLz3Ml0c GXUt8Nw.5Eq2WLoyxnSRvbnJwbDw9OrONfGYMhxY9b7isfiK580qTeigB3MfiOhGNuiBogVoV0Iw ph9QK1LoWCAKvYNqIHhxd0uaH5t8XU4KrJ.MbH71a.ZUu2roLfZ20vmPwDrv6y2A54xXdzTOWLGl VSB3fKFCM9pAYgTzdPBrGjpDMXbcEtIy19lLPO5GKgEgzWxbMEj0jpe6xAfgHqwHwbM7a2Yd8Vjb 78D22yqjs5jBlQU4thVMB4yVafSA2iHSFjQimV4MFoD2Au.XhGXoh6o7y9hI2a06Y65Cxjfibrhg 3rE3MiVO.gvgYnbUYmsAUMDao1vuMTYSVyG9EB2KndCYLlbx__4sPxvEsUJgfsECoMJ2xMJWNbJw s2QuHZDDVc1_wY.GAV4nxvwxgK2g2Vigxyzdr9BUuQGFoDxEWbtlCgVaRnDqn6Met3lxtfr3_raT Wq4J3UYx0fieu5swyDAtNIx9YocFJ_7pzzKa5Lj4fiWRWfr235T6oTlq07lz6Com_oqWsNPBykVx D7ZyNnwvdMkbYwp3rc8RnWhfRu6AMNQ0mzP8dD4jg2Zl0EXI48psQnUNN12t.wYojcYMl28hwF_b Q9wXc1LZiiSm.EuQq1KxYb3SzXA4307t_OIo4GwgKw.yDRv_zY2ocn8nKR_DFMzijdswcw3m05yV 9URyOb.AwBdahIlCSPbAhWUEsM251Zj2HIQsR48C4160SS.0ArO18YVNqeIVXIKO8irrRvQGThVz s4GpieIWnmU4i75yjykIhK2ezHpRG2dknt1m3._hxQtUYwrJc2mUpqx3sCm5g9vZENafv.pJZTTX rRI30Tx7tXYmeQkc_dfb34PBVEQ37YldBFhnS.MzPA2l6xv_LMfMPnW3xHJ6yoUinI1EBGRbn7e3 JrFF7hXhZJxE274wCVbedHLWb6ENfiG0W2KtZqAOf.Cdt9my.M7Tq9rOIqTKFrOcIQPSGiqdKclp ij3wPs2.goDZ4GDOF2qPi2__eWiRNBEh1rPWC7gX_CnNWl7rcaUpdUeaVhaibDB3oH2uTRhkXxpk 0yM1GUIheVP2r7FWMzZUmTO4ugiDYfKuXBCxcJom0nAZ6Gus4.uxmQ_Cc4yIrOJaByE6HiooxP3a YWUxmbNVisml33CCB3h3PUmuchQTuizCIBzbKUFLBQ9uJrAFvZ0OM0mfirybxVNPNdndGg4X9.u8 SEEreVft5Cjxw59.YdvZQgKr6KUfh74rpktxIvp42O404KnihkWpnARwDbAfFHZ3CWhXjF_ndrZo 7YdKjstm5rrlxRlrXR9CZraxqFELqytB5t6pEGHVvxaE- Received: from sonic.gate.mail.ne1.yahoo.com by sonic307.consmr.mail.ne1.yahoo.com with HTTP; Tue, 26 Jan 2021 17:14:10 +0000 Received: by smtp406.mail.bf1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 95bfae2557e9d921feb8a05f30947867; Tue, 26 Jan 2021 17:01:22 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov, linux-kernel@vger.kernel.org, Pablo Neira Ayuso , netdev@vger.kernel.org, netfilter-devel@vger.kernel.org Subject: [PATCH v24 18/25] LSM: security_secid_to_secctx in netlink netfilter Date: Tue, 26 Jan 2021 08:41:01 -0800 Message-Id: <20210126164108.1958-19-casey@schaufler-ca.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20210126164108.1958-1-casey@schaufler-ca.com> References: <20210126164108.1958-1-casey@schaufler-ca.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Change netlink netfilter interfaces to use lsmcontext pointers, and remove scaffolding. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley Acked-by: Pablo Neira Ayuso Signed-off-by: Casey Schaufler Cc: netdev@vger.kernel.org Cc: netfilter-devel@vger.kernel.org --- net/netfilter/nfnetlink_queue.c | 37 +++++++++++++-------------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 84be5a49a157..0d8b83d84422 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -301,15 +301,13 @@ static int nfqnl_put_sk_uidgid(struct sk_buff *skb, struct sock *sk) return -1; } -static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata) +static void nfqnl_get_sk_secctx(struct sk_buff *skb, struct lsmcontext *context) { - u32 seclen = 0; #if IS_ENABLED(CONFIG_NETWORK_SECMARK) struct lsmblob blob; - struct lsmcontext context = { }; if (!skb || !sk_fullsock(skb->sk)) - return 0; + return; read_lock_bh(&skb->sk->sk_callback_lock); @@ -318,14 +316,12 @@ static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata) * blob. security_secid_to_secctx() will know which security * module to use to create the secctx. */ lsmblob_init(&blob, skb->secmark); - security_secid_to_secctx(&blob, &context); - *secdata = context.context; + security_secid_to_secctx(&blob, context); } read_unlock_bh(&skb->sk->sk_callback_lock); - seclen = context.len; #endif - return seclen; + return; } static u32 nfqnl_get_bridge_size(struct nf_queue_entry *entry) @@ -398,12 +394,10 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, struct net_device *indev; struct net_device *outdev; struct nf_conn *ct = NULL; + struct lsmcontext context = { }; enum ip_conntrack_info ctinfo; struct nfnl_ct_hook *nfnl_ct; bool csum_verify; - struct lsmcontext scaff; /* scaffolding */ - char *secdata = NULL; - u32 seclen = 0; size = nlmsg_total_size(sizeof(struct nfgenmsg)) + nla_total_size(sizeof(struct nfqnl_msg_packet_hdr)) @@ -469,9 +463,9 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, } if ((queue->flags & NFQA_CFG_F_SECCTX) && entskb->sk) { - seclen = nfqnl_get_sk_secctx(entskb, &secdata); - if (seclen) - size += nla_total_size(seclen); + nfqnl_get_sk_secctx(entskb, &context); + if (context.len) + size += nla_total_size(context.len); } skb = alloc_skb(size, GFP_ATOMIC); @@ -604,7 +598,8 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, nfqnl_put_sk_uidgid(skb, entskb->sk) < 0) goto nla_put_failure; - if (seclen && nla_put(skb, NFQA_SECCTX, seclen, secdata)) + if (context.len && + nla_put(skb, NFQA_SECCTX, context.len, context.context)) goto nla_put_failure; if (ct && nfnl_ct->build(skb, ct, ctinfo, NFQA_CT, NFQA_CT_INFO) < 0) @@ -632,10 +627,8 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, } nlh->nlmsg_len = skb->len; - if (seclen) { - lsmcontext_init(&scaff, secdata, seclen, 0); - security_release_secctx(&scaff); - } + if (context.len) + security_release_secctx(&context); return skb; nla_put_failure: @@ -643,10 +636,8 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, kfree_skb(skb); net_err_ratelimited("nf_queue: error creating packet message\n"); nlmsg_failure: - if (seclen) { - lsmcontext_init(&scaff, secdata, seclen, 0); - security_release_secctx(&scaff); - } + if (context.len) + security_release_secctx(&context); return NULL; } From patchwork Tue Jan 26 16:41:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12049631 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6F69BC43381 for ; Wed, 27 Jan 2021 10:22:06 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2C40B20731 for ; Wed, 27 Jan 2021 10:22:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S313916AbhAZXCm (ORCPT ); Tue, 26 Jan 2021 18:02:42 -0500 Received: from sonic302-28.consmr.mail.ne1.yahoo.com ([66.163.186.154]:38584 "EHLO sonic302-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390063AbhAZRQU (ORCPT ); Tue, 26 Jan 2021 12:16:20 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1611681329; bh=7b7li26OpOiFhUePWqDmaQRC8tZucSaraGLOIGsiglg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=DTh7DO4cJied5p2yl4Nf3O8Gz0Ukw6zV8umMAK1GdFGT0XiD+RILSAnlAYHTBmUPU7RA8g2cUCp3sznpEOtyt3hFt07gGfQB72b2CgzGi7qz3M0YcAH1NZl8yi0VM0Q+gjWJNsfq6LJH+BdZMjqY+iEwu5gwpQIIjpWEsGvsZBYJ5rmcuOzQavDmsA+9dL/Usac0doQWZtCf89ploeIcGYR65XxOVTsS29CoZ5PKcafcH9thLw7VVvzhej6z9/sMdeQUUoG4BCOdG6igBdln5sF3yxhjC/4tfH4EKLnaNWury/9vZ3cku8Ys0hbkq/TJDcB7ODw7PWYRITJcaqw7hA== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1611681329; bh=pCy631fSs6QeTupU2KQNHWL8H9HBhGRDv2YEyFlOs7l=; h=From:To:Subject:Date:From:Subject:Reply-To; b=ervn4RG1JoTI+cFL1zQxOsZPkGh5WaxHC3w2Lud20Zn6dAkR7/mTNn+wqc4N/O+6amWOgz+zA8MiQh4nw7Om+H2T63ig/Q9S/ojaw7sMJyqwHK+vTJJdX/fm6zwl+yx4UHu+ZdG/p8krJJF0yho/HkZA+6BV4xSNNEPtbyp/xhHKk+QsMtIXo+ju0iXumyDGxVgU5jwgMeVbTOoOxt7ZQUDiRKKUhQnqICrlC2SVmZAueUVIctdxccE4hfwGbb66n5za8+W34qNTu0+1ihYxaq7wkF5NklRg9QCxYg/sDXWssGp1jzhp8TFgAXqDbTCvbk6gVBo1gy/RZezXdPYCcQ== X-YMail-OSG: UFP642AVM1nAQM3mp6LAhbVKtjzTontXTuI7R3nImd6QBXqlgUuygw6fyk7vlgp y0jBV9622mgo553sit0PNNXxBcw7HZIGMQSew7ZHqD10y9DjHdaxiSf6nZW9QJ8.cIhqMFUY3eL6 5zV3ySPEr5R1KFGhu5r5HUB0BPxmAzUUZh3NhklXAg1xuhsA.RpS1ZInQx4OwMyF87TNontmIiSV yNXtb2cCsbkXbrPoWb2DJEG4yIiJfzx3QkOBEQbjGnEcDvIQdi6Gav.NmDyC2VkL_jdoU9IMp2hx gEsJPHWjy_x4G.61sK7GdrP5I9FCML2_gwexVES4M3GnINBWXtx3Z9d_N.jG9bRJlCn5vUEUWQSJ z4oTyVQaxSRvPvkIRHTYx75KuMPgJs39FqdkLMVT2OOGSxbJIcBiuDkXD1IzvD2KW0IZyt60t2T. BWM8OdjO1wJ9Pzf0PNhFsDcH39ySPYLZQ2sz1UGwiC0JOppl7CXVr2GrM5Gcd8jucslFftog6nUT 1t8Qw5EAKafdv8ApUDMD9FrEwE2ZF7EHSAIWr9RzVcUSBogi4QkbfUwOCUA87.lXh5DnNsN8gA0x 48S_50NRU1_3PQEz4MnA7WRi04k_Np4qd7gQ7oqjxUfrAQy1Ba7dqTJJJ9cGorEvEJBFahRpDsvl Gstv1SyZEB7Z3JkYS.zPVKj6pReL5_T5XXB6qrsBS_8RF70XNBGeibfVaaHbOw2X5ub8wExRpvhj 6CyBj2kQIQxsA2fp669ooCwCUkGmXM5.1bzEC0_rcrzZlGAZeN_WSlISypHs3U.cHy39UnAVOL.S SGDyCM3wzFNZskTypHfSia5ljwA45pgZFUhhzotUl6BTokgbi7Ns6v5NapNwSII4IKIIJMrHKoEb jF7cXU3HlemRw5B0CkOFbSnBoWvC.LsWmOkUbQiUk80TFaAYiao7.z.U1uhopkWgoNMagSInAEmu siYpVE5DXFG4MjG4STwi5GxGHsAEWFJn.16UpKDofClnjtMPUwIj_3.Y0q12hU_ZiqfstwPoD0PH 6Jgl8vNW3DSHgGELIH1DJ644lsfKgYVs5PelSVWMpOsxpdTp8zdTOcUvfQHoOquo0Ny1Ll2YqWJE jzLioRQHay6fws7OPJEaamNSG_4RUVzlQDpFAyDGTlrcl44oQUiYVIBKWLrjeOvSeITeV7HuCB3m bag.94GXkLLow3CLZUm2HrEKRTQufCj8JVZv6E233B05v9whVVZHOZCA0SmjPHJsWNzL6eT0a3oP S1SuXs6THFNmS1DVDubYT5jk_gg3XuHfrVSE6JFlR7BB5B1oHcU0xw5yXV6bdocIOFptFzhzssdy Dyz4zYMci.vvQq7r4YUJDBE2JT3ZZCiwgBAkhkgskV3GE_gwRM7Xj2EDJSxJME8nclmk2elhAGLx I2NsRXLRZ86PvHCBj5.95LgCSnpQeM1QcaJzXpubqogPsnnKrlmh5Uybpc3A3HeaVaTLA4kPhoZj nQPV3O4VXmMXnH2.Nc09FXtY5cFnnqVmUzbDdvBUlwGW.WSeqcWlJteDVK3dTCDAEpcVvMhMeW.3 i5B1O5mDGevvf0zzlZ3cGPZr5.UGOPywkheYQjRmj1Nw9Pzfyo6P8.SaFyMcSjm_gEnNSOpaSEK. e6BvqEdo_alLwhdVb3LtzAYtLS8ZZz3QB0xhnKEnKN3HYHGntLOGWcJ8725tdO.mmwo3fP1sv8hD SnuBP3shjW369mz3PCI4DJl3zBHp3.hatxl.wYo1NjM83knapUNHxR9j4R482xxeVuTo2LS3f_Bj n93awo1Hdn0N44pB8XTJdIS53nOnbZENOrWDJJjE_FNO1K72puXC3teVUB9qUknr6tbJJK7jJBeP J1Q7U19iscW9VOSPHAkLEYhbpezOvfU_QbzGitJwgDpCQ2gF.LE89yxAMrcpdmIdDsYUyeSRGKHR yEwYNCVh0TL3AEybW0suNBFc0Pywkfj5kj7novfQAi9CQ1.oK_bSJsMb.GLP5ywt3SFQLsZBHsK9 _FFjJjRSxw4ex6rS.0NCyDIf4QhsQYu4xdpmUKc0mtnSwagFUHLKmHpInscJ3eAQ9qUixd0QQWLd pbCYxH2loy6VPLcc1vwSJsAr6JoIH5VlTwV1tJmPcgaQci2oNzH9woFZoftz54QcSesXZxCBwOVR Lt6ZnqrhtGcM1maHlOKjkfoUai.xVkrrB68gEiqDGBW85YuSJOL_o2pEmT44TJ1Sr_3syAjCJbn. jf7o57UuQATivWG14RemuQB1A_YT2J9vw5B3ROCIq3kYpluDenk0vRp0sKUxhzJ0XCP54rnAEbrq pZu4yJ_h_JIMO7Mjfsbfwf.Iq.tD8F_YIy9dCSJ5l29_K5tG_nzb_MB04xMZnRlhdbp0E1_bbuZH JKczem2FSVntwCqQdDR902yZJZ0hJa6pb6fg9AdTpFmDBUBQ_GzKJ8sBb1O_uJBW.u_3r9h_mf7_ n7TRSx_h.Rmc66dsZnP9_FpFBA1z2YfyHqCHPXe4T6A2fZ_ySv33ceVLjLxWjFQ.FEXEwk4wt4Ia OjZkSvb1P6p9TOwoGLV5dYdn7b_lMveyE55wpR9JBXHkEz12nm9a3Ukzfho9Bg_vqLIRsMD86hZF Qn7h3iUmRM8KDJLUWII_BEJRSs8aC9K7QeB8fpJYoEOwpIbCmQmbf3Lzc4JZf14dX0Ul6Le7NLse JULhQeNLXSGNCz9zDPnuUAY.1MsJ2NelyDM56lJEgzI0C503nRwHba8GV7YICBxzQ.JU5sRi2HsB fiAp1wMRYB37h08iaRjGOooAlT0Zq24a3hJPazopiNYZrUBsiXo_gzk3.zHmmQseSqvfUQvcuy2s Bs2uHYZntw1QklDGqaLIUY0vqthcBClhv_7T86FQ.OHEiWN74M4FobAATpamZpSEBtlKOTLzx5Se kEHXspb7hb5yl5nZIneRytdVdkRmYt1v2pGOgtYiBTyEtt._QIqeoo.V44bFbj3_p9ucuVoUbfwn FYXzFW1p829._s40s18fYGHdh_HIuNyIFEtdFex7COoWYtHs2eF3dkxLE2qRZDrKLZELl121jsPo uMBf7JzE3bhI2XdHfmg8GGL6rXazZb7PzuBStg8USnN6VPrxpoP9Rne.IOhbGQ11xOUsTCLkn5HA M4f01lY8V1nZ6bJHyGPHhRiE- Received: from sonic.gate.mail.ne1.yahoo.com by sonic302.consmr.mail.ne1.yahoo.com with HTTP; Tue, 26 Jan 2021 17:15:29 +0000 Received: by smtp424.mail.bf1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 6385815b14939a264fb9c6892e640443; Tue, 26 Jan 2021 17:02:31 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov, linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH v24 19/25] NET: Store LSM netlabel data in a lsmblob Date: Tue, 26 Jan 2021 08:41:02 -0800 Message-Id: <20210126164108.1958-20-casey@schaufler-ca.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20210126164108.1958-1-casey@schaufler-ca.com> References: <20210126164108.1958-1-casey@schaufler-ca.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Netlabel uses LSM interfaces requiring an lsmblob and the internal storage is used to pass information between these interfaces, so change the internal data from a secid to a lsmblob. Update the netlabel interfaces and their callers to accommodate the change. This requires that the modules using netlabel use the lsm_id.slot to access the correct secid when using netlabel. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley Acked-by: Paul Moore Signed-off-by: Casey Schaufler Cc: netdev@vger.kernel.org --- include/net/netlabel.h | 8 +-- net/ipv4/cipso_ipv4.c | 26 ++++++---- net/netlabel/netlabel_kapi.c | 6 +-- net/netlabel/netlabel_unlabeled.c | 79 +++++++++-------------------- net/netlabel/netlabel_unlabeled.h | 2 +- security/selinux/hooks.c | 2 +- security/selinux/include/security.h | 1 + security/selinux/netlabel.c | 2 +- security/selinux/ss/services.c | 4 +- security/smack/smack.h | 1 + security/smack/smack_access.c | 2 +- security/smack/smack_lsm.c | 11 ++-- security/smack/smackfs.c | 10 ++-- 13 files changed, 68 insertions(+), 86 deletions(-) diff --git a/include/net/netlabel.h b/include/net/netlabel.h index 43ae50337685..73fc25b4042b 100644 --- a/include/net/netlabel.h +++ b/include/net/netlabel.h @@ -166,7 +166,7 @@ struct netlbl_lsm_catmap { * @attr.mls: MLS sensitivity label * @attr.mls.cat: MLS category bitmap * @attr.mls.lvl: MLS sensitivity level - * @attr.secid: LSM specific secid token + * @attr.lsmblob: LSM specific data * * Description: * This structure is used to pass security attributes between NetLabel and the @@ -201,7 +201,7 @@ struct netlbl_lsm_secattr { struct netlbl_lsm_catmap *cat; u32 lvl; } mls; - u32 secid; + struct lsmblob lsmblob; } attr; }; @@ -415,7 +415,7 @@ int netlbl_cfg_unlbl_static_add(struct net *net, const void *addr, const void *mask, u16 family, - u32 secid, + struct lsmblob *lsmblob, struct netlbl_audit *audit_info); int netlbl_cfg_unlbl_static_del(struct net *net, const char *dev_name, @@ -523,7 +523,7 @@ static inline int netlbl_cfg_unlbl_static_add(struct net *net, const void *addr, const void *mask, u16 family, - u32 secid, + struct lsmblob *lsmblob, struct netlbl_audit *audit_info) { return -ENOSYS; diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index 471d33a0d095..1ac343d02b58 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c @@ -106,15 +106,17 @@ int cipso_v4_rbm_strictvalid = 1; /* Base length of the local tag (non-standard tag). * Tag definition (may change between kernel versions) * - * 0 8 16 24 32 - * +----------+----------+----------+----------+ - * | 10000000 | 00000110 | 32-bit secid value | - * +----------+----------+----------+----------+ - * | in (host byte order)| - * +----------+----------+ - * + * 0 8 16 16 + sizeof(struct lsmblob) + * +----------+----------+---------------------+ + * | 10000000 | 00000110 | LSM blob data | + * +----------+----------+---------------------+ + * + * All secid and flag fields are in host byte order. + * The lsmblob structure size varies depending on which + * Linux security modules are built in the kernel. + * The data is opaque. */ -#define CIPSO_V4_TAG_LOC_BLEN 6 +#define CIPSO_V4_TAG_LOC_BLEN (2 + sizeof(struct lsmblob)) /* * Helper Functions @@ -1469,7 +1471,11 @@ static int cipso_v4_gentag_loc(const struct cipso_v4_doi *doi_def, buffer[0] = CIPSO_V4_TAG_LOCAL; buffer[1] = CIPSO_V4_TAG_LOC_BLEN; - *(u32 *)&buffer[2] = secattr->attr.secid; + /* Ensure that there is sufficient space in the CIPSO header + * for the LSM data. */ + BUILD_BUG_ON(CIPSO_V4_TAG_LOC_BLEN > CIPSO_V4_OPT_LEN_MAX); + memcpy(&buffer[2], &secattr->attr.lsmblob, + sizeof(secattr->attr.lsmblob)); return CIPSO_V4_TAG_LOC_BLEN; } @@ -1489,7 +1495,7 @@ static int cipso_v4_parsetag_loc(const struct cipso_v4_doi *doi_def, const unsigned char *tag, struct netlbl_lsm_secattr *secattr) { - secattr->attr.secid = *(u32 *)&tag[2]; + memcpy(&secattr->attr.lsmblob, &tag[2], sizeof(secattr->attr.lsmblob)); secattr->flags |= NETLBL_SECATTR_SECID; return 0; diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c index 5e1239cef000..bbfaff539416 100644 --- a/net/netlabel/netlabel_kapi.c +++ b/net/netlabel/netlabel_kapi.c @@ -196,7 +196,7 @@ int netlbl_cfg_unlbl_map_add(const char *domain, * @addr: IP address in network byte order (struct in[6]_addr) * @mask: address mask in network byte order (struct in[6]_addr) * @family: address family - * @secid: LSM secid value for the entry + * @lsmblob: LSM data value for the entry * @audit_info: NetLabel audit information * * Description: @@ -210,7 +210,7 @@ int netlbl_cfg_unlbl_static_add(struct net *net, const void *addr, const void *mask, u16 family, - u32 secid, + struct lsmblob *lsmblob, struct netlbl_audit *audit_info) { u32 addr_len; @@ -230,7 +230,7 @@ int netlbl_cfg_unlbl_static_add(struct net *net, return netlbl_unlhsh_add(net, dev_name, addr, mask, addr_len, - secid, audit_info); + lsmblob, audit_info); } /** diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index aa53a94115f4..3befe0738d31 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -66,7 +66,7 @@ struct netlbl_unlhsh_tbl { #define netlbl_unlhsh_addr4_entry(iter) \ container_of(iter, struct netlbl_unlhsh_addr4, list) struct netlbl_unlhsh_addr4 { - u32 secid; + struct lsmblob lsmblob; struct netlbl_af4list list; struct rcu_head rcu; @@ -74,7 +74,7 @@ struct netlbl_unlhsh_addr4 { #define netlbl_unlhsh_addr6_entry(iter) \ container_of(iter, struct netlbl_unlhsh_addr6, list) struct netlbl_unlhsh_addr6 { - u32 secid; + struct lsmblob lsmblob; struct netlbl_af6list list; struct rcu_head rcu; @@ -220,7 +220,7 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex) * @iface: the associated interface entry * @addr: IPv4 address in network byte order * @mask: IPv4 address mask in network byte order - * @secid: LSM secid value for entry + * @lsmblob: LSM data value for entry * * Description: * Add a new address entry into the unlabeled connection hash table using the @@ -231,7 +231,7 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex) static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface, const struct in_addr *addr, const struct in_addr *mask, - u32 secid) + struct lsmblob *lsmblob) { int ret_val; struct netlbl_unlhsh_addr4 *entry; @@ -243,7 +243,7 @@ static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface, entry->list.addr = addr->s_addr & mask->s_addr; entry->list.mask = mask->s_addr; entry->list.valid = 1; - entry->secid = secid; + entry->lsmblob = *lsmblob; spin_lock(&netlbl_unlhsh_lock); ret_val = netlbl_af4list_add(&entry->list, &iface->addr4_list); @@ -260,7 +260,7 @@ static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface, * @iface: the associated interface entry * @addr: IPv6 address in network byte order * @mask: IPv6 address mask in network byte order - * @secid: LSM secid value for entry + * @lsmblob: LSM data value for entry * * Description: * Add a new address entry into the unlabeled connection hash table using the @@ -271,7 +271,7 @@ static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface, static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface, const struct in6_addr *addr, const struct in6_addr *mask, - u32 secid) + struct lsmblob *lsmblob) { int ret_val; struct netlbl_unlhsh_addr6 *entry; @@ -287,7 +287,7 @@ static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface, entry->list.addr.s6_addr32[3] &= mask->s6_addr32[3]; entry->list.mask = *mask; entry->list.valid = 1; - entry->secid = secid; + entry->lsmblob = *lsmblob; spin_lock(&netlbl_unlhsh_lock); ret_val = netlbl_af6list_add(&entry->list, &iface->addr6_list); @@ -366,7 +366,7 @@ int netlbl_unlhsh_add(struct net *net, const void *addr, const void *mask, u32 addr_len, - u32 secid, + struct lsmblob *lsmblob, struct netlbl_audit *audit_info) { int ret_val; @@ -375,7 +375,6 @@ int netlbl_unlhsh_add(struct net *net, struct netlbl_unlhsh_iface *iface; struct audit_buffer *audit_buf = NULL; struct lsmcontext context; - struct lsmblob blob; if (addr_len != sizeof(struct in_addr) && addr_len != sizeof(struct in6_addr)) @@ -408,7 +407,7 @@ int netlbl_unlhsh_add(struct net *net, const struct in_addr *addr4 = addr; const struct in_addr *mask4 = mask; - ret_val = netlbl_unlhsh_add_addr4(iface, addr4, mask4, secid); + ret_val = netlbl_unlhsh_add_addr4(iface, addr4, mask4, lsmblob); if (audit_buf != NULL) netlbl_af4list_audit_addr(audit_buf, 1, dev_name, @@ -421,7 +420,7 @@ int netlbl_unlhsh_add(struct net *net, const struct in6_addr *addr6 = addr; const struct in6_addr *mask6 = mask; - ret_val = netlbl_unlhsh_add_addr6(iface, addr6, mask6, secid); + ret_val = netlbl_unlhsh_add_addr6(iface, addr6, mask6, lsmblob); if (audit_buf != NULL) netlbl_af6list_audit_addr(audit_buf, 1, dev_name, @@ -438,11 +437,7 @@ int netlbl_unlhsh_add(struct net *net, unlhsh_add_return: rcu_read_unlock(); if (audit_buf != NULL) { - /* lsmblob_init() puts secid into all of the secids in blob. - * security_secid_to_secctx() will know which security module - * to use to create the secctx. */ - lsmblob_init(&blob, secid); - if (security_secid_to_secctx(&blob, &context) == 0) { + if (security_secid_to_secctx(lsmblob, &context) == 0) { audit_log_format(audit_buf, " sec_obj=%s", context.context); security_release_secctx(&context); @@ -477,7 +472,6 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, struct audit_buffer *audit_buf; struct net_device *dev; struct lsmcontext context; - struct lsmblob blob; spin_lock(&netlbl_unlhsh_lock); list_entry = netlbl_af4list_remove(addr->s_addr, mask->s_addr, @@ -497,13 +491,8 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, addr->s_addr, mask->s_addr); if (dev != NULL) dev_put(dev); - /* lsmblob_init() puts entry->secid into all of the secids - * in blob. security_secid_to_secctx() will know which - * security module to use to create the secctx. */ - if (entry != NULL) - lsmblob_init(&blob, entry->secid); if (entry != NULL && - security_secid_to_secctx(&blob, &context) == 0) { + security_secid_to_secctx(&entry->lsmblob, &context) == 0) { audit_log_format(audit_buf, " sec_obj=%s", context.context); security_release_secctx(&context); @@ -544,7 +533,6 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, struct audit_buffer *audit_buf; struct net_device *dev; struct lsmcontext context; - struct lsmblob blob; spin_lock(&netlbl_unlhsh_lock); list_entry = netlbl_af6list_remove(addr, mask, &iface->addr6_list); @@ -563,13 +551,8 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, addr, mask); if (dev != NULL) dev_put(dev); - /* lsmblob_init() puts entry->secid into all of the secids - * in blob. security_secid_to_secctx() will know which - * security module to use to create the secctx. */ - if (entry != NULL) - lsmblob_init(&blob, entry->secid); if (entry != NULL && - security_secid_to_secctx(&blob, &context) == 0) { + security_secid_to_secctx(&entry->lsmblob, &context) == 0) { audit_log_format(audit_buf, " sec_obj=%s", context.context); security_release_secctx(&context); @@ -923,14 +906,8 @@ static int netlbl_unlabel_staticadd(struct sk_buff *skb, if (ret_val != 0) return ret_val; - /* netlbl_unlhsh_add will be changed to pass a struct lsmblob * - * instead of a u32 later in this patch set. security_secctx_to_secid() - * will only be setting one entry in the lsmblob struct, so it is - * safe to use lsmblob_value() to get that one value. */ - - return netlbl_unlhsh_add(&init_net, - dev_name, addr, mask, addr_len, - lsmblob_value(&blob), &audit_info); + return netlbl_unlhsh_add(&init_net, dev_name, addr, mask, addr_len, + &blob, &audit_info); } /** @@ -977,11 +954,8 @@ static int netlbl_unlabel_staticadddef(struct sk_buff *skb, if (ret_val != 0) return ret_val; - /* security_secctx_to_secid() will only put one secid into the lsmblob - * so it's safe to use lsmblob_value() to get the secid. */ - return netlbl_unlhsh_add(&init_net, - NULL, addr, mask, addr_len, - lsmblob_value(&blob), &audit_info); + return netlbl_unlhsh_add(&init_net, NULL, addr, mask, addr_len, &blob, + &audit_info); } /** @@ -1093,8 +1067,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, struct net_device *dev; struct lsmcontext context; void *data; - u32 secid; - struct lsmblob blob; + struct lsmblob *lsmb; data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).portid, cb_arg->seq, &netlbl_unlabel_gnl_family, @@ -1132,7 +1105,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, if (ret_val != 0) goto list_cb_failure; - secid = addr4->secid; + lsmb = (struct lsmblob *)&addr4->lsmblob; } else { ret_val = nla_put_in6_addr(cb_arg->skb, NLBL_UNLABEL_A_IPV6ADDR, @@ -1146,14 +1119,10 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, if (ret_val != 0) goto list_cb_failure; - secid = addr6->secid; + lsmb = (struct lsmblob *)&addr6->lsmblob; } - /* lsmblob_init() secid into all of the secids in blob. - * security_secid_to_secctx() will know which security module - * to use to create the secctx. */ - lsmblob_init(&blob, secid); - ret_val = security_secid_to_secctx(&blob, &context); + ret_val = security_secid_to_secctx(lsmb, &context); if (ret_val != 0) goto list_cb_failure; ret_val = nla_put(cb_arg->skb, @@ -1512,7 +1481,7 @@ int netlbl_unlabel_getattr(const struct sk_buff *skb, &iface->addr4_list); if (addr4 == NULL) goto unlabel_getattr_nolabel; - secattr->attr.secid = netlbl_unlhsh_addr4_entry(addr4)->secid; + secattr->attr.lsmblob = netlbl_unlhsh_addr4_entry(addr4)->lsmblob; break; } #if IS_ENABLED(CONFIG_IPV6) @@ -1525,7 +1494,7 @@ int netlbl_unlabel_getattr(const struct sk_buff *skb, &iface->addr6_list); if (addr6 == NULL) goto unlabel_getattr_nolabel; - secattr->attr.secid = netlbl_unlhsh_addr6_entry(addr6)->secid; + secattr->attr.lsmblob = netlbl_unlhsh_addr6_entry(addr6)->lsmblob; break; } #endif /* IPv6 */ diff --git a/net/netlabel/netlabel_unlabeled.h b/net/netlabel/netlabel_unlabeled.h index 058e3a285d56..168920780994 100644 --- a/net/netlabel/netlabel_unlabeled.h +++ b/net/netlabel/netlabel_unlabeled.h @@ -211,7 +211,7 @@ int netlbl_unlhsh_add(struct net *net, const void *addr, const void *mask, u32 addr_len, - u32 secid, + struct lsmblob *lsmblob, struct netlbl_audit *audit_info); int netlbl_unlhsh_remove(struct net *net, const char *dev_name, diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 7bc9a043a30a..60e35d31cc4c 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -6952,7 +6952,7 @@ static int selinux_perf_event_write(struct perf_event *event) } #endif -static struct lsm_id selinux_lsmid __lsm_ro_after_init = { +struct lsm_id selinux_lsmid __lsm_ro_after_init = { .lsm = "selinux", .slot = LSMBLOB_NEEDED }; diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 3cc8bab31ea8..6a40b47307ca 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -73,6 +73,7 @@ struct netlbl_lsm_secattr; extern int selinux_enabled_boot; +extern struct lsm_id selinux_lsmid; /* * type_datum properties diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c index 6a94b31b5472..d8d7603ab14e 100644 --- a/security/selinux/netlabel.c +++ b/security/selinux/netlabel.c @@ -108,7 +108,7 @@ static struct netlbl_lsm_secattr *selinux_netlbl_sock_getattr( return NULL; if ((secattr->flags & NETLBL_SECATTR_SECID) && - (secattr->attr.secid == sid)) + (secattr->attr.lsmblob.secid[selinux_lsmid.slot] == sid)) return secattr; return NULL; diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 597b79703584..a18339bc883a 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -3787,7 +3787,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); @@ -3863,7 +3863,7 @@ int security_netlbl_sid_to_secattr(struct selinux_state *state, if (secattr->domain == NULL) goto out; - secattr->attr.secid = sid; + secattr->attr.lsmblob.secid[selinux_lsmid.slot] = sid; secattr->flags |= NETLBL_SECATTR_DOMAIN_CPY | NETLBL_SECATTR_SECID; mls_export_netlbl_lvl(policydb, ctx, secattr); rc = mls_export_netlbl_cat(policydb, ctx, secattr); diff --git a/security/smack/smack.h b/security/smack/smack.h index 0f8d0feb89a4..b06fc332a1f9 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h @@ -303,6 +303,7 @@ int smack_populate_secattr(struct smack_known *skp); * Shared data. */ extern int smack_enabled; +extern struct lsm_id smack_lsmid; extern int smack_cipso_direct; extern int smack_cipso_mapped; extern struct smack_known *smack_net_ambient; diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c index 7eabb448acab..fccd5da3014e 100644 --- a/security/smack/smack_access.c +++ b/security/smack/smack_access.c @@ -522,7 +522,7 @@ int smack_populate_secattr(struct smack_known *skp) { int slen; - skp->smk_netlabel.attr.secid = skp->smk_secid; + skp->smk_netlabel.attr.lsmblob.secid[smack_lsmid.slot] = skp->smk_secid; skp->smk_netlabel.domain = skp->smk_known; skp->smk_netlabel.cache = netlbl_secattr_cache_alloc(GFP_ATOMIC); if (skp->smk_netlabel.cache != NULL) { diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index ef04029dcdf1..03a1c40174d7 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -3721,11 +3721,12 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap, if ((sap->flags & NETLBL_SECATTR_CACHE) != 0) return (struct smack_known *)sap->cache->data; + /* + * Looks like a fallback, which gives us a secid. + */ if ((sap->flags & NETLBL_SECATTR_SECID) != 0) - /* - * Looks like a fallback, which gives us a secid. - */ - return smack_from_secid(sap->attr.secid); + return smack_from_secid( + sap->attr.lsmblob.secid[smack_lsmid.slot]); if ((sap->flags & NETLBL_SECATTR_MLS_LVL) != 0) { /* @@ -4699,7 +4700,7 @@ struct lsm_blob_sizes smack_blob_sizes __lsm_ro_after_init = { .lbs_sock = sizeof(struct socket_smack), }; -static struct lsm_id smack_lsmid __lsm_ro_after_init = { +struct lsm_id smack_lsmid __lsm_ro_after_init = { .lsm = "smack", .slot = LSMBLOB_NEEDED }; diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index 5d44b7d258ef..ad946ccf5023 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c @@ -1140,6 +1140,7 @@ static void smk_net4addr_insert(struct smk_net4addr *new) static ssize_t smk_write_net4addr(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { + struct lsmblob lsmblob; struct smk_net4addr *snp; struct sockaddr_in newname; char *smack; @@ -1271,10 +1272,13 @@ static ssize_t smk_write_net4addr(struct file *file, const char __user *buf, * this host so that incoming packets get labeled. * but only if we didn't get the special CIPSO option */ - if (rc == 0 && skp != NULL) + if (rc == 0 && skp != NULL) { + lsmblob_init(&lsmblob, 0); + lsmblob.secid[smack_lsmid.slot] = snp->smk_label->smk_secid; rc = netlbl_cfg_unlbl_static_add(&init_net, NULL, - &snp->smk_host, &snp->smk_mask, PF_INET, - snp->smk_label->smk_secid, &audit_info); + &snp->smk_host, &snp->smk_mask, PF_INET, &lsmblob, + &audit_info); + } if (rc == 0) rc = count; From patchwork Tue Jan 26 16:41:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12048595 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 22080C433E9 for ; Tue, 26 Jan 2021 23:03:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DE8C220663 for ; Tue, 26 Jan 2021 23:03:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728229AbhAZXDl (ORCPT ); Tue, 26 Jan 2021 18:03:41 -0500 Received: from sonic314-26.consmr.mail.ne1.yahoo.com ([66.163.189.152]:42566 "EHLO sonic314-26.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390618AbhAZRTe (ORCPT ); Tue, 26 Jan 2021 12:19:34 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1611681528; bh=aiFReX2NAaXis4TAYg24pkQIsNJb1hINvQ6KahGRSqg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=WLoOJrngp0PKulo12wGg/jXgmylw5zxPyN/vy1ThqXFz+VL5iFCr5yo2+bVTzaX3pXYGVceVOH78ELyLxMM4IAyR4ZmfFDryiiKWys7s2gk84IUOCuZXvH+XqiB8QsgvK36yiTfZFU0MeDYPWl1+svuRaA7hXMr4KKUZn7RwlruaTBBY9JZk/Ji4fduDpWVSfi+IOCJVunZKIM0EgXnVLzW1LNuZZlj1goTcSX6mPMTrvaZFjZn6Ov8TBPE3LUqDAoDxsGp6x/+yL9he02Xgz64uxOwAGsf5q9JF4Vu5sZIVQvXeLJrZ8fh9k54F7Me66Nsu9mq0krLs1YZU/OnXyQ== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1611681528; bh=pgePccUKD7o7IWAJqAvePx1p6aKYQJuJXaBLp2DsrtL=; h=From:To:Subject:Date:From:Subject:Reply-To; b=JF6Ros+dDEf6xZ3UQFgvZuGnoT28KG2Z9xzoVXVngXDqyQouwG/gDxTR/SkYS7C6ratU73e+NaHBaGSe33RWAFW/ms71HHe4uSJVRjwhsgL1cERhpNcEW/lxIXTKPfjaE5olz8dJgaHVgLZJG+//VAk2ob01rwfyL/ZonCATt85ZHdS3MUu442NKcgKdH1Gzg3tu3lekRcd2MYW2eM5Xd4qBmbQ+JzpffqNuonJiNys4uN4h55JY2HkjHIUDQGjsSRCU2Isif3Vn5ulK/D3Bont0+AzZhQ7UytzyJ/XEDRHyUM1jTxUVfNAthxnaWJYQGXnOvNy2hfLPfBDenJinIA== X-YMail-OSG: TKio.I8VM1kCBXLhlBUJHaYgfx9lmignJVI9n2OH7CXmc1pDRAMyptyuyl6Qy_p LGboDa600xYotBfTqw5xAhBdZC5SWDrWzOgrx2eoIGg4ypGNnvHRt1HLlu0N9eF3SZQ316v7Z3c9 .6.pOsI24rzDcPZnhwyLDCQKGZzYg.z.QwI_bX5moXEkB44wBmR.T_E6HS_VdcwZk6Wy6VzKpNeu BgqmL2H_MwrjnEEThVhaoPcEUlchDcc86CGG7IqnFohjjSIM_GdF0aZ2dHHSLx4c7y9U4pK07alh a03NTSfNQMxa8FpKHDLZJ_5vYNeY2ENwDVMZgQAwiqIreEXBdpPyi82qUA6TsxxJ4zWDqnBkT2al nYUS96V76OlBHcZXykDmZOHlMrjrR4rVNR138GcUNwrXz87ELFlvrE6jRlxthFuZm6i0IRFuQOK1 F2i1yRzI.iLIaCWud6eUBDjsj5orRQw..jQe0Qa7xLIqea0.xadVjh7MBrNC4wI0SWohYHhG80Hf v99yLnpBslWQtVVyPvXjzChHW9G5f0wcxgSq.IXO0kHDFsR6UyrdU1KZStfcu3e6G7fuJracfayR 2wwJ0qBF4223ezW0dxV4ltbuyQr3QkVPEZwf.TgZYcrGHLj7fSL4RcH_U6BqsqVEJdfOwncab1yd M.2P.svXBqKKA9N1VESh3EXjUOi.iPcs06R.QGrzxwfDNzqYFEQq45WkWK9AqSrznOXDREDqHRtT o54eYdYte1kNGejqK1wYzy5cxtUa9.VrQfaV89YMc7cbxhaMix_ohMKQ1odIGuPqwKyMVpLmA8Vz MoCxKTfIhGxH9tB15_Tdxh8xYnxaSO7fOHFVS.eGwYDCz.3VElDgm2h2YS4ASjQ3tSh.i7hjyxN6 Bl97bqfIHkeJWsmWn29Z0EucuMpPF2JduvB0kU9zzHffGFFO2r.cCP7.rlKXJroBNgZFNk9_NMbc rweyGvV4pdXui6qAMZYh3GiyWLH0gEx.uTLRCjsu5psiEkkOafdyTPkanZ63Icvoeux.RWF5n8v3 jPW94Gg_V9cD0ULHMnxD7AddGIGOn2_TdwJFstKLyik.QPjXQYolU86kGQAf6YWMLSGkWR3lrpqg rSzQNvAWBNrkeXxsKlgGbADLze21_LWPEwUe9I2yxMzfRJeAwhe36Waroi6ohftbX2I9b7zDsIPV Aep6acw8EXgwC2Vy3RFcGqNHMlrnr_OSgzoXA8Xxzs8VCn5dsWS_lErdXWn19ffFIA5TVF0J2k0s GojtLDhkt_fQ7qQIhrJT0.mFo5McQoXzulUGKtpdIo5qKi2u42R3Y5yMVTOX2t3t8RUJgkhPPfJN ssg49UspeQDmb_54cjxOE9uxsaneP64NVx9yx8.DhyuMyFHQycMgCxYjxgyZNVzc8pqEvDv1lbt0 Ur6KxnBroR9S4hbrF6Pu8g8ybW_rkj6jcjxxb3iLY0ZG..3F59PH7JSTqiu0Hp8CEBy7LMNM0jk_ JgpuZ5FbX0SzrKDJ0KaF_7NZkPnFIIZxG0IQTr3f2il8blws6WMwI6sO94rvbNuTxYfLOmo2uT4Q QOAMP83Gz2Dwe0xdbwB4z7idEoBmeUrX_rH_fDe4kNKmcajH._yHz8XZZ67xqSLEnc34DZYTE85Z ipJurY2Dm9gmBrfLFRGLez9YIx3pQPE_vyOCJkAafdizA8lSnMwOiN.XtANNaZE.aIuu.tVEP9D0 o3hbQ.XBntQ5VW0EKKZPRxGaexbchyvXI_hXSshz_XEoLa.uGq0I0jqfyQ25R31_VFVK3TR1YsxT CpE2On1Y7JnVE1umAcEuFVAJ.IbTnX7o5a75y0wgCxSs84ajt5U9YArVIb07CyoHwL2yfHtV3LUK OLkJp2jA13YBt.9tIoor3lyscpAQSzodkTOCIke7C7e4DUEdiNhkKouQ7c3WKiGqCytUbDD4APLE 9to1lSs39YXerUQNICfyOy3FtwrEpyzTyMDwMVT4wK9mc5evrOT9aWTANaNNhz.2.V6XZNtw21l0 EXwuNhxBXNBxWqc8iBLaCTdpEP4i3DSc6Xa9VryQ51EUGXcW_xAGXVj3bAMbBnxbcwwHCXCHJJ9A 85g16qv3yjTD2n5jGSJNU_kGO3tf105NhyXaoVO7aCM.PBB5g7V_3afNjosqTvMdaFDm8XWhhZid V0RDgmmpCx_AT4pBLU26iHD8BtZM80f9sKf4XzDZl.TMOaAC9i8JG22VNJZfRreq89NIvTn_m9ZQ hfcQ_X3i2eoVMgq4DUgkdEIJFbafdQBRNSjVWO9HFp.3REQRyrhDTeflf7pnQmi39ZVueYlUZ_sg vAjzMttOTOc5rT8oLi2bJGQX4vw7OSVVnE0AwoxKaLqwyj8yKW7Q1yi5Cj5jEr63qoxvFFH1weYU Fv06TQiNWxzBrTK6VpKAlP5IKSpt4FcOAX7ozMX6aZRRzrpzWPt.j4oSIqVJYRsTVqB633KYC8s4 guZbBEgTJPa6JbJf6DQOCRX1r1IM4R28OstBWchRjHV8k8KawU6OPfxaO_k3V4ric51M5.LymeCy Xc_.njyloiJgA7AnTgECB4G6wj0S53g6_Fhti.iv936rJ17RJYMQPym.40ijPcUJz_U0wc5.Ag3G vB0lJwIPvL77m6QMsxVzQ74VYTWWM3UVXLjbgSQnPA9llclL2ojgiNrTuXnxvpwasFGiTXqEfZjl Ry1Jm6LRYsypQ0GeX5Enodw.FQzbfxT6fFMglXiavVu0kpwD4qym4ubeW4uJVPn75Pcyrh2P.EXE .nxlt1945aJoShntsI6qd4Sxnn.i.z2gLdj4DgMa1U46nev3fO9xuA3xJD9XeWh233xB3Jn_5I1m c6rzDjWovWYxX6l_0SpQ3RjgPRlMq31fCe.7zAGBNnlksN525fMJn93CuXnWaEvQuRPRMMRlOhpB Q01mgkuyj7uzAM8ls1Zt5x2qv32NoMu8IoZRdnUU9gkBh0zEwoInUo2x3yRYat0p5JS4tSZZ0K7p CkvJRfZ9WCjxQtwh.fRh2dc2kT9xc8wTFFgSAQUNYqHapzuAxKKmDp7V8lY03XZoGP9WaouxJs2Q 8JY1oToh52CjZNhfI2yQwWfbARQ67S6Kr6jj7wiVqjdXIVL__3UTloJN9ibiHxCYAbDWUX9Uq9ud OdlNk1a0iIuXquqLIHF0_ydZOqTXIkY2ohAvhQVf5Rw-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic314.consmr.mail.ne1.yahoo.com with HTTP; Tue, 26 Jan 2021 17:18:48 +0000 Received: by smtp407.mail.ne1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 2551eeea7e1bd4c4f8a232783244f546; Tue, 26 Jan 2021 17:05:58 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov, linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH v24 22/25] Audit: Add new record for multiple process LSM attributes Date: Tue, 26 Jan 2021 08:41:05 -0800 Message-Id: <20210126164108.1958-23-casey@schaufler-ca.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20210126164108.1958-1-casey@schaufler-ca.com> References: <20210126164108.1958-1-casey@schaufler-ca.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Create a new audit record type to contain the subject information when there are multiple security modules that require such data. This record is linked with the same timestamp and serial number using the audit_alloc_local() mechanism. The record is produced only in cases where there is more than one security module with a process "context". In cases where this record is produced the subj= fields of other records in the audit event will be set to "subj=?". An example of the MAC_TASK_CONTEXTS (1420) record is: type=UNKNOWN[1420] msg=audit(1600880931.832:113) subj_apparmor==unconfined subj_smack=_ There will be a subj_$LSM= entry for each security module LSM that supports the secid_to_secctx and secctx_to_secid hooks. The BPF security module implements secid/secctx translation hooks, so it has to be considered to provide a secctx even though it may not actually do so. Signed-off-by: Casey Schaufler To: paul@paul-moore.com To: linux-audit@redhat.com To: rgb@redhat.com Cc: netdev@vger.kernel.org --- drivers/android/binder.c | 2 +- include/linux/audit.h | 24 ++++++++ include/linux/security.h | 16 ++++- include/net/netlabel.h | 3 +- include/net/scm.h | 2 +- include/net/xfrm.h | 13 +++- include/uapi/linux/audit.h | 1 + kernel/audit.c | 80 ++++++++++++++++++------- kernel/audit.h | 3 + kernel/auditfilter.c | 6 +- kernel/auditsc.c | 75 ++++++++++++++++++++--- net/ipv4/ip_sockglue.c | 2 +- net/netfilter/nf_conntrack_netlink.c | 4 +- net/netfilter/nf_conntrack_standalone.c | 2 +- net/netfilter/nfnetlink_queue.c | 2 +- net/netlabel/netlabel_domainhash.c | 4 +- net/netlabel/netlabel_unlabeled.c | 24 ++++---- net/netlabel/netlabel_user.c | 20 ++++--- net/netlabel/netlabel_user.h | 6 +- net/xfrm/xfrm_policy.c | 10 ++-- net/xfrm/xfrm_state.c | 20 ++++--- security/integrity/ima/ima_api.c | 7 ++- security/integrity/integrity_audit.c | 6 +- security/security.c | 46 +++++++++----- security/smack/smackfs.c | 3 +- 25 files changed, 274 insertions(+), 107 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 4c810ea52ab7..28f573d46391 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2700,7 +2700,7 @@ static void binder_transaction(struct binder_proc *proc, size_t added_size; security_task_getsecid(proc->tsk, &blob); - ret = security_secid_to_secctx(&blob, &lsmctx); + ret = security_secid_to_secctx(&blob, &lsmctx, LSMBLOB_DISPLAY); if (ret) { return_error = BR_FAILED_REPLY; return_error_param = ret; diff --git a/include/linux/audit.h b/include/linux/audit.h index 97cd7471e572..229cd71fbf09 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -164,6 +164,8 @@ extern struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp extern __printf(2, 3) void audit_log_format(struct audit_buffer *ab, const char *fmt, ...); extern void audit_log_end(struct audit_buffer *ab); +extern void audit_log_end_local(struct audit_buffer *ab, + struct audit_context *context); extern bool audit_string_contains_control(const char *string, size_t len); extern void audit_log_n_hex(struct audit_buffer *ab, @@ -188,6 +190,7 @@ extern void audit_log_lost(const char *message); extern int audit_log_task_context(struct audit_buffer *ab); extern void audit_log_task_info(struct audit_buffer *ab); +extern void audit_log_lsm(struct audit_context *context); extern int audit_update_lsm_rules(void); @@ -226,6 +229,9 @@ void audit_log_format(struct audit_buffer *ab, const char *fmt, ...) { } static inline void audit_log_end(struct audit_buffer *ab) { } +static inline void audit_log_end_local(struct audit_buffer *ab, + struct audit_context *context) +{ } static inline void audit_log_n_hex(struct audit_buffer *ab, const unsigned char *buf, size_t len) { } @@ -252,6 +258,8 @@ static inline int audit_log_task_context(struct audit_buffer *ab) } static inline void audit_log_task_info(struct audit_buffer *ab) { } +static void audit_log_lsm(struct audit_context *context) +{ } static inline kuid_t audit_get_loginuid(struct task_struct *tsk) { @@ -291,6 +299,7 @@ extern int audit_alloc(struct task_struct *task); extern void __audit_free(struct task_struct *task); extern struct audit_context *audit_alloc_local(gfp_t gfpflags); extern void audit_free_context(struct audit_context *context); +extern void audit_free_local(struct audit_context *context); extern void __audit_syscall_entry(int major, unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3); extern void __audit_syscall_exit(int ret_success, long ret_value); @@ -386,6 +395,19 @@ static inline void audit_ptrace(struct task_struct *t) __audit_ptrace(t); } +static inline struct audit_context *audit_alloc_for_lsm(gfp_t gfp) +{ + struct audit_context *context = audit_context(); + + if (context) + return context; + + if (lsm_multiple_contexts()) + return audit_alloc_local(gfp); + + return NULL; +} + /* Private API (for audit.c only) */ extern void __audit_ipc_obj(struct kern_ipc_perm *ipcp); extern void __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, umode_t mode); @@ -560,6 +582,8 @@ extern int audit_signals; } static inline void audit_free_context(struct audit_context *context) { } +static inline void audit_free_local(struct audit_context *context) +{ } static inline int audit_alloc(struct task_struct *task) { return 0; diff --git a/include/linux/security.h b/include/linux/security.h index e5740e08bc0c..18dd3218f1c0 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -182,6 +182,8 @@ struct lsmblob { #define LSMBLOB_INVALID -1 /* Not a valid LSM slot number */ #define LSMBLOB_NEEDED -2 /* Slot requested on initialization */ #define LSMBLOB_NOT_NEEDED -3 /* Slot not requested */ +#define LSMBLOB_DISPLAY -4 /* Use the "display" slot */ +#define LSMBLOB_FIRST -5 /* Use the default "display" slot */ /** * lsmblob_init - initialize an lsmblob structure @@ -248,6 +250,15 @@ static inline u32 lsmblob_value(const struct lsmblob *blob) return 0; } +static inline bool lsm_multiple_contexts(void) +{ +#ifdef CONFIG_SECURITY + return lsm_slot_to_name(1) != NULL; +#else + return false; +#endif +} + /* These functions are in security/commoncap.c */ extern int cap_capable(const struct cred *cred, struct user_namespace *ns, int cap, unsigned int opts); @@ -564,7 +575,8 @@ int security_setprocattr(const char *lsm, const char *name, void *value, size_t size); int security_netlink_send(struct sock *sk, struct sk_buff *skb); int security_ismaclabel(const char *name); -int security_secid_to_secctx(struct lsmblob *blob, struct lsmcontext *cp); +int security_secid_to_secctx(struct lsmblob *blob, struct lsmcontext *cp, + int display); int security_secctx_to_secid(const char *secdata, u32 seclen, struct lsmblob *blob); void security_release_secctx(struct lsmcontext *cp); @@ -1390,7 +1402,7 @@ static inline int security_ismaclabel(const char *name) } static inline int security_secid_to_secctx(struct lsmblob *blob, - struct lsmcontext *cp) + struct lsmcontext *cp, int display) { return -EOPNOTSUPP; } diff --git a/include/net/netlabel.h b/include/net/netlabel.h index 73fc25b4042b..9bc1f969a25d 100644 --- a/include/net/netlabel.h +++ b/include/net/netlabel.h @@ -97,7 +97,8 @@ struct calipso_doi; /* NetLabel audit information */ struct netlbl_audit { - u32 secid; + struct audit_context *localcontext; + struct lsmblob lsmdata; kuid_t loginuid; unsigned int sessionid; }; diff --git a/include/net/scm.h b/include/net/scm.h index b77a52f93389..f4d567d4885e 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -101,7 +101,7 @@ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct sc * and the infrastructure will know which it is. */ lsmblob_init(&lb, scm->secid); - err = security_secid_to_secctx(&lb, &context); + err = security_secid_to_secctx(&lb, &context, LSMBLOB_DISPLAY); if (!err) { put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, context.len, diff --git a/include/net/xfrm.h b/include/net/xfrm.h index b2a06f10b62c..bfe3ba2a5233 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -669,13 +669,22 @@ struct xfrm_spi_skb_cb { #define XFRM_SPI_SKB_CB(__skb) ((struct xfrm_spi_skb_cb *)&((__skb)->cb[0])) #ifdef CONFIG_AUDITSYSCALL -static inline struct audit_buffer *xfrm_audit_start(const char *op) +static inline struct audit_buffer *xfrm_audit_start(const char *op, + struct audit_context **lac) { + struct audit_context *context; struct audit_buffer *audit_buf = NULL; if (audit_enabled == AUDIT_OFF) return NULL; - audit_buf = audit_log_start(audit_context(), GFP_ATOMIC, + context = audit_context(); + if (lac != NULL) { + if (lsm_multiple_contexts() && context == NULL) + context = audit_alloc_local(GFP_ATOMIC); + *lac = context; + } + + audit_buf = audit_log_start(context, GFP_ATOMIC, AUDIT_MAC_IPSEC_EVENT); if (audit_buf == NULL) return NULL; diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h index cd2d8279a5e4..2a63720e56f6 100644 --- a/include/uapi/linux/audit.h +++ b/include/uapi/linux/audit.h @@ -139,6 +139,7 @@ #define AUDIT_MAC_UNLBL_STCDEL 1417 /* NetLabel: del a static label */ #define AUDIT_MAC_CALIPSO_ADD 1418 /* NetLabel: add CALIPSO DOI entry */ #define AUDIT_MAC_CALIPSO_DEL 1419 /* NetLabel: del CALIPSO DOI entry */ +#define AUDIT_MAC_TASK_CONTEXTS 1420 /* Multiple LSM contexts */ #define AUDIT_FIRST_KERN_ANOM_MSG 1700 #define AUDIT_LAST_KERN_ANOM_MSG 1799 diff --git a/kernel/audit.c b/kernel/audit.c index ce90ea8373d3..732ce576ed89 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -386,10 +386,12 @@ void audit_log_lost(const char *message) static int audit_log_config_change(char *function_name, u32 new, u32 old, int allow_changes) { + struct audit_context *context; struct audit_buffer *ab; int rc = 0; - ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_CONFIG_CHANGE); + context = audit_alloc_for_lsm(GFP_KERNEL); + ab = audit_log_start(context, GFP_KERNEL, AUDIT_CONFIG_CHANGE); if (unlikely(!ab)) return rc; audit_log_format(ab, "op=set %s=%u old=%u ", function_name, new, old); @@ -398,7 +400,7 @@ static int audit_log_config_change(char *function_name, u32 new, u32 old, if (rc) allow_changes = 0; /* Something weird, deny request */ audit_log_format(ab, " res=%d", allow_changes); - audit_log_end(ab); + audit_log_end_local(ab, context); return rc; } @@ -1072,12 +1074,6 @@ static void audit_log_common_recv_msg(struct audit_context *context, audit_log_task_context(*ab); } -static inline void audit_log_user_recv_msg(struct audit_buffer **ab, - u16 msg_type) -{ - audit_log_common_recv_msg(NULL, ab, msg_type); -} - int is_audit_feature_set(int i) { return af.features & AUDIT_FEATURE_TO_MASK(i); @@ -1110,6 +1106,7 @@ static void audit_log_feature_change(int which, u32 old_feature, u32 new_feature audit_log_format(ab, " feature=%s old=%u new=%u old_lock=%u new_lock=%u res=%d", audit_feature_names[which], !!old_feature, !!new_feature, !!old_lock, !!new_lock, res); + audit_log_lsm(ab->ctx); audit_log_end(ab); } @@ -1190,6 +1187,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) struct audit_buffer *ab; u16 msg_type = nlh->nlmsg_type; struct audit_sig_info *sig_data; + struct audit_context *lcontext; err = audit_netlink_ok(skb, msg_type); if (err) @@ -1357,7 +1355,8 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) if (err) break; } - audit_log_user_recv_msg(&ab, msg_type); + lcontext = audit_alloc_for_lsm(GFP_KERNEL); + audit_log_common_recv_msg(lcontext, &ab, msg_type); if (msg_type != AUDIT_USER_TTY) { /* ensure NULL termination */ str[data_len - 1] = '\0'; @@ -1370,7 +1369,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) data_len--; audit_log_n_untrustedstring(ab, str, data_len); } - audit_log_end(ab); + audit_log_end_local(ab, lcontext); } break; case AUDIT_ADD_RULE: @@ -1378,13 +1377,14 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) if (data_len < sizeof(struct audit_rule_data)) return -EINVAL; if (audit_enabled == AUDIT_LOCKED) { - audit_log_common_recv_msg(audit_context(), &ab, + lcontext = audit_alloc_for_lsm(GFP_KERNEL); + audit_log_common_recv_msg(lcontext, &ab, AUDIT_CONFIG_CHANGE); audit_log_format(ab, " op=%s audit_enabled=%d res=0", msg_type == AUDIT_ADD_RULE ? "add_rule" : "remove_rule", audit_enabled); - audit_log_end(ab); + audit_log_end_local(ab, lcontext); return -EPERM; } err = audit_rule_change(msg_type, seq, data, data_len); @@ -1394,10 +1394,10 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) break; case AUDIT_TRIM: audit_trim_trees(); - audit_log_common_recv_msg(audit_context(), &ab, - AUDIT_CONFIG_CHANGE); + lcontext = audit_alloc_for_lsm(GFP_KERNEL); + audit_log_common_recv_msg(lcontext, &ab, AUDIT_CONFIG_CHANGE); audit_log_format(ab, " op=trim res=1"); - audit_log_end(ab); + audit_log_end_local(ab, lcontext); break; case AUDIT_MAKE_EQUIV: { void *bufp = data; @@ -1425,6 +1425,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) /* OK, here comes... */ err = audit_tag_tree(old, new); + lcontext = audit_alloc_for_lsm(GFP_KERNEL); audit_log_common_recv_msg(audit_context(), &ab, AUDIT_CONFIG_CHANGE); audit_log_format(ab, " op=make_equiv old="); @@ -1432,7 +1433,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) audit_log_format(ab, " new="); audit_log_untrustedstring(ab, new); audit_log_format(ab, " res=%d", !err); - audit_log_end(ab); + audit_log_end_local(ab, lcontext); kfree(old); kfree(new); break; @@ -1443,7 +1444,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) if (lsmblob_is_set(&audit_sig_lsm)) { err = security_secid_to_secctx(&audit_sig_lsm, - &context); + &context, LSMBLOB_FIRST); if (err) return err; } @@ -1498,13 +1499,14 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) old.enabled = t & AUDIT_TTY_ENABLE; old.log_passwd = !!(t & AUDIT_TTY_LOG_PASSWD); + lcontext = audit_alloc_for_lsm(GFP_KERNEL); audit_log_common_recv_msg(audit_context(), &ab, AUDIT_CONFIG_CHANGE); audit_log_format(ab, " op=tty_set old-enabled=%d new-enabled=%d" " old-log_passwd=%d new-log_passwd=%d res=%d", old.enabled, s.enabled, old.log_passwd, s.log_passwd, !err); - audit_log_end(ab); + audit_log_end_local(ab, lcontext); break; } default: @@ -1550,6 +1552,7 @@ static void audit_receive(struct sk_buff *skb) /* Log information about who is connecting to the audit multicast socket */ static void audit_log_multicast(int group, const char *op, int err) { + struct audit_context *context; const struct cred *cred; struct tty_struct *tty; char comm[sizeof(current->comm)]; @@ -1558,7 +1561,8 @@ static void audit_log_multicast(int group, const char *op, int err) if (!audit_enabled) return; - ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_EVENT_LISTENER); + context = audit_alloc_for_lsm(GFP_KERNEL); + ab = audit_log_start(context, GFP_KERNEL, AUDIT_EVENT_LISTENER); if (!ab) return; @@ -1576,7 +1580,7 @@ static void audit_log_multicast(int group, const char *op, int err) audit_log_untrustedstring(ab, get_task_comm(comm, current)); audit_log_d_path_exe(ab, current->mm); /* exe= */ audit_log_format(ab, " nl-mcgrp=%d op=%s res=%d", group, op, !err); - audit_log_end(ab); + audit_log_end_local(ab, context); } /* Run custom bind function on netlink socket group connect or bind requests. */ @@ -2138,7 +2142,19 @@ int audit_log_task_context(struct audit_buffer *ab) if (!lsmblob_is_set(&blob)) return 0; - error = security_secid_to_secctx(&blob, &context); + /* + * If there is more than one security module that has a + * subject "context" it's necessary to put the subject data + * into a separate record to maintain compatibility. + */ + if (lsm_multiple_contexts()) { + if (ab->ctx) + ab->ctx->lsm = blob; + audit_log_format(ab, " subj=?"); + return 0; + } + + error = security_secid_to_secctx(&blob, &context, LSMBLOB_FIRST); if (error) { if (error != -EINVAL) goto error_path; @@ -2224,6 +2240,7 @@ void audit_log_task_info(struct audit_buffer *ab) audit_log_untrustedstring(ab, get_task_comm(comm, current)); audit_log_d_path_exe(ab, current->mm); audit_log_task_context(ab); + audit_log_lsm(ab->ctx); } EXPORT_SYMBOL(audit_log_task_info); @@ -2274,6 +2291,7 @@ static void audit_log_set_loginuid(kuid_t koldloginuid, kuid_t kloginuid, unsigned int oldsessionid, unsigned int sessionid, int rc) { + struct audit_context *context; struct audit_buffer *ab; uid_t uid, oldloginuid, loginuid; struct tty_struct *tty; @@ -2281,7 +2299,8 @@ static void audit_log_set_loginuid(kuid_t koldloginuid, kuid_t kloginuid, if (!audit_enabled) return; - ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_LOGIN); + context = audit_alloc_for_lsm(GFP_KERNEL); + ab = audit_log_start(context, GFP_KERNEL, AUDIT_LOGIN); if (!ab) return; @@ -2296,7 +2315,7 @@ static void audit_log_set_loginuid(kuid_t koldloginuid, kuid_t kloginuid, oldloginuid, loginuid, tty ? tty_name(tty) : "(none)", oldsessionid, sessionid, !rc); audit_put_tty(tty); - audit_log_end(ab); + audit_log_end_local(ab, context); } /** @@ -2396,6 +2415,21 @@ void audit_log_end(struct audit_buffer *ab) audit_buffer_free(ab); } +/** + * audit_log_end_local - end one audit record with local context + * @ab: the audit_buffer + * @context: the local context + * + * Emit an LSM context record if appropriate, then end the audit event + * in the usual way. + */ +void audit_log_end_local(struct audit_buffer *ab, struct audit_context *context) +{ + audit_log_end(ab); + audit_log_lsm_common(context); + audit_free_local(context); +} + /** * audit_log - Log an audit record * @ctx: audit context diff --git a/kernel/audit.h b/kernel/audit.h index 3f2285e1c6e0..4f245c3dac0c 100644 --- a/kernel/audit.h +++ b/kernel/audit.h @@ -100,6 +100,7 @@ struct audit_context { int dummy; /* must be the first element */ int in_syscall; /* 1 if task is in a syscall */ bool local; /* local context needed */ + bool lsmdone; /* multiple security reported */ enum audit_state state, current_state; unsigned int serial; /* serial number for record */ int major; /* syscall number */ @@ -131,6 +132,7 @@ struct audit_context { kgid_t gid, egid, sgid, fsgid; unsigned long personality; int arch; + struct lsmblob lsm; pid_t target_pid; kuid_t target_auid; @@ -201,6 +203,7 @@ struct audit_context { extern bool audit_ever_enabled; extern void audit_log_session_info(struct audit_buffer *ab); +extern void audit_log_lsm_common(struct audit_context *context); extern int auditd_test_task(struct task_struct *task); diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 9e73a7961665..2b0a6fda767d 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -1098,12 +1098,14 @@ static void audit_list_rules(int seq, struct sk_buff_head *q) /* Log rule additions and removals */ static void audit_log_rule_change(char *action, struct audit_krule *rule, int res) { + struct audit_context *context; struct audit_buffer *ab; if (!audit_enabled) return; - ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_CONFIG_CHANGE); + context = audit_alloc_for_lsm(GFP_KERNEL); + ab = audit_log_start(context, GFP_KERNEL, AUDIT_CONFIG_CHANGE); if (!ab) return; audit_log_session_info(ab); @@ -1111,7 +1113,7 @@ static void audit_log_rule_change(char *action, struct audit_krule *rule, int re audit_log_format(ab, " op=%s", action); audit_log_key(ab, rule->filterkey); audit_log_format(ab, " list=%d res=%d", rule->listnr, res); - audit_log_end(ab); + audit_log_end_local(ab, context); } /** diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 479b3933d788..376adae15a9d 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -942,6 +942,7 @@ static inline struct audit_context *audit_alloc_context(enum audit_state state, INIT_LIST_HEAD(&context->names_list); context->fds[0] = -1; context->return_valid = AUDITSC_INVALID; + context->lsmdone = false; return context; } @@ -989,12 +990,11 @@ struct audit_context *audit_alloc_local(gfp_t gfpflags) context = audit_alloc_context(AUDIT_RECORD_CONTEXT, gfpflags); if (!context) { audit_log_lost("out of memory in audit_alloc_local"); - goto out; + return NULL; } context->serial = audit_serial(); ktime_get_coarse_real_ts64(&context->ctime); context->local = true; -out: return context; } EXPORT_SYMBOL(audit_alloc_local); @@ -1015,6 +1015,13 @@ void audit_free_context(struct audit_context *context) } EXPORT_SYMBOL(audit_free_context); +void audit_free_local(struct audit_context *context) +{ + if (context && context->local) + audit_free_context(context); +} +EXPORT_SYMBOL(audit_free_local); + static int audit_log_pid_context(struct audit_context *context, pid_t pid, kuid_t auid, kuid_t uid, unsigned int sessionid, @@ -1032,7 +1039,7 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, from_kuid(&init_user_ns, auid), from_kuid(&init_user_ns, uid), sessionid); if (lsmblob_is_set(blob)) { - if (security_secid_to_secctx(blob, &lsmctx)) { + if (security_secid_to_secctx(blob, &lsmctx, LSMBLOB_FIRST)) { audit_log_format(ab, " obj=(none)"); rc = 1; } else { @@ -1277,7 +1284,8 @@ static void show_special(struct audit_context *context, int *call_panic) struct lsmblob blob; lsmblob_init(&blob, osid); - if (security_secid_to_secctx(&blob, &lsmcxt)) { + if (security_secid_to_secctx(&blob, &lsmcxt, + LSMBLOB_FIRST)) { audit_log_format(ab, " osid=%u", osid); *call_panic = 1; } else { @@ -1432,7 +1440,7 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n, struct lsmcontext lsmctx; lsmblob_init(&blob, n->osid); - if (security_secid_to_secctx(&blob, &lsmctx)) { + if (security_secid_to_secctx(&blob, &lsmctx, LSMBLOB_FIRST)) { audit_log_format(ab, " osid=%u", n->osid); if (call_panic) *call_panic = 2; @@ -1506,6 +1514,47 @@ static void audit_log_proctitle(void) audit_log_end(ab); } +void audit_log_lsm_common(struct audit_context *context) +{ + struct audit_buffer *ab; + struct lsmcontext lsmdata; + bool sep = false; + int error; + int i; + + if (!lsm_multiple_contexts() || context == NULL || + !lsmblob_is_set(&context->lsm)) + return; + + ab = audit_log_start(context, GFP_ATOMIC, AUDIT_MAC_TASK_CONTEXTS); + if (!ab) + return; /* audit_panic or being filtered */ + + for (i = 0; i < LSMBLOB_ENTRIES; i++) { + if (context->lsm.secid[i] == 0) + continue; + error = security_secid_to_secctx(&context->lsm, &lsmdata, i); + if (error && error != -EINVAL) { + audit_panic("error in audit_log_lsm"); + return; + } + + audit_log_format(ab, "%ssubj_%s=%s", sep ? " " : "", + lsm_slot_to_name(i), lsmdata.context); + sep = true; + + security_release_secctx(&lsmdata); + } + audit_log_end(ab); + context->lsmdone = true; +} + +void audit_log_lsm(struct audit_context *context) +{ + if (!context->lsmdone) + audit_log_lsm_common(context); +} + static void audit_log_exit(void) { int i, call_panic = 0; @@ -1540,6 +1589,8 @@ static void audit_log_exit(void) audit_log_key(ab, context->filterkey); audit_log_end(ab); + audit_log_lsm(context); + for (aux = context->aux; aux; aux = aux->next) { ab = audit_log_start(context, GFP_KERNEL, aux->type); @@ -1630,6 +1681,8 @@ static void audit_log_exit(void) audit_log_proctitle(); + audit_log_lsm(context); + /* Send end of event record to help user space know we are finished */ ab = audit_log_start(context, GFP_KERNEL, AUDIT_EOE); if (ab) @@ -2621,10 +2674,12 @@ void __audit_ntp_log(const struct audit_ntp_data *ad) void __audit_log_nfcfg(const char *name, u8 af, unsigned int nentries, enum audit_nfcfgop op, gfp_t gfp) { + struct audit_context *context; struct audit_buffer *ab; char comm[sizeof(current->comm)]; - ab = audit_log_start(audit_context(), gfp, AUDIT_NETFILTER_CFG); + context = audit_alloc_for_lsm(GFP_KERNEL); + ab = audit_log_start(context, gfp, AUDIT_NETFILTER_CFG); if (!ab) return; audit_log_format(ab, "table=%s family=%u entries=%u op=%s", @@ -2634,7 +2689,7 @@ void __audit_log_nfcfg(const char *name, u8 af, unsigned int nentries, audit_log_task_context(ab); /* subj= */ audit_log_format(ab, " comm="); audit_log_untrustedstring(ab, get_task_comm(comm, current)); - audit_log_end(ab); + audit_log_end_local(ab, context); } EXPORT_SYMBOL_GPL(__audit_log_nfcfg); @@ -2669,6 +2724,7 @@ static void audit_log_task(struct audit_buffer *ab) */ void audit_core_dumps(long signr) { + struct audit_context *context; struct audit_buffer *ab; if (!audit_enabled) @@ -2677,12 +2733,13 @@ void audit_core_dumps(long signr) if (signr == SIGQUIT) /* don't care for those */ return; - ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_ANOM_ABEND); + context = audit_alloc_for_lsm(GFP_KERNEL); + ab = audit_log_start(context, GFP_KERNEL, AUDIT_ANOM_ABEND); if (unlikely(!ab)) return; audit_log_task(ab); audit_log_format(ab, " sig=%ld res=1", signr); - audit_log_end(ab); + audit_log_end_local(ab, context); } /** diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index ae073b642fa7..5c0029a3a595 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -140,7 +140,7 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) return; lsmblob_init(&lb, secid); - err = security_secid_to_secctx(&lb, &context); + err = security_secid_to_secctx(&lb, &context, LSMBLOB_DISPLAY); if (err) return; diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 42570b8da17a..c8facca4818c 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -344,7 +344,7 @@ static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct) * security_secid_to_secctx() will know which security module * to use to create the secctx. */ lsmblob_init(&blob, ct->secmark); - ret = security_secid_to_secctx(&blob, &context); + ret = security_secid_to_secctx(&blob, &context, LSMBLOB_DISPLAY); if (ret) return 0; @@ -660,7 +660,7 @@ static inline int ctnetlink_secctx_size(const struct nf_conn *ct) struct lsmblob blob; struct lsmcontext context; - ret = security_secid_to_secctx(&blob, &context); + ret = security_secid_to_secctx(&blob, &context, LSMBLOB_DISPLAY); if (ret) return 0; diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index c6112960fc73..2cb3a8df7932 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -177,7 +177,7 @@ static void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) struct lsmcontext context; lsmblob_init(&blob, ct->secmark); - ret = security_secid_to_secctx(&blob, &context); + ret = security_secid_to_secctx(&blob, &context, LSMBLOB_DISPLAY); if (ret) return; diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 0d8b83d84422..f2dffeed4789 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -316,7 +316,7 @@ static void nfqnl_get_sk_secctx(struct sk_buff *skb, struct lsmcontext *context) * blob. security_secid_to_secctx() will know which security * module to use to create the secctx. */ lsmblob_init(&blob, skb->secmark); - security_secid_to_secctx(&blob, context); + security_secid_to_secctx(&blob, context, LSMBLOB_DISPLAY); } read_unlock_bh(&skb->sk->sk_callback_lock); diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c index dc8c39f51f7d..2690a528d262 100644 --- a/net/netlabel/netlabel_domainhash.c +++ b/net/netlabel/netlabel_domainhash.c @@ -259,7 +259,7 @@ static void netlbl_domhsh_audit_add(struct netlbl_dom_map *entry, break; } audit_log_format(audit_buf, " res=%u", result == 0 ? 1 : 0); - audit_log_end(audit_buf); + audit_log_end_local(audit_buf, audit_info->localcontext); } } @@ -614,7 +614,7 @@ int netlbl_domhsh_remove_entry(struct netlbl_dom_map *entry, audit_log_format(audit_buf, " nlbl_domain=%s res=1", entry->domain ? entry->domain : "(default)"); - audit_log_end(audit_buf); + audit_log_end_local(audit_buf, audit_info->localcontext); } switch (entry->def.type) { diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 3befe0738d31..ff5901113a27 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -437,13 +437,14 @@ int netlbl_unlhsh_add(struct net *net, unlhsh_add_return: rcu_read_unlock(); if (audit_buf != NULL) { - if (security_secid_to_secctx(lsmblob, &context) == 0) { + if (security_secid_to_secctx(lsmblob, &context, + LSMBLOB_FIRST) == 0) { audit_log_format(audit_buf, " sec_obj=%s", context.context); security_release_secctx(&context); } audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0); - audit_log_end(audit_buf); + audit_log_end_local(audit_buf, audit_info->localcontext); } return ret_val; } @@ -492,13 +493,14 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, if (dev != NULL) dev_put(dev); if (entry != NULL && - security_secid_to_secctx(&entry->lsmblob, &context) == 0) { + security_secid_to_secctx(&entry->lsmblob, &context, + LSMBLOB_FIRST) == 0) { audit_log_format(audit_buf, " sec_obj=%s", context.context); security_release_secctx(&context); } audit_log_format(audit_buf, " res=%u", entry != NULL ? 1 : 0); - audit_log_end(audit_buf); + audit_log_end_local(audit_buf, audit_info->localcontext); } if (entry == NULL) @@ -552,13 +554,14 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, if (dev != NULL) dev_put(dev); if (entry != NULL && - security_secid_to_secctx(&entry->lsmblob, &context) == 0) { + security_secid_to_secctx(&entry->lsmblob, &context, + LSMBLOB_FIRST) == 0) { audit_log_format(audit_buf, " sec_obj=%s", context.context); security_release_secctx(&context); } audit_log_format(audit_buf, " res=%u", entry != NULL ? 1 : 0); - audit_log_end(audit_buf); + audit_log_end_local(audit_buf, audit_info->localcontext); } if (entry == NULL) @@ -741,7 +744,7 @@ static void netlbl_unlabel_acceptflg_set(u8 value, if (audit_buf != NULL) { audit_log_format(audit_buf, " unlbl_accept=%u old=%u", value, old_val); - audit_log_end(audit_buf); + audit_log_end_local(audit_buf, audit_info->localcontext); } } @@ -1122,7 +1125,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, lsmb = (struct lsmblob *)&addr6->lsmblob; } - ret_val = security_secid_to_secctx(lsmb, &context); + ret_val = security_secid_to_secctx(lsmb, &context, LSMBLOB_FIRST); if (ret_val != 0) goto list_cb_failure; ret_val = nla_put(cb_arg->skb, @@ -1528,14 +1531,11 @@ int __init netlbl_unlabel_defconf(void) int ret_val; struct netlbl_dom_map *entry; struct netlbl_audit audit_info; - struct lsmblob blob; /* Only the kernel is allowed to call this function and the only time * it is called is at bootup before the audit subsystem is reporting * messages so don't worry to much about these values. */ - security_task_getsecid(current, &blob); - /* scaffolding until audit_info.secid is converted */ - audit_info.secid = blob.secid[0]; + security_task_getsecid(current, &audit_info.lsmdata); audit_info.loginuid = GLOBAL_ROOT_UID; audit_info.sessionid = 0; diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c index 951ba0639d20..90a18b245380 100644 --- a/net/netlabel/netlabel_user.c +++ b/net/netlabel/netlabel_user.c @@ -83,14 +83,17 @@ int __init netlbl_netlink_init(void) struct audit_buffer *netlbl_audit_start_common(int type, struct netlbl_audit *audit_info) { + struct audit_context *audit_ctx; struct audit_buffer *audit_buf; struct lsmcontext context; - struct lsmblob blob; if (audit_enabled == AUDIT_OFF) return NULL; - audit_buf = audit_log_start(audit_context(), GFP_ATOMIC, type); + audit_ctx = audit_alloc_for_lsm(GFP_ATOMIC); + audit_info->localcontext = audit_ctx; + + audit_buf = audit_log_start(audit_ctx, GFP_ATOMIC, type); if (audit_buf == NULL) return NULL; @@ -98,11 +101,14 @@ struct audit_buffer *netlbl_audit_start_common(int type, from_kuid(&init_user_ns, audit_info->loginuid), audit_info->sessionid); - lsmblob_init(&blob, audit_info->secid); - if (audit_info->secid != 0 && - security_secid_to_secctx(&blob, &context) == 0) { - audit_log_format(audit_buf, " subj=%s", context.context); - security_release_secctx(&context); + if (lsmblob_is_set(&audit_info->lsmdata)) { + if (!lsm_multiple_contexts() && + security_secid_to_secctx(&audit_info->lsmdata, &context, + LSMBLOB_FIRST) == 0) { + audit_log_format(audit_buf, " subj=%s", + context.context); + security_release_secctx(&context); + } } return audit_buf; diff --git a/net/netlabel/netlabel_user.h b/net/netlabel/netlabel_user.h index 438b5db6c714..bd4335443b87 100644 --- a/net/netlabel/netlabel_user.h +++ b/net/netlabel/netlabel_user.h @@ -34,11 +34,7 @@ static inline void netlbl_netlink_auditinfo(struct sk_buff *skb, struct netlbl_audit *audit_info) { - struct lsmblob blob; - - security_task_getsecid(current, &blob); - /* scaffolding until secid is converted */ - audit_info->secid = blob.secid[0]; + security_task_getsecid(current, &audit_info->lsmdata); audit_info->loginuid = audit_get_loginuid(current); audit_info->sessionid = audit_get_sessionid(current); } diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index d622c2548d22..6aa4bcc08848 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -4205,30 +4205,32 @@ static void xfrm_audit_common_policyinfo(struct xfrm_policy *xp, void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, bool task_valid) { + struct audit_context *context; struct audit_buffer *audit_buf; - audit_buf = xfrm_audit_start("SPD-add"); + audit_buf = xfrm_audit_start("SPD-add", &context); if (audit_buf == NULL) return; xfrm_audit_helper_usrinfo(task_valid, audit_buf); audit_log_format(audit_buf, " res=%u", result); xfrm_audit_common_policyinfo(xp, audit_buf); - audit_log_end(audit_buf); + audit_log_end_local(audit_buf, context); } EXPORT_SYMBOL_GPL(xfrm_audit_policy_add); void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, bool task_valid) { + struct audit_context *context; struct audit_buffer *audit_buf; - audit_buf = xfrm_audit_start("SPD-delete"); + audit_buf = xfrm_audit_start("SPD-delete", &context); if (audit_buf == NULL) return; xfrm_audit_helper_usrinfo(task_valid, audit_buf); audit_log_format(audit_buf, " res=%u", result); xfrm_audit_common_policyinfo(xp, audit_buf); - audit_log_end(audit_buf); + audit_log_end_local(audit_buf, context); } EXPORT_SYMBOL_GPL(xfrm_audit_policy_delete); #endif diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index d01ca1a18418..a3d49a854ed2 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -2746,29 +2746,31 @@ static void xfrm_audit_helper_pktinfo(struct sk_buff *skb, u16 family, void xfrm_audit_state_add(struct xfrm_state *x, int result, bool task_valid) { + struct audit_context *context; struct audit_buffer *audit_buf; - audit_buf = xfrm_audit_start("SAD-add"); + audit_buf = xfrm_audit_start("SAD-add", &context); if (audit_buf == NULL) return; xfrm_audit_helper_usrinfo(task_valid, audit_buf); xfrm_audit_helper_sainfo(x, audit_buf); audit_log_format(audit_buf, " res=%u", result); - audit_log_end(audit_buf); + audit_log_end_local(audit_buf, context); } EXPORT_SYMBOL_GPL(xfrm_audit_state_add); void xfrm_audit_state_delete(struct xfrm_state *x, int result, bool task_valid) { + struct audit_context *context; struct audit_buffer *audit_buf; - audit_buf = xfrm_audit_start("SAD-delete"); + audit_buf = xfrm_audit_start("SAD-delete", &context); if (audit_buf == NULL) return; xfrm_audit_helper_usrinfo(task_valid, audit_buf); xfrm_audit_helper_sainfo(x, audit_buf); audit_log_format(audit_buf, " res=%u", result); - audit_log_end(audit_buf); + audit_log_end_local(audit_buf, context); } EXPORT_SYMBOL_GPL(xfrm_audit_state_delete); @@ -2778,7 +2780,7 @@ void xfrm_audit_state_replay_overflow(struct xfrm_state *x, struct audit_buffer *audit_buf; u32 spi; - audit_buf = xfrm_audit_start("SA-replay-overflow"); + audit_buf = xfrm_audit_start("SA-replay-overflow", NULL); if (audit_buf == NULL) return; xfrm_audit_helper_pktinfo(skb, x->props.family, audit_buf); @@ -2796,7 +2798,7 @@ void xfrm_audit_state_replay(struct xfrm_state *x, struct audit_buffer *audit_buf; u32 spi; - audit_buf = xfrm_audit_start("SA-replayed-pkt"); + audit_buf = xfrm_audit_start("SA-replayed-pkt", NULL); if (audit_buf == NULL) return; xfrm_audit_helper_pktinfo(skb, x->props.family, audit_buf); @@ -2811,7 +2813,7 @@ void xfrm_audit_state_notfound_simple(struct sk_buff *skb, u16 family) { struct audit_buffer *audit_buf; - audit_buf = xfrm_audit_start("SA-notfound"); + audit_buf = xfrm_audit_start("SA-notfound", NULL); if (audit_buf == NULL) return; xfrm_audit_helper_pktinfo(skb, family, audit_buf); @@ -2825,7 +2827,7 @@ void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family, struct audit_buffer *audit_buf; u32 spi; - audit_buf = xfrm_audit_start("SA-notfound"); + audit_buf = xfrm_audit_start("SA-notfound", NULL); if (audit_buf == NULL) return; xfrm_audit_helper_pktinfo(skb, family, audit_buf); @@ -2843,7 +2845,7 @@ void xfrm_audit_state_icvfail(struct xfrm_state *x, __be32 net_spi; __be32 net_seq; - audit_buf = xfrm_audit_start("SA-icv-failure"); + audit_buf = xfrm_audit_start("SA-icv-failure", NULL); if (audit_buf == NULL) return; xfrm_audit_helper_pktinfo(skb, x->props.family, audit_buf); diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c index e83fa1c32843..8b6f8402703d 100644 --- a/security/integrity/ima/ima_api.c +++ b/security/integrity/ima/ima_api.c @@ -340,6 +340,7 @@ void ima_store_measurement(struct integrity_iint_cache *iint, void ima_audit_measurement(struct integrity_iint_cache *iint, const unsigned char *filename) { + struct audit_context *context; struct audit_buffer *ab; char *hash; const char *algo_name = hash_algo_name[iint->ima_hash->algo]; @@ -356,8 +357,8 @@ void ima_audit_measurement(struct integrity_iint_cache *iint, hex_byte_pack(hash + (i * 2), iint->ima_hash->digest[i]); hash[i * 2] = '\0'; - ab = audit_log_start(audit_context(), GFP_KERNEL, - AUDIT_INTEGRITY_RULE); + context = audit_alloc_for_lsm(GFP_KERNEL); + ab = audit_log_start(context, GFP_KERNEL, AUDIT_INTEGRITY_RULE); if (!ab) goto out; @@ -366,7 +367,7 @@ void ima_audit_measurement(struct integrity_iint_cache *iint, audit_log_format(ab, " hash=\"%s:%s\"", algo_name, hash); audit_log_task_info(ab); - audit_log_end(ab); + audit_log_end_local(ab, context); iint->flags |= IMA_AUDITED; out: diff --git a/security/integrity/integrity_audit.c b/security/integrity/integrity_audit.c index 29220056207f..b38163c43659 100644 --- a/security/integrity/integrity_audit.c +++ b/security/integrity/integrity_audit.c @@ -38,13 +38,15 @@ void integrity_audit_message(int audit_msgno, struct inode *inode, const char *cause, int result, int audit_info, int errno) { + struct audit_context *context; struct audit_buffer *ab; char name[TASK_COMM_LEN]; if (!integrity_audit_info && audit_info == 1) /* Skip info messages */ return; - ab = audit_log_start(audit_context(), GFP_KERNEL, audit_msgno); + context = audit_alloc_for_lsm(GFP_KERNEL); + ab = audit_log_start(context, GFP_KERNEL, audit_msgno); audit_log_format(ab, "pid=%d uid=%u auid=%u ses=%u", task_pid_nr(current), from_kuid(&init_user_ns, current_uid()), @@ -63,5 +65,5 @@ void integrity_audit_message(int audit_msgno, struct inode *inode, audit_log_format(ab, " ino=%lu", inode->i_ino); } audit_log_format(ab, " res=%d errno=%d", !result, errno); - audit_log_end(ab); + audit_log_end_local(ab, context); } diff --git a/security/security.c b/security/security.c index 03fb8a702f64..9bb1fe69d310 100644 --- a/security/security.c +++ b/security/security.c @@ -2236,7 +2236,7 @@ int security_setprocattr(const char *lsm, const char *name, void *value, hlist_for_each_entry(hp, &security_hook_heads.setprocattr, list) { rc = hp->hook.setprocattr(name, value, size); - if (rc < 0) + if (rc < 0 && rc != -EINVAL) return rc; } @@ -2281,13 +2281,31 @@ int security_ismaclabel(const char *name) } EXPORT_SYMBOL(security_ismaclabel); -int security_secid_to_secctx(struct lsmblob *blob, struct lsmcontext *cp) +int security_secid_to_secctx(struct lsmblob *blob, struct lsmcontext *cp, + int ilsm) { struct security_hook_list *hp; - int ilsm = lsm_task_ilsm(current); memset(cp, 0, sizeof(*cp)); + /* + * ilsm either is the slot number use for formatting + * or an instruction on which relative slot to use. + */ + if (ilsm == LSMBLOB_DISPLAY) + ilsm = lsm_task_ilsm(current); + else if (ilsm == LSMBLOB_FIRST) + ilsm = LSMBLOB_INVALID; + else if (ilsm < 0) { + WARN_ONCE(true, + "LSM: %s unknown interface LSM\n", __func__); + ilsm = LSMBLOB_INVALID; + } else if (ilsm >= lsm_slot) { + WARN_ONCE(true, + "LSM: %s invalid interface LSM\n", __func__); + ilsm = LSMBLOB_INVALID; + } + hlist_for_each_entry(hp, &security_hook_heads.secid_to_secctx, list) { if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) continue; @@ -2317,7 +2335,7 @@ int security_secctx_to_secid(const char *secdata, u32 seclen, return hp->hook.secctx_to_secid(secdata, seclen, &blob->secid[hp->lsmid->slot]); } - return 0; + return -EOPNOTSUPP; } EXPORT_SYMBOL(security_secctx_to_secid); @@ -2811,23 +2829,17 @@ int security_key_getsecurity(struct key *key, char **_buffer) int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule) { struct security_hook_list *hp; - bool one_is_good = false; - int rc = 0; - int trc; + int ilsm = lsm_task_ilsm(current); hlist_for_each_entry(hp, &security_hook_heads.audit_rule_init, list) { if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) continue; - trc = hp->hook.audit_rule_init(field, op, rulestr, - &lsmrule[hp->lsmid->slot]); - if (trc == 0) - one_is_good = true; - else - rc = trc; + if (ilsm != LSMBLOB_INVALID && ilsm != hp->lsmid->slot) + continue; + return hp->hook.audit_rule_init(field, op, rulestr, + &lsmrule[hp->lsmid->slot]); } - if (one_is_good) - return 0; - return rc; + return 0; } int security_audit_rule_known(struct audit_krule *krule) @@ -2859,6 +2871,8 @@ int security_audit_rule_match(struct lsmblob *blob, u32 field, u32 op, continue; if (lsmrule[hp->lsmid->slot] == NULL) continue; + if (lsmrule[hp->lsmid->slot] == NULL) + continue; rc = hp->hook.audit_rule_match(blob->secid[hp->lsmid->slot], field, op, &lsmrule[hp->lsmid->slot]); diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index ad946ccf5023..cefdc531ebdc 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c @@ -185,7 +185,8 @@ static void smk_netlabel_audit_set(struct netlbl_audit *nap) nap->loginuid = audit_get_loginuid(current); nap->sessionid = audit_get_sessionid(current); - nap->secid = skp->smk_secid; + lsmblob_init(&nap->lsmdata, 0); + nap->lsmdata.secid[smack_lsmid.slot] = skp->smk_secid; } /*