From patchwork Tue Sep 27 19:54:03 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12991258 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 35800C6FA86 for ; Tue, 27 Sep 2022 20:07:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232861AbiI0UHR (ORCPT ); Tue, 27 Sep 2022 16:07:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44782 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232299AbiI0UGy (ORCPT ); Tue, 27 Sep 2022 16:06:54 -0400 Received: from sonic306-27.consmr.mail.ne1.yahoo.com (sonic306-27.consmr.mail.ne1.yahoo.com [66.163.189.89]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 61FA31EAD47 for ; Tue, 27 Sep 2022 13:06:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1664309160; bh=uT9reuuisT9bCYeVveRbY1qbZdIvJNHjxL5Je3V5MZc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=bZ5TnFZXYmgCJVodsVCnz9Q07127jfS0iw9kZSI9yPVDXt3BTRGoz6Fi6SbcwfuA7V2861Lp2Mtusk9UpnSZm9kGl85dIpsITYj+eygjBhAUb86SK8O4hwKmCphT55IRpM9kZu0yOohoYoXvAcCtfaTWMH/FgUybgBEtyu9QvBfjqfZ1xuSzYQnIulP09htuqHkl4z+KJQfb1gm90G1RTPZvXqXOx6DQexbNBiMo87zdIr/yqZcHlqHL6OyAO43SSfOadwoZgPjoiTHYcQqWiB/Qi1LwOrlu/vNYvLSlTT0Tsdb7+MZOGJ/o6jx09hd1D+wlILufxnG4CXn+3T6MNA== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1664309160; bh=lKF4CFfgmBoEXxiwSEj9yTYGUD0Ozh47iP4Y2g8iC5C=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=co0PiQBhuvslcZzOaIwMiMsaFScrrnSw/2o/ZZzhBa4IfPVC0wfD9pIE0Jd/Kd08/ZxRr3+sf5oP5JxYedd4F6+LO/Ko6SBHpe8RO52pZQobVCX0lwWy14rITIYaMCVUPcQCSLXSLKOgksEihSIlfvhxqA3VKirle+4qwUyM04XNIUdS8g4kZlZ06cLclabC1SPRHL/8Ye9VOBafI3Bxe381ujucmN6wjXv8CTJM7QyWCFHgA4ljMWmk9KXQWrocV3g/JbX5DKCJnjDKUnEjDvkKg4qYaFjNop43Kfh4bv431iZVu6b7zEh8xB6aJ2dqzhTSJg6zSsR4l1i3Ht9C6A== X-YMail-OSG: kXmI0DMVM1kH1wVdIBLwGlobmJcVPO69YKYtPQFJazZBGrnemtOg3l3E.dUaKHM svOWV1Bh0ATyjhE7d9Zp3MhKOBdPIbQUrYG9Nr9oz0W0TZmi6PwyfsYwpmU4vENAp_nr6LAScdJy 8mtXlvZVpK2dLR35.MPVdNZmz8f2K6nb_BruxhAyd6iAaUmP0ZhyH1Hrf5it9aH3st_t7Jy_sXOQ _t0t0cGEqZWAr7euaMfyZsaU2FuVA5kmZ7cDcDAMSspNLH61qqJjjTieQjXI_r_lF9g3uIn4_Eze jkuNCxDSg.gFhe4ovOL8cCH6j_7K2nOlIEm_ajDVEAVrOmXH5jro3ZUCpgWr5FrWSxFWlUkgEiDb KTxGdiFKOWDpXNE1BtgCVp4qrNdb1kEuothaxdkh09XJfcsKIDjOoG8Dl5mK0lhfcF1y_Oj4uNxw yYoJU8PHNSBeKM1diq4hLdecdZMvaPMpC8gvkbMi7sZs9yL5ov91MN3jCM8lYkKk0Ce5H4MptcsM J83CsmyoYyE0au5aJ5_7OgOFOcC1lRqUj4OlJEoVdf.ZU102AUfN5y.C8ahU3NxxlAeXEujtv6Ue n8S8gmwV_wDQfB7kL6N3CiU_wGo4aZu6Rgk0pGSltUCKjJNjBIKd5I0amCUqHqkJr.BhGUTL.GFk smGKjBx2BzrQMfc5WdO2PsT_If4kXFqraQPFvFoJbM5NO9CpnCoRBbf3uk2YgmFZUG2NWATpMN5i r7Glml7gxFayfHo2TKtr5DThqrH31Ip7PnnC527Bmd9Lq4Z4Ht02TUMyp3tG7VcxEVAvOTczmRvF C5nVo3vl3UHk1Xvsp_8fQ9.fNPtQ_3T1nPo3zvom2DMcQ3vxXkQMPFQu3KKzulS_fh2_lKUHGPMS dn4HxL5gOXd5rg.o6rKdmCQWKvmmmsEyqvNutb20wm6NcdAOTCHhUcBnh1MYbRZRh5VnHglPBL_m x1qrXBkRnJP8gpk0PTbid3GsC7r0eTmxzFWd9t1vyA15XfNBfn01aBenjqMAC3KqrIRoI7UMi.hZ 5cqfe.ArCVV8pUKbRJHpJv.BdFYACwtUO1gMnGFuFQv8xar7A0rNQVEAgZSglvCssbE0zXRLFAdf 51l6QyuyABuGFtN4vWlsFrLK_G88I2heUuXBj3WwxS5nFCLU_UvrvijscaDkt1PxFnq9j2wPfXpS 0Cm3rJo9nrjBwiMmZkqcxfqTRYa956KcmNnAXgCdH9hqSe_HtuZbMyeR1I0pDDPtx.Yo_hU3qbtE wguD4KWdMkb8JDOIIgHVPbBjaGUyYrir6EKeTSa2vxDqJPjY_jxpqm0Eeh9odzkMOUQDWBVaH2W4 0Pu6JotuaRzgBEAISrJqsZDAijTG.Xu59X_mgznIghMK.v9ydGf7.KgRVXHzi.yziBtaH37LYqVL VZhVgMDUULhXvYuzQ92OdkbcRFO7mrrIF7lxDXFVWNOF.uY.xh7kA38blwkZbtiYy9b4yLbVHQls 4mJQjuDaL7pxLP2Rb1UXn7QL.qiOapkI85JmhKyy71p57dE9TOj1eTH4cDqGhtx.B1YmXhHxabtv 2dd7QoNPZ1AeBJfwnFU5KBviWabpilXUaN7TiEcSUBPV2G6O9HagHix5ABE7_epx6mIy7yOrM3LS 8BOxhdp8ELOIkf_qo8hgJuaQ8MIVu9St8nNuyyPUY2ljgWP.BZzv2ntFgwg_9QQX73gNTBChr5nj Xp14.HtQJ8T1B7QCOFjUSs2yJs6TnXg6Za9dQAJfrdwq8STkgI8sJzH7iDNyIBaweRXbkAPwCrCB ZTB5lGpHhc20UrfnbTm5BTN6ZUYZU4AsL0CkHiegxq9kc6ZMi9uUdP5Mt0jvWuBC5FFnx9.qPm0M ZSoq_N1eG_5lflIVI_90V7pZGtOqiD_CMyp4pKbpD2ffbsym.mbpnYKuTvVL6quWA3Z8f02m57UI sDfWoWMQNPxtmwsSY5mYzZRzfe8J6pSdWO.52D0RA8vo5H.4Loql6aRD_Xbi5k77AE3KvP0acV9B vtEJO6AHs7UkGKXsLbtq9thd01tbZUvstHpZ6T0qRJmmT4dYSED_sh8izOTinCciDFES39Pepsn9 q4LdUzfzLN6.UawfGR_0BnupQp5abhbSzAZOydtqU4fRDwoSjgOsRUcWJWxHyjSHrDh7P08lyYsg WfCuIEvavKJbNH2oITeUt7.dALrg5FNsdMBdYMOzZ1g3aTVtyqJFgVZXx_7dzN51RbutCEvgza0O qrld8p6.yiiSxhsMmoHgDPETIjaXsyvfxGeMatzseT9ESW_qPb88kVjYKhrKfzCReumwamspI377 Sn6wiLhknPQvbTZ7mPqF8U5Awh00EGpzBntcoS2EMgJLyrIIAxPTUFq4kj58Wwz9.cwQ- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic306.consmr.mail.ne1.yahoo.com with HTTP; Tue, 27 Sep 2022 20:06:00 +0000 Received: by hermes--production-gq1-7dfd88c84d-h7f6x (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID f8e196d1098f8fc47a5a474327d019a8; Tue, 27 Sep 2022 20:05:55 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, paul@paul-moore.com, linux-security-module@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, jmorris@namei.org, selinux@vger.kernel.org, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, stephen.smalley.work@gmail.com, linux-kernel@vger.kernel.org, Chuck Lever , linux-integrity@vger.kernel.org, netdev@vger.kernel.org, netfilter-devel@vger.kernel.org, linux-nfs@vger.kernel.org Subject: [PATCH v38 21/39] LSM: Ensure the correct LSM context releaser Date: Tue, 27 Sep 2022 12:54:03 -0700 Message-Id: <20220927195421.14713-22-casey@schaufler-ca.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220927195421.14713-1-casey@schaufler-ca.com> References: <20220927195421.14713-1-casey@schaufler-ca.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Add a new lsmcontext data structure to hold all the information about a "security context", including the string, its size and which LSM allocated the string. The allocation information is necessary because LSMs have different policies regarding the lifecycle of these strings. SELinux allocates and destroys them on each use, whereas Smack provides a pointer to an entry in a list that never goes away. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Paul Moore Acked-by: Stephen Smalley Acked-by: Chuck Lever Signed-off-by: Casey Schaufler Cc: linux-integrity@vger.kernel.org Cc: netdev@vger.kernel.org Cc: linux-audit@redhat.com Cc: netfilter-devel@vger.kernel.org To: Pablo Neira Ayuso Cc: linux-nfs@vger.kernel.org --- drivers/android/binder.c | 10 ++++--- fs/ceph/xattr.c | 6 ++++- fs/nfs/nfs4proc.c | 8 ++++-- fs/nfsd/nfs4xdr.c | 7 +++-- include/linux/security.h | 35 +++++++++++++++++++++++-- include/net/scm.h | 5 +++- kernel/audit.c | 14 +++++++--- kernel/auditsc.c | 12 ++++++--- net/ipv4/ip_sockglue.c | 4 ++- net/netfilter/nf_conntrack_netlink.c | 4 ++- net/netfilter/nf_conntrack_standalone.c | 4 ++- net/netfilter/nfnetlink_queue.c | 13 ++++++--- net/netlabel/netlabel_unlabeled.c | 19 +++++++++++--- net/netlabel/netlabel_user.c | 4 ++- security/security.c | 11 ++++---- 15 files changed, 121 insertions(+), 35 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 6e1e35de1fcb..12aa3bea59ee 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2898,6 +2898,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 */ struct list_head sgc_head; struct list_head pf_head; const void __user *user_buffer = (const void __user *) @@ -3231,7 +3232,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; @@ -3647,8 +3649,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 f31350cda960..d943be72dfff 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c @@ -1395,12 +1395,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 3ed14a2a84a4..47259990fae1 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -133,8 +133,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 1e9690a061ec..4a96e06f4827 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -2848,6 +2848,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 @@ -3357,8 +3358,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 8d3b875cd04a..a3c11934620a 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -154,6 +154,37 @@ extern const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1]; extern int lsm_id; extern struct lsm_id *lsm_idlist[]; +/* + * 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 * @@ -607,7 +638,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); @@ -1478,7 +1509,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 3d026013e6eb..d14e54098b9c 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1214,6 +1214,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) @@ -1471,15 +1472,18 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) } sig_data = kmalloc(struct_size(sig_data, ctx, 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, struct_size(sig_data, ctx, len)); @@ -2171,6 +2175,7 @@ int audit_log_task_context(struct audit_buffer *ab) unsigned len; int error; struct lsmblob blob; + struct lsmcontext scaff; /* scaffolding */ security_current_getsecid_subj(&blob); if (!lsmblob_is_set(&blob)) @@ -2185,7 +2190,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 092aba46a9b3..8a16ed2f7206 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -1096,6 +1096,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; @@ -1113,7 +1114,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="); @@ -1373,6 +1375,7 @@ static void audit_log_time(struct audit_context *context, struct audit_buffer ** static void show_special(struct audit_context *context, int *call_panic) { + struct lsmcontext lsmcxt; struct audit_buffer *ab; int i; @@ -1407,7 +1410,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) { @@ -1569,6 +1573,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)) { @@ -1577,7 +1582,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 bb8e2af31d4f..030b8c3ffae0 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 2e257aa4f61b..2bf2673042f4 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -348,6 +348,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 @@ -368,7 +369,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 da61eb8cde76..b0f4349ff88f 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -179,6 +179,7 @@ static void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) u32 len; char *secctx; struct lsmblob blob; + struct lsmcontext context; lsmblob_init(&blob, ct->secmark); ret = security_secid_to_secctx(&blob, &secctx, &len); @@ -187,7 +188,8 @@ static void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) seq_printf(s, "secctx=%s ", secctx); - security_release_secctx(secctx, len); + lsmcontext_init(&context, secctx, len, 0); /* scaffolding */ + security_release_secctx(&context); } #else static inline void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index bc25d49575e4..1416f8b2fc83 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -397,6 +397,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, enum ip_conntrack_info ctinfo = 0; const struct nfnl_ct_hook *nfnl_ct; bool csum_verify; + struct lsmcontext scaff; /* scaffolding */ char *secdata = NULL; u32 seclen = 0; ktime_t tstamp; @@ -634,8 +635,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: @@ -643,8 +646,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 604b9d1dd085..f62b88c85976 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -374,6 +374,7 @@ int netlbl_unlhsh_add(struct net *net, struct net_device *dev; struct netlbl_unlhsh_iface *iface; struct audit_buffer *audit_buf = NULL; + struct lsmcontext context; char *secctx = NULL; u32 secctx_len; struct lsmblob blob; @@ -447,7 +448,9 @@ int netlbl_unlhsh_add(struct net *net, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " sec_obj=%s", secctx); - security_release_secctx(secctx, secctx_len); + /* scaffolding */ + lsmcontext_init(&context, secctx, secctx_len, 0); + security_release_secctx(&context); } audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0); audit_log_end(audit_buf); @@ -478,6 +481,7 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, struct netlbl_unlhsh_addr4 *entry; struct audit_buffer *audit_buf; struct net_device *dev; + struct lsmcontext context; char *secctx; u32 secctx_len; struct lsmblob blob; @@ -508,7 +512,9 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " sec_obj=%s", secctx); - security_release_secctx(secctx, secctx_len); + /* scaffolding */ + lsmcontext_init(&context, secctx, secctx_len, 0); + security_release_secctx(&context); } audit_log_format(audit_buf, " res=%u", entry != NULL ? 1 : 0); audit_log_end(audit_buf); @@ -545,6 +551,7 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, struct netlbl_unlhsh_addr6 *entry; struct audit_buffer *audit_buf; struct net_device *dev; + struct lsmcontext context; char *secctx; u32 secctx_len; struct lsmblob blob; @@ -574,7 +581,8 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " sec_obj=%s", secctx); - security_release_secctx(secctx, secctx_len); + lsmcontext_init(&context, secctx, secctx_len, 0); + security_release_secctx(&context); } audit_log_format(audit_buf, " res=%u", entry != NULL ? 1 : 0); audit_log_end(audit_buf); @@ -1093,6 +1101,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, int ret_val = -ENOMEM; struct netlbl_unlhsh_walk_arg *cb_arg = arg; struct net_device *dev; + struct lsmcontext context; void *data; u32 secid; char *secctx; @@ -1163,7 +1172,9 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, NLBL_UNLABEL_A_SECCTX, secctx_len, secctx); - security_release_secctx(secctx, secctx_len); + /* scaffolding */ + lsmcontext_init(&context, secctx, secctx_len, 0); + security_release_secctx(&context); if (ret_val != 0) goto list_cb_failure; diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c index 893301ae0131..ef139d8ae7cd 100644 --- a/net/netlabel/netlabel_user.c +++ b/net/netlabel/netlabel_user.c @@ -84,6 +84,7 @@ struct audit_buffer *netlbl_audit_start_common(int type, struct netlbl_audit *audit_info) { struct audit_buffer *audit_buf; + struct lsmcontext context; char *secctx; u32 secctx_len; struct lsmblob blob; @@ -103,7 +104,8 @@ struct audit_buffer *netlbl_audit_start_common(int type, if (audit_info->secid != 0 && security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " subj=%s", secctx); - security_release_secctx(secctx, secctx_len); + lsmcontext_init(&context, secctx, secctx_len, 0);/*scaffolding*/ + security_release_secctx(&context); } return audit_buf; diff --git a/security/security.c b/security/security.c index 43d2431dbda0..44312b3437da 100644 --- a/security/security.c +++ b/security/security.c @@ -2357,16 +2357,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);