From patchwork Mon Oct 14 15:14:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 13835216 X-Patchwork-Delegate: paul@paul-moore.com Received: from sonic314-26.consmr.mail.ne1.yahoo.com (sonic314-26.consmr.mail.ne1.yahoo.com [66.163.189.152]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B12591CF7AD for ; Mon, 14 Oct 2024 15:15:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=66.163.189.152 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728918912; cv=none; b=uQFYM6rZiJTLawm3gP6N9JVKBrq3qozNkZRKoIk9dYhX9uhAuvt4pDnq035ol5pmxJdNoipLZESGaCfzaOrBtxb0GuPgwrtE5xRNprROu4GxvRoLtgp40vd8l43nq0e5W/iaxdNsuHlA7+Omh6v+qMuVZJ3rCWoFump7p+i4Zy8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728918912; c=relaxed/simple; bh=LMKlopL1q8pvatpyC6IK2IovRHHhbpmCwd99OO8TgHg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=W8HJloyeEUH6g+gD6nyRE7S69iyRAQJGj4l68+dAXPVHXBLmSMoccN3h0CDMysVfn8Te0xrdRTStxwtbuD1M3kVsS201ctIdDTUXIv5gC5vlfpkkRtz6ltSLlwrjqsvclvz1mJnY6rgaA0OWcS1KkrWOfNtiFnfdvaH4YAcpk9g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=schaufler-ca.com; spf=none smtp.mailfrom=schaufler-ca.com; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b=eD7DSv6u; arc=none smtp.client-ip=66.163.189.152 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=schaufler-ca.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=schaufler-ca.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="eD7DSv6u" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1728918901; bh=p+mCeeSdAE2EH1n1FUke1xHdjOxroqZMdAIDBzOT2CY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=eD7DSv6uMfLQPIVHgPC5ZRwzPd24L5kvwwSA4q3tPzL8MsW3dFYY8le+8fBeVSnL+Is5TbDXxbY/rqUBnwuJTJ1t27dU3e84ekog827fpB+vZPUYci88CAdpmZshft4goA8jbj7o1H0l4ONJr6sE9yu+njDbsaFDTtfEAh5KFBMMxW+8O5cP77hji/+XRIA3mM6zmXVRw1tGfE0GW1xl5n9iwxIG/liXd+LTHRHG12bqby0Ej2hz3FyhZuvE6/ofYx2N0wh098TbbkdYmVHQEeqcEfDcT+47GXFMmvYLxnIxVaiGdy61wUk58q/xpq5kXM9sYxNFLRGC3hIBu1fhmA== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1728918901; bh=iWnMJQXf8mBbVbzRfh/WO3h4tBItMdpB77Bbgk+8YNr=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=Yil9zfecUXklOeEsrxmiX8HMD7sW2zfv3KX5CtShIzehmrGTMHqaKkGQVhlHTfl/vdQKEis/5vLsuzjUIVM7Z7GeaZebBrk27a6LaLzoa/xBg3ABSkIottOqBi3LDz2FA/j8aZNdh238YVJCviNyhuaIje7SGlz12WJsUhxgViUqrKrQ9WOcrLWdLd0gmR9dvIEBeaIv3LPGcOXaEFrngmC+nrZK+umZtCrkL8tQq38nQ5L2qHgdeyLeBNJBf8pk0Pua760miZbLuY5dAmZLbzIxgK8Ke6owMNxSin3ExCgfoKcoTurqQUwriD6o93SjjJdOs3nNQXxeFrFYPCJaUw== X-YMail-OSG: vlAQoh8VM1ln_rhXMhdbbR0kR074uTJMTICGiuDywFx7tD.YVDowgoVWgQeZth1 FewFuJO_63pQ0ILW2f8KwU_CejpE_a8GexmK75fBdy.FPCRgeXLlZ.x2HDpuk3SllZhO30t4yuQC Gs6gpOpjJaribVFBDaR1Rf2uI6SOT5hSAtcITjMk9.6ZxYX09E6.p_55p_5u0mJxozfSU0nNQ4i6 3IGQGqeD6JtlPdSczimMsqPMTo9cW0VXhfGOjnAxjjE4jyCX8_.B4gWniQyypNk.yQGjN9DaR6O8 yKunK..VKzAeTuJpwveW.cA3WkieQp3HCjADKvCFbzuBtxSbz0O_tvwj18widGNvavptbR8m0OZp pFu5tA5K_CIj_rtvePVSkhwBYDxD_SYyqL7Q.24JHBGrRHNw2GGaJIyW5Unwjamu4QEKPqao0ASS DM6By7c8AGvLInpDzLGFFjyqnLK0V21anPulSTJV.h_Wk8kkqSXW3htu9l5RSZMTjmvMz9pY08Ye sVI728dfc5v5TWyXt1mRV65DP6wXq6_eviVq6.h671qOXXTHjH.4N89B6b0CvP3sle476M_3C_4R ut40.UPQP50vzyiADOWJom.q.uDw1BsAcWOtehgxD07MnHvEySIhXY5cFqanuuiVCLN99f0xpF0b qTzCL7h_ERYBBsXSK6tXXVz7sgJ.yNM6JeKGGoxL8VInilNTco5HioDeYITzSPO26j3stWceyAEY _K.sWCkvTMr7q3mg2Ba3UWg2wM_JH5HXs8QHfMfU.XNPj_a2lzGnDfDIqrqlcjNayzTQZH9FY2Bm Fc_ZPthiB6GrjXFp8Cg0NttulPHTn4FaXsmA78ZGR2w6AId2JDvmd5etMGvZqgifMTpfADddhKtu 2pfxYM8pSZK9j6xVns0f_sPsKiz619OE.Nn6_zD_JetS6G.Zo9jNnhx.DBlQss1Toj32cF8YzAtq TPAvlr8_RjENICZbQa3BRC5HzofpFKtS1ukWgAXEVc7REXvJ0nHoKPbESDma2fcqhmSWvqU9WXyx K_JR6YsSaBNv18Q3S92iq1XPpNz.y6T9txO72m3LnWaXT0TOaLRu1royrK83YACdLbEoiwPdeGKw iif0W3gVjE0KUtfPB9g5wpIokML6nG0.ULShTrQy6uTW88MlGfBQVc4brLnZzn.nJACDM02hmYBm c2J0AgD4aU06Oo5mwMW0ZeR64kDp5DrsVS5qaNB2OaINYcGhPiCiq.McWQ_iPHv8XpPesJxc6w9c nT8O2a_rgP7jiNs9QH9IWOIw19dAYhuV7tw2sV86C2uO7jgY_4SM6w8zrBm6GZz_iDr17oiXBcNs ar5tlueAjgGujWLV22oxZhH3JI9fldYRNGZjQ4vBurJdMncL9dL4NZMO3gKGQqcamqidxpsCGd16 bkqoyBd_100SPjlh_nG0omPOUSungLbelEa5h7SDQHHSvzcfpbAw.zxwp0tfwgdaMZPYB0e8dLix nX2kO9XEjQ2fOWM74Rq34i.0tG9fO34mPBBW6fZoYETADpnjNIz83AHYDLQleRLMa28b1JdiwSZc ETuvFiqR3642PqhN1nWjl4NAvCQZ736cNd2A4v_ohUTNWkX.utOvQ_nkIhuHutJx2lkOORl3IG2q zeReTy31SzthaRQ4GPty3GUmLV3eDljRLtin3K6ARYzyaoAUCEJ.muYI_f1jZHlRcckQKsJdN1x3 p0Onj6M2IhhhcbR1BDPACkgGFgRj2SMmb1iTV.9HceMaDDIQghXggUG.FwvzA.Bsr29Vjbew5E7A 3u3c2UzUf.RSYiOz0tnW65dGzxSB4BImizzjW54GH5Vf2m1rWRzvKjR7IERBCJung3S40jt9hQ3P ReZoBKzbs8h6fWb0IgAkCwx8PZE_Hh_hO..Erzhx0cDlDLfproHA6yYWQUZ3Ut4Qc_H5r2X5nFsM YktYEfdHx4CocFzK3vGgyAML0rH8ozzYilCCetQE0RRAJxaGfCP4rZe0jhr4iUkF3CVsZsQt5P5r gVZQx1iYzDibeLLcr1M2XB.9aAPwhb87dXmKOXm3HkI6f4IFrWvoR.xO3qiOP3u5_Cl7etxZ.VxM a_7pkAwbWPz7HHli1kcRWdxQ689Ux4wk7EE1t13pwEFiHAaOpYtUPomiHYQ2F9GpmAuC1nAphjBv v70611IEBIVh0yRl.psXTkA9JklgpbLdZw.4.79m.5e8Spk3HOhVy7QxKDfA1E46D2VbwHfGfO_W 85FG41x03yirj__BURppzuxydJJpBJir5PaS8aJUkmdR16psqIjM6eVKsTjFfuCVNewcs6JZ00_H 3Qpq.8H3mPP1Zhwq2ZyyGQ_cBxsse.pNaAsH5kDiIP7c- X-Sonic-MF: X-Sonic-ID: 151ffe51-7462-4e96-b94f-b0a50efb0b54 Received: from sonic.gate.mail.ne1.yahoo.com by sonic314.consmr.mail.ne1.yahoo.com with HTTP; Mon, 14 Oct 2024 15:15:01 +0000 Received: by hermes--production-gq1-5d95dc458-4tw7n (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID 6c392927ea0eb898578ed262d71f570d; Mon, 14 Oct 2024 15:14:55 +0000 (UTC) From: Casey Schaufler To: casey@schaufler-ca.com, paul@paul-moore.com, linux-security-module@vger.kernel.org Cc: jmorris@namei.org, serge@hallyn.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, stephen.smalley.work@gmail.com, linux-kernel@vger.kernel.org, selinux@vger.kernel.org, mic@digikod.net, linux-integrity@vger.kernel.org, netdev@vger.kernel.org, audit@vger.kernel.org, netfilter-devel@vger.kernel.org, linux-nfs@vger.kernel.org, Todd Kjos Subject: [PATCH v2 1/6] LSM: Ensure the correct LSM context releaser Date: Mon, 14 Oct 2024 08:14:45 -0700 Message-ID: <20241014151450.73674-2-casey@schaufler-ca.com> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20241014151450.73674-1-casey@schaufler-ca.com> References: <20241014151450.73674-1-casey@schaufler-ca.com> Precedence: bulk X-Mailing-List: linux-security-module@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add a new lsm_context 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. Update security_release_secctx() to use the lsm_context instead of a (char *, len) pair. Change its callers to do likewise. The LSMs supporting this hook have had comments added to remind the developer that there is more work to be done. The BPF security module provides all LSM hooks. While there has yet to be a known instance of a BPF configuration that uses security contexts, the possibility is real. In the existing implementation there is potential for multiple frees in that case. Signed-off-by: Casey Schaufler Cc: linux-integrity@vger.kernel.org Cc: netdev@vger.kernel.org Cc: audit@vger.kernel.org Cc: netfilter-devel@vger.kernel.org To: Pablo Neira Ayuso Cc: linux-nfs@vger.kernel.org Cc: Todd Kjos Reviewed-by: Serge Hallyn --- drivers/android/binder.c | 24 ++++++------- fs/ceph/xattr.c | 6 +++- fs/nfs/nfs4proc.c | 8 +++-- fs/nfsd/nfs4xdr.c | 8 +++-- include/linux/lsm_hook_defs.h | 2 +- include/linux/security.h | 35 +++++++++++++++++-- include/net/scm.h | 11 +++--- kernel/audit.c | 30 ++++++++--------- kernel/auditsc.c | 23 +++++++------ net/ipv4/ip_sockglue.c | 10 +++--- net/netfilter/nf_conntrack_netlink.c | 10 +++--- net/netfilter/nf_conntrack_standalone.c | 9 +++-- net/netfilter/nfnetlink_queue.c | 13 ++++--- net/netlabel/netlabel_unlabeled.c | 45 +++++++++++-------------- net/netlabel/netlabel_user.c | 11 +++--- security/apparmor/include/secid.h | 2 +- security/apparmor/secid.c | 11 ++++-- security/security.c | 8 ++--- security/selinux/hooks.c | 11 ++++-- 19 files changed, 167 insertions(+), 110 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 978740537a1a..d4229bf6f789 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -3011,8 +3011,7 @@ static void binder_transaction(struct binder_proc *proc, struct binder_context *context = proc->context; int t_debug_id = atomic_inc_return(&binder_last_id); ktime_t t_start_time = ktime_get(); - char *secctx = NULL; - u32 secctx_sz = 0; + struct lsm_context lsmctx; struct list_head sgc_head; struct list_head pf_head; const void __user *user_buffer = (const void __user *) @@ -3291,7 +3290,8 @@ static void binder_transaction(struct binder_proc *proc, size_t added_size; security_cred_getsecid(proc->cred, &secid); - ret = security_secid_to_secctx(secid, &secctx, &secctx_sz); + ret = security_secid_to_secctx(secid, &lsmctx.context, + &lsmctx.len); if (ret) { binder_txn_error("%d:%d failed to get security context\n", thread->pid, proc->pid); @@ -3300,7 +3300,7 @@ static void binder_transaction(struct binder_proc *proc, 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) { binder_txn_error("%d:%d integer overflow of extra_buffers_size\n", @@ -3334,23 +3334,23 @@ 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 = 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); } - security_release_secctx(secctx, secctx_sz); - secctx = NULL; + security_release_secctx(&lsmctx); + lsmctx.context = NULL; } t->buffer->debug_id = t->debug_id; t->buffer->transaction = t; @@ -3394,7 +3394,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)) { @@ -3773,8 +3773,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) - security_release_secctx(secctx, secctx_sz); + if (lsmctx.context) + security_release_secctx(&lsmctx); 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 e066a556eccb..f7996770cc2c 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c @@ -1446,12 +1446,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 lsm_context 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 #ifdef CONFIG_FS_ENCRYPTION kfree(as_ctx->fscrypt_auth); diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index cd2fbde2e6d7..76776d716744 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -138,8 +138,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 lsm_context 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 f118921250c3..537ad363d70a 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -3653,8 +3653,12 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr, out: #ifdef CONFIG_NFSD_V4_SECURITY_LABEL - if (args.context) - security_release_secctx(args.context, args.contextlen); + if (args.context) { + struct lsm_context scaff; /* scaffolding */ + + lsmcontext_init(&scaff, args.context, args.contextlen, 0); + security_release_secctx(&scaff); + } #endif /* CONFIG_NFSD_V4_SECURITY_LABEL */ kfree(args.acl); if (tempfh) { diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index eb2937599cb0..c13df23132eb 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -300,7 +300,7 @@ LSM_HOOK(int, -EOPNOTSUPP, secid_to_secctx, u32 secid, char **secdata, LSM_HOOK(int, -EOPNOTSUPP, lsmprop_to_secctx, struct lsm_prop *prop, char **secdata, u32 *seclen) LSM_HOOK(int, 0, secctx_to_secid, const char *secdata, u32 seclen, u32 *secid) -LSM_HOOK(void, LSM_RET_VOID, release_secctx, char *secdata, u32 seclen) +LSM_HOOK(void, LSM_RET_VOID, release_secctx, struct lsm_context *cp) LSM_HOOK(void, LSM_RET_VOID, inode_invalidate_secctx, struct inode *inode) LSM_HOOK(int, 0, inode_notifysecctx, struct inode *inode, void *ctx, u32 ctxlen) LSM_HOOK(int, 0, inode_setsecctx, struct dentry *dentry, void *ctx, u32 ctxlen) diff --git a/include/linux/security.h b/include/linux/security.h index fd690fa73162..1a3ca02224e8 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -225,6 +225,37 @@ extern unsigned long dac_mmap_min_addr; #define dac_mmap_min_addr 0UL #endif +/* + * 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 lsm_context { + char *context; /* Provided by the module */ + u32 len; + int id; /* 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 + * @id: Which LSM provided the context + * + * Fill in the lsmcontext from the provided information. + * This is a scaffolding function that will be removed when + * lsm_context integration is complete. + */ +static inline void lsmcontext_init(struct lsm_context *cp, char *context, + u32 size, int id) +{ + cp->id = id; + cp->context = context; + cp->len = size; +} + /* * Values used in the task_security_ops calls */ @@ -556,7 +587,7 @@ int security_ismaclabel(const char *name); int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen); int security_lsmprop_to_secctx(struct lsm_prop *prop, char **secdata, u32 *seclen); int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid); -void security_release_secctx(char *secdata, u32 seclen); +void security_release_secctx(struct lsm_context *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); @@ -1545,7 +1576,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 lsm_context *cp) { } diff --git a/include/net/scm.h b/include/net/scm.h index 0d35c7c77a74..f75449e1d876 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -105,16 +105,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) { - char *secdata; - u32 seclen; + struct lsm_context ctx; int err; if (test_bit(SOCK_PASSSEC, &sock->flags)) { - err = security_secid_to_secctx(scm->secid, &secdata, &seclen); + err = security_secid_to_secctx(scm->secid, &ctx.context, + &ctx.len); if (!err) { - put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, secdata); - security_release_secctx(secdata, seclen); + put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, ctx.len, + ctx.context); + security_release_secctx(&ctx); } } } diff --git a/kernel/audit.c b/kernel/audit.c index d2797e8fe182..bafd8fd2b1f3 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1221,8 +1221,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; - char *ctx = NULL; - u32 len; + struct lsm_context lsmctx; err = audit_netlink_ok(skb, msg_type); if (err) @@ -1472,27 +1471,29 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh, break; } case AUDIT_SIGNAL_INFO: - len = 0; if (lsmprop_is_set(&audit_sig_lsm)) { - err = security_lsmprop_to_secctx(&audit_sig_lsm, &ctx, - &len); + err = security_lsmprop_to_secctx(&audit_sig_lsm, + &lsmctx.context, + &lsmctx.len); if (err) return err; } - sig_data = kmalloc(struct_size(sig_data, ctx, len), GFP_KERNEL); + sig_data = kmalloc(struct_size(sig_data, ctx, lsmctx.len), + GFP_KERNEL); if (!sig_data) { if (lsmprop_is_set(&audit_sig_lsm)) - security_release_secctx(ctx, len); + security_release_secctx(&lsmctx); return -ENOMEM; } sig_data->uid = from_kuid(&init_user_ns, audit_sig_uid); sig_data->pid = audit_sig_pid; if (lsmprop_is_set(&audit_sig_lsm)) { - memcpy(sig_data->ctx, ctx, len); - security_release_secctx(ctx, len); + memcpy(sig_data->ctx, lsmctx.context, lsmctx.len); + security_release_secctx(&lsmctx); } audit_send_reply(skb, seq, AUDIT_SIGNAL_INFO, 0, 0, - sig_data, struct_size(sig_data, ctx, len)); + sig_data, struct_size(sig_data, ctx, + lsmctx.len)); kfree(sig_data); break; case AUDIT_TTY_GET: { @@ -2180,23 +2181,22 @@ void audit_log_key(struct audit_buffer *ab, char *key) int audit_log_task_context(struct audit_buffer *ab) { struct lsm_prop prop; - char *ctx = NULL; - unsigned len; + struct lsm_context ctx; int error; security_current_getlsmprop_subj(&prop); if (!lsmprop_is_set(&prop)) return 0; - error = security_lsmprop_to_secctx(&prop, &ctx, &len); + error = security_lsmprop_to_secctx(&prop, &ctx.context, &ctx.len); if (error) { if (error != -EINVAL) goto error_path; return 0; } - audit_log_format(ab, " subj=%s", ctx); - security_release_secctx(ctx, len); + audit_log_format(ab, " subj=%s", ctx.context); + security_release_secctx(&ctx); return 0; error_path: diff --git a/kernel/auditsc.c b/kernel/auditsc.c index f28fd513d047..c196dd4c9b54 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -1098,8 +1098,7 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, char *comm) { struct audit_buffer *ab; - char *ctx = NULL; - u32 len; + struct lsm_context ctx; int rc = 0; ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID); @@ -1110,12 +1109,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 (lsmprop_is_set(prop)) { - if (security_lsmprop_to_secctx(prop, &ctx, &len)) { + if (security_lsmprop_to_secctx(prop, &ctx.context, &ctx.len)) { audit_log_format(ab, " obj=(none)"); rc = 1; } else { - audit_log_format(ab, " obj=%s", ctx); - security_release_secctx(ctx, len); + audit_log_format(ab, " obj=%s", ctx.context); + security_release_secctx(&ctx); } } audit_log_format(ab, " ocomm="); @@ -1371,6 +1370,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 lsm_context lsmcxt; struct audit_buffer *ab; int i; @@ -1401,7 +1401,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) { @@ -1560,15 +1561,15 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n, MAJOR(n->rdev), MINOR(n->rdev)); if (lsmprop_is_set(&n->oprop)) { - char *ctx = NULL; - u32 len; + struct lsm_context ctx; - if (security_lsmprop_to_secctx(&n->oprop, &ctx, &len)) { + if (security_lsmprop_to_secctx(&n->oprop, &ctx.context, + &ctx.len)) { if (call_panic) *call_panic = 2; } else { - audit_log_format(ab, " obj=%s", ctx); - security_release_secctx(ctx, len); + audit_log_format(ab, " obj=%s", ctx.context); + security_release_secctx(&ctx); } } diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index cf377377b52d..a8180dcc2a32 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -128,20 +128,20 @@ 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) { - char *secdata; - u32 seclen, secid; + struct lsm_context ctx; + u32 secid; int err; err = security_socket_getpeersec_dgram(NULL, skb, &secid); if (err) return; - err = security_secid_to_secctx(secid, &secdata, &seclen); + err = security_secid_to_secctx(secid, &ctx.context, &ctx.len); if (err) return; - put_cmsg(msg, SOL_IP, SCM_SECURITY, seclen, secdata); - security_release_secctx(secdata, seclen); + put_cmsg(msg, SOL_IP, SCM_SECURITY, ctx.len, ctx.context); + security_release_secctx(&ctx); } 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 6a1239433830..86a57a3afdd6 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -357,10 +357,10 @@ 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; + struct lsm_context ctx; + int ret; - ret = security_secid_to_secctx(ct->secmark, &secctx, &len); + ret = security_secid_to_secctx(ct->secmark, &ctx.context, &ctx.len); if (ret) return 0; @@ -369,13 +369,13 @@ 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, ctx.context)) goto nla_put_failure; nla_nest_end(skb, nest_secctx); ret = 0; nla_put_failure: - security_release_secctx(secctx, len); + security_release_secctx(&ctx); return ret; } #else diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index 7d4f0fa8b609..5f7fd23b7afe 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -172,17 +172,16 @@ static void ct_seq_stop(struct seq_file *s, void *v) #ifdef CONFIG_NF_CONNTRACK_SECMARK static void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) { + struct lsm_context ctx; int ret; - u32 len; - char *secctx; - ret = security_secid_to_secctx(ct->secmark, &secctx, &len); + ret = security_secid_to_secctx(ct->secmark, &ctx.context, &ctx.len); if (ret) return; - seq_printf(s, "secctx=%s ", secctx); + seq_printf(s, "secctx=%s ", ctx.context); - security_release_secctx(secctx, len); + security_release_secctx(&ctx); } #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 d2773ce9b585..37757cd77cf1 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -567,6 +567,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 lsm_context scaff; /* scaffolding */ char *secdata = NULL; u32 seclen = 0; ktime_t tstamp; @@ -810,8 +811,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: @@ -819,8 +822,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 1bc2d0890a9f..8303bbcfc543 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -374,8 +374,7 @@ int netlbl_unlhsh_add(struct net *net, struct net_device *dev; struct netlbl_unlhsh_iface *iface; struct audit_buffer *audit_buf = NULL; - char *secctx = NULL; - u32 secctx_len; + struct lsm_context ctx; if (addr_len != sizeof(struct in_addr) && addr_len != sizeof(struct in6_addr)) @@ -438,11 +437,10 @@ int netlbl_unlhsh_add(struct net *net, unlhsh_add_return: rcu_read_unlock(); if (audit_buf != NULL) { - if (security_secid_to_secctx(secid, - &secctx, - &secctx_len) == 0) { - audit_log_format(audit_buf, " sec_obj=%s", secctx); - security_release_secctx(secctx, secctx_len); + if (security_secid_to_secctx(secid, &ctx.context, + &ctx.len) == 0) { + audit_log_format(audit_buf, " sec_obj=%s", ctx.context); + security_release_secctx(&ctx); } audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0); audit_log_end(audit_buf); @@ -473,8 +471,7 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, struct netlbl_unlhsh_addr4 *entry; struct audit_buffer *audit_buf; struct net_device *dev; - char *secctx; - u32 secctx_len; + struct lsm_context ctx; spin_lock(&netlbl_unlhsh_lock); list_entry = netlbl_af4list_remove(addr->s_addr, mask->s_addr, @@ -494,10 +491,10 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, addr->s_addr, mask->s_addr); dev_put(dev); if (entry != NULL && - security_secid_to_secctx(entry->secid, - &secctx, &secctx_len) == 0) { - audit_log_format(audit_buf, " sec_obj=%s", secctx); - security_release_secctx(secctx, secctx_len); + security_secid_to_secctx(entry->secid, &ctx.context, + &ctx.len) == 0) { + audit_log_format(audit_buf, " sec_obj=%s", ctx.context); + security_release_secctx(&ctx); } audit_log_format(audit_buf, " res=%u", entry != NULL ? 1 : 0); audit_log_end(audit_buf); @@ -534,8 +531,7 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, struct netlbl_unlhsh_addr6 *entry; struct audit_buffer *audit_buf; struct net_device *dev; - char *secctx; - u32 secctx_len; + struct lsm_context ctx; spin_lock(&netlbl_unlhsh_lock); list_entry = netlbl_af6list_remove(addr, mask, &iface->addr6_list); @@ -554,10 +550,10 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, addr, mask); dev_put(dev); if (entry != NULL && - security_secid_to_secctx(entry->secid, - &secctx, &secctx_len) == 0) { - audit_log_format(audit_buf, " sec_obj=%s", secctx); - security_release_secctx(secctx, secctx_len); + security_secid_to_secctx(entry->secid, &ctx.context, + &ctx.len) == 0) { + audit_log_format(audit_buf, " sec_obj=%s", ctx.context); + security_release_secctx(&ctx); } audit_log_format(audit_buf, " res=%u", entry != NULL ? 1 : 0); audit_log_end(audit_buf); @@ -1069,10 +1065,9 @@ 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 lsm_context ctx; void *data; u32 secid; - char *secctx; - u32 secctx_len; data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).portid, cb_arg->seq, &netlbl_unlabel_gnl_family, @@ -1127,14 +1122,14 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, secid = addr6->secid; } - ret_val = security_secid_to_secctx(secid, &secctx, &secctx_len); + ret_val = security_secid_to_secctx(secid, &ctx.context, &ctx.len); if (ret_val != 0) goto list_cb_failure; ret_val = nla_put(cb_arg->skb, NLBL_UNLABEL_A_SECCTX, - secctx_len, - secctx); - security_release_secctx(secctx, secctx_len); + ctx.len, + ctx.context); + security_release_secctx(&ctx); if (ret_val != 0) goto list_cb_failure; diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c index 81635a13987b..f5e7a9919df1 100644 --- a/net/netlabel/netlabel_user.c +++ b/net/netlabel/netlabel_user.c @@ -84,8 +84,7 @@ struct audit_buffer *netlbl_audit_start_common(int type, struct netlbl_audit *audit_info) { struct audit_buffer *audit_buf; - char *secctx; - u32 secctx_len; + struct lsm_context ctx; if (audit_enabled == AUDIT_OFF) return NULL; @@ -99,10 +98,10 @@ struct audit_buffer *netlbl_audit_start_common(int type, audit_info->sessionid); if (lsmprop_is_set(&audit_info->prop) && - security_lsmprop_to_secctx(&audit_info->prop, &secctx, - &secctx_len) == 0) { - audit_log_format(audit_buf, " subj=%s", secctx); - security_release_secctx(secctx, secctx_len); + security_lsmprop_to_secctx(&audit_info->prop, &ctx.context, + &ctx.len) == 0) { + audit_log_format(audit_buf, " subj=%s", ctx.context); + security_release_secctx(&ctx); } return audit_buf; diff --git a/security/apparmor/include/secid.h b/security/apparmor/include/secid.h index cc6d1c9f4a47..8b92f90b6921 100644 --- a/security/apparmor/include/secid.h +++ b/security/apparmor/include/secid.h @@ -29,7 +29,7 @@ int apparmor_secid_to_secctx(u32 secid, char **secdata, u32 *seclen); int apparmor_lsmprop_to_secctx(struct lsm_prop *prop, char **secdata, u32 *seclen); int apparmor_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid); -void apparmor_release_secctx(char *secdata, u32 seclen); +void apparmor_release_secctx(struct lsm_context *cp); int aa_alloc_secid(struct aa_label *label, gfp_t gfp); diff --git a/security/apparmor/secid.c b/security/apparmor/secid.c index 6350d107013a..8d9ced8cdffd 100644 --- a/security/apparmor/secid.c +++ b/security/apparmor/secid.c @@ -120,9 +120,16 @@ int apparmor_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) return 0; } -void apparmor_release_secctx(char *secdata, u32 seclen) +void apparmor_release_secctx(struct lsm_context *cp) { - kfree(secdata); + /* + * stacking scaffolding: + * When it is possible for more than one LSM to provide a + * release hook, do this check: + * if (cp->id == LSM_ID_APPARMOR || cp->id == LSM_ID_UNDEF) + */ + + kfree(cp->context); } /** diff --git a/security/security.c b/security/security.c index 0003d5ace5cc..0c9c3a02704b 100644 --- a/security/security.c +++ b/security/security.c @@ -4365,14 +4365,14 @@ EXPORT_SYMBOL(security_secctx_to_secid); /** * security_release_secctx() - Free a secctx buffer - * @secdata: secctx - * @seclen: length of secctx + * @cp: the security context * * Release the security context. */ -void security_release_secctx(char *secdata, u32 seclen) +void security_release_secctx(struct lsm_context *cp) { - call_void_hook(release_secctx, secdata, seclen); + call_void_hook(release_secctx, cp); + memset(cp, 0, sizeof(*cp)); } EXPORT_SYMBOL(security_release_secctx); diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 025b60c5b605..1503d398c87d 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -6624,9 +6624,16 @@ static int selinux_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) secid, GFP_KERNEL); } -static void selinux_release_secctx(char *secdata, u32 seclen) +static void selinux_release_secctx(struct lsm_context *cp) { - kfree(secdata); + /* + * stacking scaffolding: + * When it is possible for more than one LSM to provide a + * release hook, do this check: + * if (cp->id == LSM_ID_SELINUX || cp->id == LSM_ID_UNDEF) + */ + + kfree(cp->context); } static void selinux_inode_invalidate_secctx(struct inode *inode) From patchwork Mon Oct 14 15:14:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 13835217 X-Patchwork-Delegate: paul@paul-moore.com Received: from sonic314-26.consmr.mail.ne1.yahoo.com (sonic314-26.consmr.mail.ne1.yahoo.com [66.163.189.152]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B3E431CF7B0 for ; Mon, 14 Oct 2024 15:15:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=66.163.189.152 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728918912; cv=none; b=U9kMrigeh0HOV4kN0CK/W3n33VAQ7NXhlCG+SFjMml7uxwcBuF9o1OY9Vcj/GeKJuV5sLQ9yq2HFOkT4YWvfOFXuXpcsbRuPJ5TN5yt8sdMtfOSI5xijAoPzBEqjRC3J/KHCr6ckxsfzSMi8zl7U6HtVcTxLBPk/eD5aVbxpa2c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728918912; c=relaxed/simple; bh=w4yTSnKE9r5Ps7xTYtGDMZjpibZez4tae5E7It+MbZA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=bzqAEauqZDZfnqawS4qvnnYcGBaCIuZuLlMHi4w3uC7AaqVbAGu4tpnr1VvfbZgG4tu07IhVvlSWNz1gcmfR5vEsMv2XQIGP+HV5RoJBCOjstVMtdKh+EuTGjoqw+ZYNv9WFf1JBI+hg9clIqX2a0yNvArjg342nBonazfZ3pno= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=schaufler-ca.com; spf=none smtp.mailfrom=schaufler-ca.com; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b=Li8xQbSb; arc=none smtp.client-ip=66.163.189.152 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=schaufler-ca.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=schaufler-ca.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="Li8xQbSb" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1728918901; bh=LtMrLSWC/CIpqiboKMENYczoqdAM2a5MXfVTzhAVYak=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=Li8xQbSbnp4FinOra326xCOwsOZI19uIFJ8/zuxyvPQcA9i/D1m+eu05zVJIt6EOzwsUPaEhG3uGqBtTJ5aaNVOBFKsQUJnhRuINlSTu41PwNMCJbM/mmJTtrXB4sN9mRnj7hIpagzDGnPH1tz8pVTIXe1lrJqPPNIy07RE3dVmYpYRX8Pv1ZF/RXTVOOD7F8uzUX06+CiqSKTWfE5gvUbkykOpE38Xs6RDFLlVHlhu9vFqzU3VhNOrQUMLSf/BQ/mDbiDZS6VZ2Pw2JcnkadJ7vf4CxOIqadZ47RGXGqCHymfo5tE9q6fPqjCxTYI07LGV47OALH5evOnn2SssTAw== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1728918901; bh=1pVT9IDNH2Cxb9jEWGtQvhoLJ1fVgfNvc+O6Y90Q+2K=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=CePw0lZ4uJtPZnN19wegwO63FLSFaNR3wBue5vu3bKe/0x7A0TGA/lfIxd47m6Pgie0K+uARePsgjUUQnc5lKiXbQi++8nca29fMLY14262sXjI2KDUuIyOp2QCyHeqTXlC9vfLVRtM6/ucEsP1ZIt8FODQXtw3FMl5ba1Eu9jF2kVXfOuxJyUVuCCbPAB8E9WPMUqMAe0oClkD+G92WyZpfy5bBEusLPS+8iFn1dTARP+cu97l9T+1SJlo01vIKRbg29vK1vTLcSAGFNnzQydn/ZO1nVjIavi8xNYeMlFE5wNpkKLDHsaAYSeNhg/JM14gcH6v+nVagVMnMssyOGQ== X-YMail-OSG: 5sn4HoMVM1nvXBZcRCfDal6NUwE0z7l7.9P1Qe7UcJeu__mHxDxaCSDZmmuW4dn 71waKm4Gm6S.MgDQZk3gd9_4yk5e2pSTsc2ucLMk1WgB8gpbTcbuFcd2Un5vo9BSpGsHGKeBcDz3 qIX1eZKXYfOe6PjcqSukn0loIv0txDhaHSPFGATRR04g33VHWF5a4NtGVzVvTfxTuYzkgwqi_YTn nSQp7Zp4h7nuj90J7c9qFbpRgDDSWJRvnXbS0T95PZ7Ci9sVlWfR1QkY4CFr4IXtZd06Sky2Y4EC PCMSaYKiFmJtsyCIWRjGTjVVxsT_xX3DMky1EbuHlDQAQ6ybUSlXzWUOkQ6pA0pi3Zrds8CIdCeB xHXfqHKnSP0C5Qdg55oWW83f.x2TznGKmNL87xtKdDP9ezCMDGFJA.dwUiuEEPoWBODTq_7XaQNg ZFHDLEaOvBw6eC58lJXLAvRZeEjhc8l8yldcf3l8wbuEsRA638yvuDIX2lPVHpp2ECTOwZ6eO76i 0UIE18HMnhdjzc2URtNObKyDL4_BjaJASUA40F2OVXOh5hikeKphbCczc5NH9N28W0KWXjUnnA2X A1ISkWQnOIwV1SrLeRRx9eXmsblmTuDnxvhI2ZKKHRJEVrVauaIYJfdI8dKB2dRKaHG5nKhnuLPx bYCrDWNw5Io0MVd3gS65usoPWt1QrAeKfNNT87K62nNS2w75BNvatM.RpGq_qzyb1MysSOmNd5tT nXrfoayhLLD_toY7h85nA2PH0u.Sf_E8mWxe5Qv_XUuKU.JKLSp8UJRnngI2ew9fZbj9bFn9y_kM yWegxKfokFGeQ1T35kvYDmaQ0MouC1SZX71cBTIBSxCtMFop8EAopKqlMFG4V.qIj2r93994qbK_ kRaj05Vf8B9MpjQmXRrHl1O7UptOIR4sQ.j71FDby94SmOeGNMBc7Ci6hjP868eGN7.kDrbZNoI3 n9xBJql.fCExmsvMLH8PqA7dpRS98V54pXlGMPYpu1nb5MoRtuRivlM4EBLuTb7sOFwiUKuw23NM kuZwA4AfCbPVpFOhwkW2qQX6rxMshgV1AkcomCgpVDsXI4ggjqzQNDzInfvB7qpS.OLoE5pgEQAh c6m.OcBvl3adKSmHLgmSb70xeC0.VBeJtIDtpOrzuSxFcQv2zTvZJ0uoN1M2M9vq4OjPLRLPChG4 qNp7Sht_8qIi7l4idsJ_I_tYGt0Yox.Uh.oGEuOsxZuhj4td9K2k8TcmNC_MJQgXON74CV0fm3zF iIqsahbhHJkmu8QiFOPDuCqZ52RgLYrjMQ9jCBPYPJS94hbVFgz6V8CuzRCSWKLzo4PK2a0xrwTx wdkqR_g9gm.RxjlJoe7ZQ2cUpxCJqmpVLv2VsifwnBa_tWWE8WlTNb1aBdPt.fXE7T05Oc4FJZbC GqfkoEeT1bdJCZoB_iyfXtCOLH_cJxOIsrVkIkiTyKGAdrxYfs.8sKGotV_Au777Km3VEDrw6YmT eZ0m3lAQZfjxlwdc0U89tczv5MSxQVSfuPJQgv12XBAYIfnjvAGKOh03ILOEs9OEUI6fHL8nQUWn Vkse0OXfTFnjM9C6PaXDwXD9JN2TvvHlJMPKWGYqxQ1ETmGX4FI2ImGXtlHnh2ZMIDI8dtuuAvpF 0HsIQ.Iwh0OC8Udg.owiWwzs69F.5wMH.goXS790UnJItX.HhnI7JPHlNbPbTc6pKX2sVSHBYfdE skfUDms6BTW6Nmd7zUZ1OYIczFZl.eMMOXUA9M_VaZgVYZ1_WE1SgAXvWsmhllWts_bSVMAjYOt6 i40wdXWDe5wSd.gf5ioJ1rMPtTQFgmqWcx2XgCPZeQjovJgnvGP7vNK35r_BOBGWKVK4okDj0A_0 KQmSuz7.Bb.gJxOdc6vu0GQN_VSTzGXkf2ZPzGO8OPkd50y_L9_C9yz3zUV4.qjl.8MdN_nW2hTQ iMyzncERVEpHr8gE4Oc4Djav5XW9y1yfGpPbUMyP3Z1FVmwuYJFi.dS2PnAZyLH3xZaDDDC.UZUi 1QRJpdFSWJ.uuYhwYE3laFBvNGP3RsghVmY79AzYURL_qSd98kC6GLBU8Dr1cJHyhTrwgFn5dya4 EGhbXWVlKxAiuj8dQ94st69P91ulws5L0upCVghtdOSlUTVQuTYhZxaLJvWMbhY0wFgAZPzOm9yl aCe1j_PQjlw40zKqTLzDjS2Lo0w5WVFMzQ3x52twN4EmCx6x3Y0tvccabE9YcIA_CDf.LZblk2ox H3uJrYzENF2buUVMIKjTD_ULYUVXRb8sSgd8BQDWuEyulSGhF4Tccgv_9dhGJasXVdTQ.a_ju2Zx fHcb0HQZXx4ewpEvmruFz26SRJeV8tsBvwMYYafDOWlc- X-Sonic-MF: X-Sonic-ID: c2c474dc-baa9-4f6d-80cd-664a9fe9fbd7 Received: from sonic.gate.mail.ne1.yahoo.com by sonic314.consmr.mail.ne1.yahoo.com with HTTP; Mon, 14 Oct 2024 15:15:01 +0000 Received: by hermes--production-gq1-5d95dc458-4tw7n (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID 6c392927ea0eb898578ed262d71f570d; Mon, 14 Oct 2024 15:14:57 +0000 (UTC) From: Casey Schaufler To: casey@schaufler-ca.com, paul@paul-moore.com, linux-security-module@vger.kernel.org Cc: jmorris@namei.org, serge@hallyn.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, stephen.smalley.work@gmail.com, linux-kernel@vger.kernel.org, selinux@vger.kernel.org, mic@digikod.net, netdev@vger.kernel.org, audit@vger.kernel.org, netfilter-devel@vger.kernel.org, Todd Kjos Subject: [PATCH v2 2/6] LSM: Replace context+len with lsm_context Date: Mon, 14 Oct 2024 08:14:46 -0700 Message-ID: <20241014151450.73674-3-casey@schaufler-ca.com> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20241014151450.73674-1-casey@schaufler-ca.com> References: <20241014151450.73674-1-casey@schaufler-ca.com> Precedence: bulk X-Mailing-List: linux-security-module@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Replace the (secctx,seclen) pointer pair with a single lsm_context 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. security_secid_to_secctx() and security_lsmproc_to_secctx() will now return the length value on success instead of 0. Signed-off-by: Casey Schaufler Cc: netdev@vger.kernel.org Cc: audit@vger.kernel.org Cc: netfilter-devel@vger.kernel.org Cc: Todd Kjos --- drivers/android/binder.c | 5 ++- include/linux/lsm_hook_defs.h | 5 ++- include/linux/security.h | 9 +++--- include/net/scm.h | 5 ++- kernel/audit.c | 9 +++--- kernel/auditsc.c | 16 ++++------ net/ipv4/ip_sockglue.c | 4 +-- net/netfilter/nf_conntrack_netlink.c | 8 ++--- net/netfilter/nf_conntrack_standalone.c | 4 +-- net/netfilter/nfnetlink_queue.c | 27 +++++++--------- net/netlabel/netlabel_unlabeled.c | 13 +++----- net/netlabel/netlabel_user.c | 3 +- security/apparmor/include/secid.h | 5 ++- security/apparmor/secid.c | 26 +++++++-------- security/security.c | 34 +++++++++----------- security/selinux/hooks.c | 23 +++++++++++--- security/smack/smack_lsm.c | 42 +++++++++++++++---------- 17 files changed, 118 insertions(+), 120 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index d4229bf6f789..5cec5b52bd4a 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -3290,9 +3290,8 @@ static void binder_transaction(struct binder_proc *proc, size_t added_size; security_cred_getsecid(proc->cred, &secid); - ret = security_secid_to_secctx(secid, &lsmctx.context, - &lsmctx.len); - if (ret) { + ret = security_secid_to_secctx(secid, &lsmctx); + if (ret < 0) { binder_txn_error("%d:%d failed to get security context\n", thread->pid, proc->pid); return_error = BR_FAILED_REPLY; diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index c13df23132eb..01e5a8e09bba 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -295,10 +295,9 @@ LSM_HOOK(int, -EINVAL, getprocattr, struct task_struct *p, const char *name, char **value) LSM_HOOK(int, -EINVAL, setprocattr, const char *name, void *value, size_t size) LSM_HOOK(int, 0, ismaclabel, const char *name) -LSM_HOOK(int, -EOPNOTSUPP, secid_to_secctx, u32 secid, char **secdata, - u32 *seclen) +LSM_HOOK(int, -EOPNOTSUPP, secid_to_secctx, u32 secid, struct lsm_context *cp) LSM_HOOK(int, -EOPNOTSUPP, lsmprop_to_secctx, struct lsm_prop *prop, - char **secdata, u32 *seclen) + struct lsm_context *cp) LSM_HOOK(int, 0, secctx_to_secid, const char *secdata, u32 seclen, u32 *secid) LSM_HOOK(void, LSM_RET_VOID, release_secctx, struct lsm_context *cp) LSM_HOOK(void, LSM_RET_VOID, inode_invalidate_secctx, struct inode *inode) diff --git a/include/linux/security.h b/include/linux/security.h index 1a3ca02224e8..64e8b18e6ea5 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -584,8 +584,8 @@ int security_getprocattr(struct task_struct *p, int lsmid, const char *name, int security_setprocattr(int lsmid, 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_lsmprop_to_secctx(struct lsm_prop *prop, char **secdata, u32 *seclen); +int security_secid_to_secctx(u32 secid, struct lsm_context *cp); +int security_lsmprop_to_secctx(struct lsm_prop *prop, struct lsm_context *cp); int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid); void security_release_secctx(struct lsm_context *cp); void security_inode_invalidate_secctx(struct inode *inode); @@ -1557,14 +1557,13 @@ 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(u32 secid, struct lsm_context *cp) { return -EOPNOTSUPP; } static inline int security_lsmprop_to_secctx(struct lsm_prop *prop, - char **secdata, u32 *seclen) + struct lsm_context *cp) { return -EOPNOTSUPP; } diff --git a/include/net/scm.h b/include/net/scm.h index f75449e1d876..22bb49589fde 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -109,10 +109,9 @@ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct sc int err; if (test_bit(SOCK_PASSSEC, &sock->flags)) { - err = security_secid_to_secctx(scm->secid, &ctx.context, - &ctx.len); + err = security_secid_to_secctx(scm->secid, &ctx); - if (!err) { + if (err >= 0) { put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, ctx.len, ctx.context); security_release_secctx(&ctx); diff --git a/kernel/audit.c b/kernel/audit.c index bafd8fd2b1f3..5cdd9aeeb9bc 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1473,9 +1473,8 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh, case AUDIT_SIGNAL_INFO: if (lsmprop_is_set(&audit_sig_lsm)) { err = security_lsmprop_to_secctx(&audit_sig_lsm, - &lsmctx.context, - &lsmctx.len); - if (err) + &lsmctx); + if (err < 0) return err; } sig_data = kmalloc(struct_size(sig_data, ctx, lsmctx.len), @@ -2188,8 +2187,8 @@ int audit_log_task_context(struct audit_buffer *ab) if (!lsmprop_is_set(&prop)) return 0; - error = security_lsmprop_to_secctx(&prop, &ctx.context, &ctx.len); - if (error) { + error = security_lsmprop_to_secctx(&prop, &ctx); + if (error < 0) { if (error != -EINVAL) goto error_path; return 0; diff --git a/kernel/auditsc.c b/kernel/auditsc.c index c196dd4c9b54..4d3c22ba7149 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -1109,7 +1109,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 (lsmprop_is_set(prop)) { - if (security_lsmprop_to_secctx(prop, &ctx.context, &ctx.len)) { + if (security_lsmprop_to_secctx(prop, &ctx) < 0) { audit_log_format(ab, " obj=(none)"); rc = 1; } else { @@ -1370,7 +1370,6 @@ static void audit_log_time(struct audit_context *context, struct audit_buffer ** static void show_special(struct audit_context *context, int *call_panic) { - struct lsm_context lsmcxt; struct audit_buffer *ab; int i; @@ -1393,16 +1392,14 @@ static void show_special(struct audit_context *context, int *call_panic) from_kgid(&init_user_ns, context->ipc.gid), context->ipc.mode); if (lsmprop_is_set(&context->ipc.oprop)) { - char *ctx = NULL; - u32 len; + struct lsm_context lsmctx; if (security_lsmprop_to_secctx(&context->ipc.oprop, - &ctx, &len)) { + &lsmctx) < 0) { *call_panic = 1; } else { - audit_log_format(ab, " obj=%s", ctx); - lsmcontext_init(&lsmcxt, ctx, len, 0); - security_release_secctx(&lsmcxt); + audit_log_format(ab, " obj=%s", lsmctx.context); + security_release_secctx(&lsmctx); } } if (context->ipc.has_perm) { @@ -1563,8 +1560,7 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n, if (lsmprop_is_set(&n->oprop)) { struct lsm_context ctx; - if (security_lsmprop_to_secctx(&n->oprop, &ctx.context, - &ctx.len)) { + if (security_lsmprop_to_secctx(&n->oprop, &ctx) < 0) { if (call_panic) *call_panic = 2; } else { diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index a8180dcc2a32..dadbf619b20f 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -136,8 +136,8 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) if (err) return; - err = security_secid_to_secctx(secid, &ctx.context, &ctx.len); - if (err) + err = security_secid_to_secctx(secid, &ctx); + if (err < 0) return; put_cmsg(msg, SOL_IP, SCM_SECURITY, ctx.len, ctx.context); diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 86a57a3afdd6..dd74d4c67c69 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -360,8 +360,8 @@ static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct) struct lsm_context ctx; int ret; - ret = security_secid_to_secctx(ct->secmark, &ctx.context, &ctx.len); - if (ret) + ret = security_secid_to_secctx(ct->secmark, &ctx); + if (ret < 0) return 0; ret = -1; @@ -665,8 +665,8 @@ static inline int ctnetlink_secctx_size(const struct nf_conn *ct) #ifdef CONFIG_NF_CONNTRACK_SECMARK int len, ret; - ret = security_secid_to_secctx(ct->secmark, NULL, &len); - if (ret) + ret = security_secid_to_secctx(ct->secmark, NULL); + if (ret < 0) return 0; return nla_total_size(0) /* CTA_SECCTX */ diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index 5f7fd23b7afe..502cf10aab41 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -175,8 +175,8 @@ static void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) struct lsm_context ctx; int ret; - ret = security_secid_to_secctx(ct->secmark, &ctx.context, &ctx.len); - if (ret) + ret = security_secid_to_secctx(ct->secmark, &ctx); + if (ret < 0) return; seq_printf(s, "secctx=%s ", ctx.context); diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 37757cd77cf1..5110f29b2f40 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -470,18 +470,18 @@ static int nfqnl_put_sk_classid(struct sk_buff *skb, struct sock *sk) return 0; } -static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata) +static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, struct lsm_context *ctx) { u32 seclen = 0; #if IS_ENABLED(CONFIG_NETWORK_SECMARK) + 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); - + seclen = security_secid_to_secctx(skb->secmark, ctx); read_unlock_bh(&skb->sk->sk_callback_lock); #endif return seclen; @@ -567,8 +567,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 lsm_context scaff; /* scaffolding */ - char *secdata = NULL; + struct lsm_context ctx; u32 seclen = 0; ktime_t tstamp; @@ -643,8 +642,8 @@ 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) + seclen = nfqnl_get_sk_secctx(entskb, &ctx); + if (seclen >= 0) size += nla_total_size(seclen); } @@ -783,7 +782,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, if (nfqnl_put_sk_classid(skb, entskb->sk) < 0) goto nla_put_failure; - if (seclen && nla_put(skb, NFQA_SECCTX, seclen, secdata)) + if (seclen && nla_put(skb, NFQA_SECCTX, ctx.len, ctx.context)) goto nla_put_failure; if (ct && nfnl_ct->build(skb, ct, ctinfo, NFQA_CT, NFQA_CT_INFO) < 0) @@ -811,10 +810,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 (seclen >= 0) + security_release_secctx(&ctx); return skb; nla_put_failure: @@ -822,10 +819,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 (seclen >= 0) + security_release_secctx(&ctx); return NULL; } diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 8303bbcfc543..dfda9ea61971 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -437,8 +437,7 @@ int netlbl_unlhsh_add(struct net *net, unlhsh_add_return: rcu_read_unlock(); if (audit_buf != NULL) { - if (security_secid_to_secctx(secid, &ctx.context, - &ctx.len) == 0) { + if (security_secid_to_secctx(secid, &ctx) >= 0) { audit_log_format(audit_buf, " sec_obj=%s", ctx.context); security_release_secctx(&ctx); } @@ -491,8 +490,7 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, addr->s_addr, mask->s_addr); dev_put(dev); if (entry != NULL && - security_secid_to_secctx(entry->secid, &ctx.context, - &ctx.len) == 0) { + security_secid_to_secctx(entry->secid, &ctx) >= 0) { audit_log_format(audit_buf, " sec_obj=%s", ctx.context); security_release_secctx(&ctx); } @@ -550,8 +548,7 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, addr, mask); dev_put(dev); if (entry != NULL && - security_secid_to_secctx(entry->secid, &ctx.context, - &ctx.len) == 0) { + security_secid_to_secctx(entry->secid, &ctx) >= 0) { audit_log_format(audit_buf, " sec_obj=%s", ctx.context); security_release_secctx(&ctx); } @@ -1122,8 +1119,8 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, secid = addr6->secid; } - ret_val = security_secid_to_secctx(secid, &ctx.context, &ctx.len); - if (ret_val != 0) + ret_val = security_secid_to_secctx(secid, &ctx); + if (ret_val < 0) goto list_cb_failure; ret_val = nla_put(cb_arg->skb, NLBL_UNLABEL_A_SECCTX, diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c index f5e7a9919df1..0d04d23aafe7 100644 --- a/net/netlabel/netlabel_user.c +++ b/net/netlabel/netlabel_user.c @@ -98,8 +98,7 @@ struct audit_buffer *netlbl_audit_start_common(int type, audit_info->sessionid); if (lsmprop_is_set(&audit_info->prop) && - security_lsmprop_to_secctx(&audit_info->prop, &ctx.context, - &ctx.len) == 0) { + security_lsmprop_to_secctx(&audit_info->prop, &ctx) > 0) { audit_log_format(audit_buf, " subj=%s", ctx.context); security_release_secctx(&ctx); } diff --git a/security/apparmor/include/secid.h b/security/apparmor/include/secid.h index 8b92f90b6921..550a8d3ed527 100644 --- a/security/apparmor/include/secid.h +++ b/security/apparmor/include/secid.h @@ -25,9 +25,8 @@ struct aa_label; extern int apparmor_display_secid_mode; struct aa_label *aa_secid_to_label(u32 secid); -int apparmor_secid_to_secctx(u32 secid, char **secdata, u32 *seclen); -int apparmor_lsmprop_to_secctx(struct lsm_prop *prop, char **secdata, - u32 *seclen); +int apparmor_secid_to_secctx(u32 secid, struct lsm_context *cp); +int apparmor_lsmprop_to_secctx(struct lsm_prop *prop, struct lsm_context *cp); int apparmor_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid); void apparmor_release_secctx(struct lsm_context *cp); diff --git a/security/apparmor/secid.c b/security/apparmor/secid.c index 8d9ced8cdffd..5d92fc3ab8b4 100644 --- a/security/apparmor/secid.c +++ b/security/apparmor/secid.c @@ -61,23 +61,21 @@ struct aa_label *aa_secid_to_label(u32 secid) return xa_load(&aa_secids, secid); } -static int apparmor_label_to_secctx(struct aa_label *label, char **secdata, - u32 *seclen) +static int apparmor_label_to_secctx(struct aa_label *label, + struct lsm_context *cp) { /* TODO: cache secctx and ref count so we don't have to recreate */ int flags = FLAG_VIEW_SUBNS | FLAG_HIDDEN_UNCONFINED | FLAG_ABS_ROOT; int len; - AA_BUG(!seclen); - if (!label) return -EINVAL; if (apparmor_display_secid_mode) flags |= FLAG_SHOW_MODE; - if (secdata) - len = aa_label_asxprint(secdata, root_ns, label, + if (cp) + len = aa_label_asxprint(&cp->context, root_ns, label, flags, GFP_ATOMIC); else len = aa_label_snxprint(NULL, 0, root_ns, label, flags); @@ -85,26 +83,28 @@ static int apparmor_label_to_secctx(struct aa_label *label, char **secdata, if (len < 0) return -ENOMEM; - *seclen = len; + if (cp) { + cp->len = len; + cp->id = LSM_ID_APPARMOR; + } - return 0; + return len; } -int apparmor_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) +int apparmor_secid_to_secctx(u32 secid, struct lsm_context *cp) { struct aa_label *label = aa_secid_to_label(secid); - return apparmor_label_to_secctx(label, secdata, seclen); + return apparmor_label_to_secctx(label, cp); } -int apparmor_lsmprop_to_secctx(struct lsm_prop *prop, char **secdata, - u32 *seclen) +int apparmor_lsmprop_to_secctx(struct lsm_prop *prop, struct lsm_context *cp) { struct aa_label *label; label = prop->apparmor.label; - return apparmor_label_to_secctx(label, secdata, seclen); + return apparmor_label_to_secctx(label, cp); } int apparmor_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) diff --git a/security/security.c b/security/security.c index 0c9c3a02704b..914d8c8beea7 100644 --- a/security/security.c +++ b/security/security.c @@ -4309,40 +4309,36 @@ EXPORT_SYMBOL(security_ismaclabel); /** * security_secid_to_secctx() - Convert a secid to a secctx * @secid: secid - * @secdata: secctx - * @seclen: secctx length + * @cp: the LSM context * - * Convert secid to security context. If @secdata is NULL the length of the - * result will be returned in @seclen, but no @secdata will be returned. This + * Convert secid to security context. If @cp is NULL the length of the + * result will be returned, but no data will be returned. This * does mean that the length could change between calls to check the length and - * the next call which actually allocates and returns the @secdata. + * the next call which actually allocates and returns the data. * - * Return: Return 0 on success, error on failure. + * Return: Return length of data on success, error on failure. */ -int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) +int security_secid_to_secctx(u32 secid, struct lsm_context *cp) { - return call_int_hook(secid_to_secctx, secid, secdata, seclen); + return call_int_hook(secid_to_secctx, secid, cp); } EXPORT_SYMBOL(security_secid_to_secctx); /** * security_lsmprop_to_secctx() - Convert a lsm_prop to a secctx * @prop: lsm specific information - * @secdata: secctx - * @seclen: secctx length + * @cp: the LSM context * - * Convert a @prop entry to security context. If @secdata is NULL the - * length of the result will be returned in @seclen, but no @secdata - * will be returned. This does mean that the length could change between - * calls to check the length and the next call which actually allocates - * and returns the @secdata. + * Convert a @prop entry to security context. If @cp is NULL the + * length of the result will be returned. This does mean that the + * length could change between calls to check the length and the + * next call which actually allocates and returns the @cp. * - * Return: Return 0 on success, error on failure. + * Return: Return length of data on success, error on failure. */ -int security_lsmprop_to_secctx(struct lsm_prop *prop, char **secdata, - u32 *seclen) +int security_lsmprop_to_secctx(struct lsm_prop *prop, struct lsm_context *cp) { - return call_int_hook(lsmprop_to_secctx, prop, secdata, seclen); + return call_int_hook(lsmprop_to_secctx, prop, cp); } EXPORT_SYMBOL(security_lsmprop_to_secctx); diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 1503d398c87d..692735eb04aa 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -6607,15 +6607,28 @@ static int selinux_ismaclabel(const char *name) return (strcmp(name, XATTR_SELINUX_SUFFIX) == 0); } -static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) +static int selinux_secid_to_secctx(u32 secid, struct lsm_context *cp) { - return security_sid_to_context(secid, secdata, seclen); + u32 seclen; + u32 ret; + + if (cp) { + cp->id = LSM_ID_SELINUX; + ret = security_sid_to_context(secid, &cp->context, &cp->len); + if (ret < 0) + return ret; + return cp->len; + } + ret = security_sid_to_context(secid, NULL, &seclen); + if (ret < 0) + return ret; + return seclen; } -static int selinux_lsmprop_to_secctx(struct lsm_prop *prop, char **secdata, - u32 *seclen) +static int selinux_lsmprop_to_secctx(struct lsm_prop *prop, + struct lsm_context *cp) { - return selinux_secid_to_secctx(prop->selinux.secid, secdata, seclen); + return selinux_secid_to_secctx(prop->selinux.secid, cp); } static int selinux_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 0c476282e279..d52163d3dd64 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -4817,22 +4817,35 @@ static int smack_ismaclabel(const char *name) return (strcmp(name, XATTR_SMACK_SUFFIX) == 0); } +/** + * smack_to_secctx - fill a lsm_context + * @skp: Smack label + * @cp: destination + * + * Fill the passed @cp and return the length of the string + */ +static int smack_to_secctx(struct smack_known *skp, struct lsm_context *cp) +{ + int len = strlen(skp->smk_known); + + if (cp) { + cp->context = skp->smk_known; + cp->len = len; + cp->id = LSM_ID_SMACK; + } + return len; +} + /** * smack_secid_to_secctx - return the smack label for a secid * @secid: incoming integer - * @secdata: destination - * @seclen: how long it is + * @cp: destination * * Exists for networking code. */ -static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) +static int smack_secid_to_secctx(u32 secid, struct lsm_context *cp) { - struct smack_known *skp = smack_from_secid(secid); - - if (secdata) - *secdata = skp->smk_known; - *seclen = strlen(skp->smk_known); - return 0; + return smack_to_secctx(smack_from_secid(secid), cp); } /** @@ -4843,15 +4856,10 @@ static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) * * Exists for audit code. */ -static int smack_lsmprop_to_secctx(struct lsm_prop *prop, char **secdata, - u32 *seclen) +static int smack_lsmprop_to_secctx(struct lsm_prop *prop, + struct lsm_context *cp) { - struct smack_known *skp = prop->smack.skp; - - if (secdata) - *secdata = skp->smk_known; - *seclen = strlen(skp->smk_known); - return 0; + return smack_to_secctx(prop->smack.skp, cp); } /** From patchwork Mon Oct 14 15:14:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 13835215 X-Patchwork-Delegate: paul@paul-moore.com Received: from sonic314-26.consmr.mail.ne1.yahoo.com (sonic314-26.consmr.mail.ne1.yahoo.com [66.163.189.152]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D08881C3300 for ; Mon, 14 Oct 2024 15:15:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=66.163.189.152 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728918909; cv=none; b=TrkI0DyH2kEkedDHcG792/GJMTl3YQ/xu2MDvXRxUH+uFn0K+MVYbFWp1Wu/rNv0SDjAafS5hQZtgf7xvC5XD6tzTkPxtanyfvHgKXCmKfhvl/qLUSstP31rN/tpVlxOarsM/mgsdgwhymg5aBbNOv+wpA7703qfaIBU5LTgurE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728918909; c=relaxed/simple; bh=K+VmdhpCUdytTi8DRHz8Ar8BXNcPqnkXTLuH0kUYKvw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=DGzyNstJBjGDi6N13lifwVRK0ROGbM9Q8t12KyxClJbhrARzKa5T270PbH7cx9vLTAfgf7x6V3ohfBHgVnsu/LFEkfN2o1N1veoxCL1axDz+MIeYRbAYveQd0bvtA93FktmWJ9ipCqAXPYbYCKVIKz7h9GIX0y51jtvmrZ5qC8k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=schaufler-ca.com; spf=none smtp.mailfrom=schaufler-ca.com; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b=AnwpwClr; arc=none smtp.client-ip=66.163.189.152 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=schaufler-ca.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=schaufler-ca.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="AnwpwClr" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1728918906; bh=bHv1UO7IMwvV06D+Xx0bjVVo9VkCj8df8TY8GRx7WvY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=AnwpwClrX0QITEdbEATnwICi9svtdZmyMPpCOV0dtz1dgqOww/11ReP7TOESMaznIlByJFV77oVHAZhSjqN3or1uPM5q0xGtEF2l1mZJ4Sf/KjmOqzljKT7fR/b970eUcuv5ccLBRel8BmHVXXty2xxYpzoPPH2ZgNA0srTHqlhNTJXKpcOVqZZGscBOxF3+0BTSJnO97GRdSP4A0BtJXmVq16nbaenrw1KGfjLROA59TO+9HQz5KvOh1UyhbbXLWvxg+2Ioh7DnRhVsKqGHLK9lFHvL7NEV7PglpvaWeaiN1tCAnJln8L57sd2dZ84iS0ueN/cnAQm6fdnY+ACVAw== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1728918906; bh=uryQrzzfqkXuekHCcNroMy++Mp5mDKnbc8kmutQWKM9=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=mhMalrZciQej/YBEnoJfURxa1TpyoJlGtsf0hONo4ZV1/9QnlDEhKx/9YLTkyNGYsQirzrg9qD+Q+28qaK2MJpTy9TFCsZkS0RhNhvNKy4+2hDfv5VYODS6So3TyolG3dzubU11g95qqciYd/DafUA2ATDFzZntIQ44SijHD8n5Pzcm4OKCPTanp31ghbOOKe+SiM3yGU6dGhX3illgBTxCn2rB3xLrsMA2QFoQiM1nLBNuunmr3AmA8Hpp82/a6XLVRuhND2igL/pIrD5BD99BC5Mj0YAVSsX8crLCY+Rg+3VHTe9/lWxPBtlEmjPyOOzh+amYvZkeshzQ6cPWcGA== X-YMail-OSG: tVQgn74VM1mpqMr3JRXDkj5RTmwZe4nj6zHuHuNBLR9UrH_npXajnFiWOQSZJ_I FqpYAvB6jYjcUgDUNOnooNNyUgVm89uXWyOrg69EQ7vTcT6SoRDLtcNmQmrmiy.IQH.mmoh1hOp_ ZJtTVucWX99KgFJO30FACApKfOtnHav5xYCEO_9jK2nwSXxgNzmXyKuSBeZon.SGOmXwadHqhxxY 3l41VNyUZTeDMqfYZelsdSBIqSdM1KvtZ6uqthT_rFl5SC1IRUNincL6voHLoxN3EZtWSenYKB9C QU9lLBW25LKPG.geXAv8FzRniDHyeg6OXKnnwutX_O7TMCMs4iZGXYRzXMxS3zs5q_3oN8XFoTXy yuUgvAlviHedvofhKce1Mrh7SdmKfzqRee7eLzD6PzUhk5FE5m4drKHdaFXlHUoKbYAloSCB36Xd nk8EncSJZ.TGsuSZxZEk_gBYOwZapPu9J2asRf9R0AcUAkaHjkF4cjn0OPBiGUiZsN_oC56fqBZo 5zLIvPn9AUdhDujh04wqRwOPav8iAIRyHJZWHeTsRd4sM_rq_dwfoYVrAF4jxbtn7kzaamdFDvlx Ioo1NFRgcge.EFmb5uPORjserk6Vb7mbNAqHXaQ7eSVhc4uBBwsg2s7RUPGID2qwAdqkUu6QQZJ3 Q3gaIm6rQ.LEpTgZHX7EBXrQas5fnt0SbXjidibZby6dbyrd1ofusYWvsgEKolf5RneFHBK9TEt0 6vRN4CnriRUM2TfV9rjq4bNFCnrepnKvBdqUNpXZpjksasuxYN1.4exGbsHQK2X2M85WLWi.dVmO CwvzxQahLulAdTo4QBBXwoS1XUJuUqSUTRpeIEDBLR2Xs_hV6MtBtPpGJuN.IGAijzq_r0xJLlzp f2c_RjWM403I2hjiLA8W..oCbIJW_14upgdjzkJPskV_6Iu25GusAyh3s.pcm803mka3XqxgM3gV ARqKdIGsz8MFlVhwJp7y196tJsek16o6EGbWtppI9ud5zDVjGpoQAr9t2GaeQh2xs6rsqjV1qK_p fd6sPCBP2.1O8WHfQGfFJubB7U09FmNiK5gbuij9K26sxYQ.nMKVlZn0zqt1sBlEnTACwqqpdrFi Op0HuDSuIAvCV0l.FMf4pxLurODjnhpqbnwv4WkBWYN6e9iUJp0Da.F7mdOiEIsRhsYUqmjeYK.A MTVKbDuGpYiSjwDuVOcz_m7sJ4e0O9hMBJ9AnckXOwlUkVIP_MiVAeAn5BqZmGUZTifac0KItyGa LOxfjlJxfJP.C_Y0dKuNOSTlItkd6lZ0rx.Wxzpw4G_MifsIVDUtrDTMHfPRH0XZzKUqUBa9XhuE 4ADXot366RxsBEXRsR9HjmMlPjhf50IAM4lePZ8EDsSsiHMIk.P9UZwcESCd4exUkZlO5uSpPJP9 tvLhO0YSqDrWCHgPLfQMu6HAnPdSr0DCM1WvqUxInKUOWXCeaghmQRIYVLHWU7k5.pEZ1mA26mdX voJpoKLKZ5uyZeZKGAIohsUXS2IJiJIuRx9jfFJ4TIOK2SNpQ4_UrH7xoJ9PWuWs2H_pFqk1NDrc S6h1pdXP.j3N.UZoVJc_G.f5eK9Y2cXbm.w39g2rD79e3r0uHggc770hOGEt6koNkc5eHtqIQFX3 .ZSMdTvaDvuPgxNjcps_PBobkER5i_Fw6t.HwIz4nK7wBghke4.LcmcDlQzx_H502jLXlwOsS8YS 3a44BXNTRgWY8RTv3W6fX_zmdyPp2vH33OFzMzijdNVNjaXjGC5gWPjXT2UAvefj4sEbGdDZKQdo bRh9Ckb_AmMRE5VHXta1AJWYnUkdEnkmn.nscQaPB17YwyjZHqDTJauQbuokDXx78CfI4pBZDg2t GBMUqiEs_n0g2F83ho7ygbtRcduvQNOOa46qcOCLy6zq_5gQevyzb_0OuYuAvbJzcPE.NA3tNiJY OqyuDhIlpRpZg4X41mXtepgLGvzoOfdDhHTm1zMfn2qJ26WbQSRQunMiLmMtv8N0FbZzjK_CJUpL cNhGNReEXBmzn9ZJ1bx.lp0BlPiH.xAo68s8c7QpcbyykFs8owREakMdTojUUay3lPglu9ODJNel xstYN2QbcfyU9y0zeoXlGQbvREOkEdU.a25MZp3krizEjt_V6Khevtp0dQnGua8xObknjqb2YXa4 eReRLcTqrbRrKQkxZiiEwEZRumvPNmUDsoVPCpp_fA4nUeyO8mLHHbD2m5b8h2AOLT.ALovXXruY ak4RgCd28J.z6L8HhlyZBqVx8FifxExioln2UuMFiR60Nra.6YfS6mCDzaKSRmBTBpaopYTQv2G7 8ZMPG1GhHFtlmE7h7lzqES8Tm4Zm3JV6RSxEGRN4- X-Sonic-MF: X-Sonic-ID: 9387055b-7561-4f4a-bf09-95d4bce60f66 Received: from sonic.gate.mail.ne1.yahoo.com by sonic314.consmr.mail.ne1.yahoo.com with HTTP; Mon, 14 Oct 2024 15:15:06 +0000 Received: by hermes--production-gq1-5d95dc458-4tw7n (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID 6c392927ea0eb898578ed262d71f570d; Mon, 14 Oct 2024 15:15:00 +0000 (UTC) From: Casey Schaufler To: casey@schaufler-ca.com, paul@paul-moore.com, linux-security-module@vger.kernel.org Cc: jmorris@namei.org, serge@hallyn.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, stephen.smalley.work@gmail.com, linux-kernel@vger.kernel.org, selinux@vger.kernel.org, mic@digikod.net, linux-nfs@vger.kernel.org Subject: [PATCH v2 3/6] LSM: Use lsm_context in security_inode_getsecctx Date: Mon, 14 Oct 2024 08:14:47 -0700 Message-ID: <20241014151450.73674-4-casey@schaufler-ca.com> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20241014151450.73674-1-casey@schaufler-ca.com> References: <20241014151450.73674-1-casey@schaufler-ca.com> Precedence: bulk X-Mailing-List: linux-security-module@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Change the security_inode_getsecctx() interface to fill a lsm_context structure instead of data and length pointers. This provides the information about which LSM created the context so that security_release_secctx() can use the correct hook. Signed-off-by: Casey Schaufler Cc: linux-nfs@vger.kernel.org --- fs/nfsd/nfs4xdr.c | 26 ++++++++++---------------- include/linux/lsm_hook_defs.h | 4 ++-- include/linux/security.h | 5 +++-- security/security.c | 12 ++++++------ security/selinux/hooks.c | 10 ++++++---- security/smack/smack_lsm.c | 7 ++++--- 6 files changed, 31 insertions(+), 33 deletions(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 537ad363d70a..93faa238b979 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -2827,11 +2827,11 @@ static __be32 nfsd4_encode_nfsace4(struct xdr_stream *xdr, struct svc_rqst *rqst #ifdef CONFIG_NFSD_V4_SECURITY_LABEL static inline __be32 nfsd4_encode_security_label(struct xdr_stream *xdr, struct svc_rqst *rqstp, - void *context, int len) + const struct lsm_context *context) { __be32 *p; - p = xdr_reserve_space(xdr, len + 4 + 4 + 4); + p = xdr_reserve_space(xdr, context->len + 4 + 4 + 4); if (!p) return nfserr_resource; @@ -2841,13 +2841,13 @@ nfsd4_encode_security_label(struct xdr_stream *xdr, struct svc_rqst *rqstp, */ *p++ = cpu_to_be32(0); /* lfs */ *p++ = cpu_to_be32(0); /* pi */ - p = xdr_encode_opaque(p, context, len); + p = xdr_encode_opaque(p, context->context, context->len); return 0; } #else static inline __be32 nfsd4_encode_security_label(struct xdr_stream *xdr, struct svc_rqst *rqstp, - void *context, int len) + struct lsm_context *context) { return 0; } #endif @@ -2930,8 +2930,7 @@ struct nfsd4_fattr_args { struct nfs4_acl *acl; u64 size; #ifdef CONFIG_NFSD_V4_SECURITY_LABEL - void *context; - int contextlen; + struct lsm_context context; #endif u32 rdattr_err; bool contextsupport; @@ -3386,8 +3385,7 @@ static __be32 nfsd4_encode_fattr4_suppattr_exclcreat(struct xdr_stream *xdr, static __be32 nfsd4_encode_fattr4_sec_label(struct xdr_stream *xdr, const struct nfsd4_fattr_args *args) { - return nfsd4_encode_security_label(xdr, args->rqstp, - args->context, args->contextlen); + return nfsd4_encode_security_label(xdr, args->rqstp, &args->context); } #endif @@ -3538,7 +3536,7 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr, args.ignore_crossmnt = (ignore_crossmnt != 0); args.acl = NULL; #ifdef CONFIG_NFSD_V4_SECURITY_LABEL - args.context = NULL; + args.context.context = NULL; #endif /* @@ -3616,7 +3614,7 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr, attrmask[0] & FATTR4_WORD0_SUPPORTED_ATTRS) { if (exp->ex_flags & NFSEXP_SECURITY_LABEL) err = security_inode_getsecctx(d_inode(dentry), - &args.context, &args.contextlen); + &args.context); else err = -EOPNOTSUPP; args.contextsupport = (err == 0); @@ -3653,12 +3651,8 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr, out: #ifdef CONFIG_NFSD_V4_SECURITY_LABEL - if (args.context) { - struct lsm_context scaff; /* scaffolding */ - - lsmcontext_init(&scaff, args.context, args.contextlen, 0); - security_release_secctx(&scaff); - } + if (args.context.context) + security_release_secctx(&args.context); #endif /* CONFIG_NFSD_V4_SECURITY_LABEL */ kfree(args.acl); if (tempfh) { diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index 01e5a8e09bba..69e1076448c6 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -303,8 +303,8 @@ LSM_HOOK(void, LSM_RET_VOID, release_secctx, struct lsm_context *cp) LSM_HOOK(void, LSM_RET_VOID, inode_invalidate_secctx, struct inode *inode) LSM_HOOK(int, 0, inode_notifysecctx, struct inode *inode, void *ctx, u32 ctxlen) LSM_HOOK(int, 0, inode_setsecctx, struct dentry *dentry, void *ctx, u32 ctxlen) -LSM_HOOK(int, -EOPNOTSUPP, inode_getsecctx, struct inode *inode, void **ctx, - u32 *ctxlen) +LSM_HOOK(int, -EOPNOTSUPP, inode_getsecctx, struct inode *inode, + struct lsm_context *cp) #if defined(CONFIG_SECURITY) && defined(CONFIG_WATCH_QUEUE) LSM_HOOK(int, 0, post_notification, const struct cred *w_cred, diff --git a/include/linux/security.h b/include/linux/security.h index 64e8b18e6ea5..7d0adc1833ab 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -591,7 +591,7 @@ void security_release_secctx(struct lsm_context *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); -int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen); +int security_inode_getsecctx(struct inode *inode, struct lsm_context *cp); int security_locked_down(enum lockdown_reason what); int lsm_fill_user_ctx(struct lsm_ctx __user *uctx, u32 *uctx_len, void *val, size_t val_len, u64 id, u64 flags); @@ -1591,7 +1591,8 @@ static inline int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 { return -EOPNOTSUPP; } -static inline int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen) +static inline int security_inode_getsecctx(struct inode *inode, + struct lsm_context *cp) { return -EOPNOTSUPP; } diff --git a/security/security.c b/security/security.c index 914d8c8beea7..4ca3c9e28b6f 100644 --- a/security/security.c +++ b/security/security.c @@ -4431,17 +4431,17 @@ EXPORT_SYMBOL(security_inode_setsecctx); /** * security_inode_getsecctx() - Get the security label of an inode * @inode: inode - * @ctx: secctx - * @ctxlen: length of secctx + * @cp: security context * - * On success, returns 0 and fills out @ctx and @ctxlen with the security - * context for the given @inode. + * On success, returns 0 and fills out @cp with the security context + * for the given @inode. * * Return: Returns 0 on success, error on failure. */ -int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen) +int security_inode_getsecctx(struct inode *inode, struct lsm_context *cp) { - return call_int_hook(inode_getsecctx, inode, ctx, ctxlen); + memset(cp, 0, sizeof(*cp)); + return call_int_hook(inode_getsecctx, inode, cp); } EXPORT_SYMBOL(security_inode_getsecctx); diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 692735eb04aa..ce5e45abd8d3 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -6678,14 +6678,16 @@ static int selinux_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen) ctx, ctxlen, 0, NULL); } -static int selinux_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen) +static int selinux_inode_getsecctx(struct inode *inode, struct lsm_context *cp) { - int len = 0; + int len; len = selinux_inode_getsecurity(&nop_mnt_idmap, inode, - XATTR_SELINUX_SUFFIX, ctx, true); + XATTR_SELINUX_SUFFIX, + (void **)&cp->context, true); if (len < 0) return len; - *ctxlen = len; + cp->len = len; + cp->id = LSM_ID_SELINUX; return 0; } #ifdef CONFIG_KEYS diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index d52163d3dd64..c9ec4d93fb13 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -4899,12 +4899,13 @@ static int smack_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen) ctx, ctxlen, 0, NULL); } -static int smack_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen) +static int smack_inode_getsecctx(struct inode *inode, struct lsm_context *cp) { struct smack_known *skp = smk_of_inode(inode); - *ctx = skp->smk_known; - *ctxlen = strlen(skp->smk_known); + cp->context = skp->smk_known; + cp->len = strlen(skp->smk_known); + cp->id = LSM_ID_SMACK; return 0; } From patchwork Mon Oct 14 15:14:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 13835218 X-Patchwork-Delegate: paul@paul-moore.com Received: from sonic306-26.consmr.mail.ne1.yahoo.com (sonic306-26.consmr.mail.ne1.yahoo.com [66.163.189.88]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8001A1AB505 for ; Mon, 14 Oct 2024 15:16:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=66.163.189.88 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728919004; cv=none; b=HBc5SoPnNc4HkP4n2AbHYC2MQ5C3zknnOzcCdCdZ3tnNzMJQbUsrQ8YUNfZSNeSnyyWI0Pe+cTEN3RZGk0DmxMjacFPclOAZKP64b6TGaV5a9SmeqQXxuegxsE0fldNTSeF9VwtDTn212G7qywArAjP9c2MTr/8S23+Tum9ExqM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728919004; c=relaxed/simple; bh=HUumJWQSUaNDZCeF4RgqkLG4LRs1MoV8/m9sy5MSbhs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=isaxlaucxeCGgvMV1lXZc5MsU2kDb9Mm8mM7T4slOVei+anx2p6dD2GabfEMAh6un/N2kqCTWWFcrkINEur2HL+haSJMZXuxMGm6/UNASuTJ8kzDoTpbM7ZTotLXK3nMmzgPCki6Cgu4EMFJxMglzwXeEZm0Kd8ksfNRIssJ/hM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=schaufler-ca.com; spf=none smtp.mailfrom=schaufler-ca.com; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b=uXrEFiF2; arc=none smtp.client-ip=66.163.189.88 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=schaufler-ca.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=schaufler-ca.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="uXrEFiF2" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1728918996; bh=rich9NI95VqRyuq/AK+XiAj+clCh1m5ei3XEp1pQo84=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=uXrEFiF2KVx5Es9YpvvMThVXiub4EzjTys2MrN7AIPKNjsI/du+oyH+XycI3x/a/gxGaplYQCHDCLrSWVYdF4/oFwNRA9WvIGzXZVt2JBEc4UvmNENmg5QLspuYoSWRaSimf04kpvBu/N7VfWvzB4glNjSNNj7Ggn3upsdoSQ6MX8eRnhrTrUC63PAji9lP/rphgRgseqTixRHVlggYfbhV6+LEkRvdRq8I8wx/kWipKFz75gVYO+7bglV7sA6VKO9uIa1lWRwOKn5BC3vnLGPI9AjFDS4hd640vS9qBnbKx5xClvDp878IPh/+uPijcd05cIa++tCcEPae1umklDw== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1728918996; bh=LJifvuxdD18OBFc2uhTJzNCnD5tH3Ib7eDjBvF0r3kM=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=VF/K//LZcl7OsIWPH5rS+v2tNtWUSSz0dGobRucQXCPadTdGKEp83MR7JzABn87jfbVxrOk7m9aY/7+avjyvS7q3KaKEikQxiixiAc2HnPSwCnJK4/OmpjtXScfvQOsLRnHwi87Dy7M72sk+yApeO6vJ/q3UpuvETt9EW/NDosUUtkV+POQVjhiXoTfDYsqLrcWA2+07HajoGVurp5oi5p3LlOfpjELnDwMnTPSlCLU3gkN1d5JAnrmK33n10OzJHWGhveEJdjqFSQCKTE0q5NAkI88YhKhSDEuXu+c4Kbf0ev9EWVCtKLYjKj6YycSKKZTAr40HUUnpC4WT2+fFgw== X-YMail-OSG: ZVA_4GUVM1nTsr9HJQBq..0x2.vCHaqHKAxC6l0PA5ZcfRrfF1uX_6AC2x1OWIE MKtBhoVKvWZik439lF7lPZJMXYofebZrwkd4LKyaCTzrfEwI8LrzTwHMOA0aoU2sxseqtQB_D2qt 8mTN5mHFmeGLSbfDKsaodgqGqSGsuP0eafID2WfZ1nk0nRJPtPuqZSn_RokhODgxkFBqDfzfoOrn G07MBIeUMakJCW_c.yfDvJ.royGwE.7y7nCnecCZQBhc_Laiar4Lq40oqyfdagCcHCnsds5mVEnS Bpb_u6jgpZLdAB_rSMiPQ9RSD0mrkrMAd9DMoh6FJH5xkJFKOjlf3.16q8ZWLPtgzIjOrJMqe2GC q4nKyIbmhDLrykb4JYCXJ1PoTD6uao9TJ3d9GSqd0Y5yrpBrM7tJu_zglu76h0JGA8tiCKjcWAEF 59f18CPeIE3woC7FR1EISMOFE0xZr2IZ_eL.utbyYyv2ObhmhafJWJFHJ55q7xy9bOxckDPYXwXh g8U1STbvjVQxTwoY1Eo4tC0oLDn05kvjG1WRLtVeE7JT7ClOQ_yf8eW9MJOc46UwP3mGZsuLjvlG s_jNUSzuxZyOa0772W8Gl.LGlbNgQHMC507BrqsAOZwm378VG95lEwSDcIqxigWuwns11sMlJPcX KAH_uH0Z0rHx3y6FRE_J1rbzmnnQ52wSrhLX3JghGrm3pRnOg1njyTOZx5728P9Idartebo6JijE 26HJDVOUW66ZHuj3I.vternXPn1BFl5vTvYzwVIKiXIE4PLDja9vVy9hA0OCg9pIR_Tv05b9yrS6 UNIv.wYhQF0dlG8lDVA6meVMkc5S95lcdrYSY6TR_X4g0.GxC0iQp0JP0AAvIliFWSM3SjwAVGWe Zluimi6ugOENIw.GaDkDCBWJwXuOFqVyK9m6E.BJao49RFq8PlQZTZcWdMMDSX2ff9iP35Bc99zN 5TUxInazUX_feE8QJKUNRsD8mHzFhbV1N4X2IfGHLj5w4Rl93XUHFXCyjiyhOkNy.Ac4HxYdDaWj j1f1ZSIopCLs2FuBioM3iBsx5mAsGIV9BGOiWjTXyR._zpd.Uhr7Nq2iL96TUPbKjlYjBHz8gCeD alRFDVx1nRV1XoyyYLsAxPrTeL1rzJ1DZd5YFj3Ivml87nmAGAhMzlTkS8jRnwIdpOxd64eZzg_Z V8SVfafz_l1ecW4V7YYufR4y.65wlGPJN8jOOPw1G940oTtcTgb8cidWD78e7uuJHYQx_3MYjZmd EhQKTO3eMlcpXKffF40q5WRIsVoKTqSaSyt5uFfgYsxGwToz53QC_65zS74uGM5SCmyyVMbpNdML LLMHssa9oV1jGo59IihCXykN6x7cRco6UhEJspTIWFAtgWYV5nsUfJzzGf5PhL8B1i1KMCqD9YpE bFD.ViFgsLzoRauHKI6Ixneg3vN8r_hQ84MC2DMd1o9riIhoA5BYIpuEOY7uJULS5Vie.0eHZAn5 6fCWwCuqDolz3UKzJGGMDwdTl7TQReEZszl51AXdeucQ7QXBMbwEoBcnOQskgymmSMh1Ja9z8wqb dkl7ajGdUEdZ55zygbc0Dri8HrGTLMpPyiDPQs99I1fYM4OBCJveCtS3XdZlAIOZE_RjhJaqyPRi vBFQV_xkdUGsKjEYa8EhvRa8hbgABGTPJhrjWlA_zFTI574M9oXQPMDvcq6XGOuDlUwD6CSS_sRD mGuL0fSejqTnc5Oasne4lgxkvWIWZeZKk99ycwWHs5gstE0cb60fjxQvsxJwLCocXXCo7Y6Pswj9 FS2BkGFsRSnKrBRX7CIpdCxVIHgQMLIZERPXUjYefpLic2SUIryHg7..5ItqBEx.9JrwcyI1hkU6 XuIaY2Iq.vVd2dll9IGsj6gFmNZCbzRZluSlHoXypZ7AqxLrNdtA44XjcMW6jVFnYIM_rmHw_Ys9 cmTIgyyrjaTK3AXWwoJbobTHHkHfidtWQHq_xnk2_fm3j1H96A8MuaC4SgeJCfRkUShIYrx_feqd 14fMS.HPmtctllBmsODjikufECb4rdANCu6RUPhWsk9t6GRP072vYG78C0SKbXk0.BoTyX2InFJz U4QBbFfsfHfhFfySOocc1k4uu7PQPSa59Z.BAXEzCsPZcgEsbul2sQgGHwA.d9lZ738QYadjOH3H x5CryX_EXccvGfxsweOVoSU_bURsH3xqrT4jhRVkIblpPWbcefFy5M.P1vR7PXsr.SgZKfUw2xiq mtWE2ybC4Uw6FnrcxxpQF945iH_N9GxF92SNozwE7lhJvrIHNJ3Dswk_hrbkk0TH8IEjh92EW5Rb Q62TU00lBybWUZoBxCQMJS_nB3Kszvgc9vVita.vm X-Sonic-MF: X-Sonic-ID: 0be80206-6059-4897-98d4-208635396b78 Received: from sonic.gate.mail.ne1.yahoo.com by sonic306.consmr.mail.ne1.yahoo.com with HTTP; Mon, 14 Oct 2024 15:16:36 +0000 Received: by hermes--production-gq1-5d95dc458-4hqnr (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID 8dd3ed09a3dd7dbd0509b276d789cdef; Mon, 14 Oct 2024 15:16:34 +0000 (UTC) From: Casey Schaufler To: casey@schaufler-ca.com, paul@paul-moore.com, linux-security-module@vger.kernel.org Cc: jmorris@namei.org, serge@hallyn.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, stephen.smalley.work@gmail.com, linux-kernel@vger.kernel.org, selinux@vger.kernel.org, mic@digikod.net, ceph-devel@vger.kernel.org, linux-nfs@vger.kernel.org Subject: [PATCH v2 4/6] LSM: lsm_context in security_dentry_init_security Date: Mon, 14 Oct 2024 08:14:48 -0700 Message-ID: <20241014151450.73674-5-casey@schaufler-ca.com> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20241014151450.73674-1-casey@schaufler-ca.com> References: <20241014151450.73674-1-casey@schaufler-ca.com> Precedence: bulk X-Mailing-List: linux-security-module@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Replace the (secctx,seclen) pointer pair with a single lsm_context 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. Special care is taken in the NFS code, which uses the same data structure for its own copied labels as it does for the data which comes from security_dentry_init_security(). In the case of copied labels the data has to be freed, not released. The scaffolding funtion lsmcontext_init() is no longer needed and is removed. Signed-off-by: Casey Schaufler Cc: ceph-devel@vger.kernel.org Cc: linux-nfs@vger.kernel.org --- fs/ceph/super.h | 3 +-- fs/ceph/xattr.c | 16 ++++++---------- fs/fuse/dir.c | 35 ++++++++++++++++++----------------- fs/nfs/dir.c | 2 +- fs/nfs/inode.c | 17 ++++++++++------- fs/nfs/internal.h | 8 +++++--- fs/nfs/nfs4proc.c | 22 +++++++++------------- fs/nfs/nfs4xdr.c | 22 ++++++++++++---------- include/linux/lsm_hook_defs.h | 2 +- include/linux/nfs4.h | 8 ++++---- include/linux/nfs_fs.h | 2 +- include/linux/security.h | 26 +++----------------------- security/security.c | 9 ++++----- security/selinux/hooks.c | 9 +++++---- 14 files changed, 80 insertions(+), 101 deletions(-) diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 2508aa8950b7..c9fad8c825dd 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -1133,8 +1133,7 @@ struct ceph_acl_sec_ctx { void *acl; #endif #ifdef CONFIG_CEPH_FS_SECURITY_LABEL - void *sec_ctx; - u32 sec_ctxlen; + struct lsm_context lsmctx; #endif #ifdef CONFIG_FS_ENCRYPTION struct ceph_fscrypt_auth *fscrypt_auth; diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index f7996770cc2c..0b9e1f385d31 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c @@ -1383,8 +1383,7 @@ int ceph_security_init_secctx(struct dentry *dentry, umode_t mode, int err; err = security_dentry_init_security(dentry, mode, &dentry->d_name, - &name, &as_ctx->sec_ctx, - &as_ctx->sec_ctxlen); + &name, &as_ctx->lsmctx); if (err < 0) { WARN_ON_ONCE(err != -EOPNOTSUPP); err = 0; /* do nothing */ @@ -1409,7 +1408,7 @@ int ceph_security_init_secctx(struct dentry *dentry, umode_t mode, */ name_len = strlen(name); err = ceph_pagelist_reserve(pagelist, - 4 * 2 + name_len + as_ctx->sec_ctxlen); + 4 * 2 + name_len + as_ctx->lsmctx.len); if (err) goto out; @@ -1432,8 +1431,9 @@ int ceph_security_init_secctx(struct dentry *dentry, umode_t mode, ceph_pagelist_encode_32(pagelist, name_len); ceph_pagelist_append(pagelist, name, name_len); - ceph_pagelist_encode_32(pagelist, as_ctx->sec_ctxlen); - ceph_pagelist_append(pagelist, as_ctx->sec_ctx, as_ctx->sec_ctxlen); + ceph_pagelist_encode_32(pagelist, as_ctx->lsmctx.len); + ceph_pagelist_append(pagelist, as_ctx->lsmctx.context, + as_ctx->lsmctx.len); err = 0; out: @@ -1446,16 +1446,12 @@ 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 lsm_context 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 - lsmcontext_init(&scaff, as_ctx->sec_ctx, as_ctx->sec_ctxlen, 0); - security_release_secctx(&scaff); + security_release_secctx(&as_ctx->lsmctx); #endif #ifdef CONFIG_FS_ENCRYPTION kfree(as_ctx->fscrypt_auth); diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 54104dd48af7..eea4d0d27ce1 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -466,29 +466,29 @@ static int get_security_context(struct dentry *entry, umode_t mode, { struct fuse_secctx *fctx; struct fuse_secctx_header *header; - void *ctx = NULL, *ptr; - u32 ctxlen, total_len = sizeof(*header); + struct lsm_context lsmctx = { }; + void *ptr; + u32 total_len = sizeof(*header); int err, nr_ctx = 0; - const char *name; + const char *name = NULL; size_t namelen; err = security_dentry_init_security(entry, mode, &entry->d_name, - &name, &ctx, &ctxlen); - if (err) { - if (err != -EOPNOTSUPP) - goto out_err; - /* No LSM is supporting this security hook. Ignore error */ - ctxlen = 0; - ctx = NULL; - } + &name, &lsmctx); + + /* If no LSM is supporting this security hook ignore error */ + if (err && err != -EOPNOTSUPP) + goto out_err; - if (ctxlen) { + if (lsmctx.len) { nr_ctx = 1; namelen = strlen(name) + 1; err = -EIO; - if (WARN_ON(namelen > XATTR_NAME_MAX + 1 || ctxlen > S32_MAX)) + if (WARN_ON(namelen > XATTR_NAME_MAX + 1 || + lsmctx.len > S32_MAX)) goto out_err; - total_len += FUSE_REC_ALIGN(sizeof(*fctx) + namelen + ctxlen); + total_len += FUSE_REC_ALIGN(sizeof(*fctx) + namelen + + lsmctx.len); } err = -ENOMEM; @@ -501,19 +501,20 @@ static int get_security_context(struct dentry *entry, umode_t mode, ptr += sizeof(*header); if (nr_ctx) { fctx = ptr; - fctx->size = ctxlen; + fctx->size = lsmctx.len; ptr += sizeof(*fctx); strcpy(ptr, name); ptr += namelen; - memcpy(ptr, ctx, ctxlen); + memcpy(ptr, lsmctx.context, lsmctx.len); } ext->size = total_len; ext->value = header; err = 0; out_err: - kfree(ctx); + if (nr_ctx) + security_release_secctx(&lsmctx); return err; } diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 492cffd9d3d8..1813ad9e9320 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -809,7 +809,7 @@ static int nfs_readdir_entry_decode(struct nfs_readdir_descriptor *desc, int ret; if (entry->fattr->label) - entry->fattr->label->len = NFS4_MAXLABELLEN; + entry->fattr->label->lsmctx.len = NFS4_MAXLABELLEN; ret = xdr_decode(desc, entry, stream); if (ret || !desc->plus) return ret; diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 542c7d97b235..d00a6304133a 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -358,14 +358,15 @@ void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr) return; if ((fattr->valid & NFS_ATTR_FATTR_V4_SECURITY_LABEL) && inode->i_security) { - error = security_inode_notifysecctx(inode, fattr->label->label, - fattr->label->len); + error = security_inode_notifysecctx(inode, + fattr->label->lsmctx.context, + fattr->label->lsmctx.len); if (error) printk(KERN_ERR "%s() %s %d " "security_inode_notifysecctx() %d\n", __func__, - (char *)fattr->label->label, - fattr->label->len, error); + (char *)fattr->label->lsmctx.context, + fattr->label->lsmctx.len, error); nfs_clear_label_invalid(inode); } } @@ -381,12 +382,14 @@ struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags) if (label == NULL) return ERR_PTR(-ENOMEM); - label->label = kzalloc(NFS4_MAXLABELLEN, flags); - if (label->label == NULL) { + label->lsmctx.context = kzalloc(NFS4_MAXLABELLEN, flags); + if (label->lsmctx.context == NULL) { kfree(label); return ERR_PTR(-ENOMEM); } - label->len = NFS4_MAXLABELLEN; + label->lsmctx.len = NFS4_MAXLABELLEN; + /* Use an invalid LSM ID as this should never be "released". */ + label->lsmctx.id = LSM_ID_UNDEF; return label; } diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 430733e3eff2..96477a57f65a 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -355,13 +355,15 @@ nfs4_label_copy(struct nfs4_label *dst, struct nfs4_label *src) if (!dst || !src) return NULL; - if (src->len > NFS4_MAXLABELLEN) + if (src->lsmctx.len > NFS4_MAXLABELLEN) return NULL; dst->lfs = src->lfs; dst->pi = src->pi; - dst->len = src->len; - memcpy(dst->label, src->label, src->len); + /* Use an invalid LSM ID as lsmctx should never be "released" */ + dst->lsmctx.id = LSM_ID_UNDEF; + dst->lsmctx.len = src->lsmctx.len; + memcpy(dst->lsmctx.context, src->lsmctx.context, src->lsmctx.len); return dst; } diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 76776d716744..b07d01f390dc 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -124,12 +124,11 @@ nfs4_label_init_security(struct inode *dir, struct dentry *dentry, label->lfs = 0; label->pi = 0; - label->len = 0; - label->label = NULL; + label->lsmctx.len = 0; + label->lsmctx.context = NULL; err = security_dentry_init_security(dentry, sattr->ia_mode, - &dentry->d_name, NULL, - (void **)&label->label, &label->len); + &dentry->d_name, NULL, &label->lsmctx); if (err == 0) return label; @@ -138,12 +137,8 @@ nfs4_label_init_security(struct inode *dir, struct dentry *dentry, static inline void nfs4_label_release_security(struct nfs4_label *label) { - struct lsm_context scaff; /* scaffolding */ - - if (label) { - lsmcontext_init(&scaff, label->label, label->len, 0); - security_release_secctx(&scaff); - } + if (label) + security_release_secctx(&label->lsmctx); } static inline u32 *nfs4_bitmask(struct nfs_server *server, struct nfs4_label *label) { @@ -6259,7 +6254,7 @@ static int _nfs4_get_security_label(struct inode *inode, void *buf, size_t buflen) { struct nfs_server *server = NFS_SERVER(inode); - struct nfs4_label label = {0, 0, buflen, buf}; + struct nfs4_label label = {0, 0, {buf, buflen, -1} }; u32 bitmask[3] = { 0, 0, FATTR4_WORD2_SECURITY_LABEL }; struct nfs_fattr fattr = { @@ -6287,7 +6282,7 @@ static int _nfs4_get_security_label(struct inode *inode, void *buf, return ret; if (!(fattr.valid & NFS_ATTR_FATTR_V4_SECURITY_LABEL)) return -ENOENT; - return label.len; + return label.lsmctx.len; } static int nfs4_get_security_label(struct inode *inode, void *buf, @@ -6364,7 +6359,8 @@ static int nfs4_do_set_security_label(struct inode *inode, static int nfs4_set_security_label(struct inode *inode, const void *buf, size_t buflen) { - struct nfs4_label ilabel = {0, 0, buflen, (char *)buf }; + struct nfs4_label ilabel = {0, 0, + {(char *)buf, buflen, -1}}; struct nfs_fattr *fattr; int status; diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index e8ac3f615f93..61a2b0e61c66 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -1154,7 +1154,7 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, } if (label && (attrmask[2] & FATTR4_WORD2_SECURITY_LABEL)) { - len += 4 + 4 + 4 + (XDR_QUADLEN(label->len) << 2); + len += 4 + 4 + 4 + (XDR_QUADLEN(label->lsmctx.len) << 2); bmval[2] |= FATTR4_WORD2_SECURITY_LABEL; } @@ -1186,8 +1186,9 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, if (label && (bmval[2] & FATTR4_WORD2_SECURITY_LABEL)) { *p++ = cpu_to_be32(label->lfs); *p++ = cpu_to_be32(label->pi); - *p++ = cpu_to_be32(label->len); - p = xdr_encode_opaque_fixed(p, label->label, label->len); + *p++ = cpu_to_be32(label->lsmctx.len); + p = xdr_encode_opaque_fixed(p, label->lsmctx.context, + label->lsmctx.len); } if (bmval[2] & FATTR4_WORD2_MODE_UMASK) { *p++ = cpu_to_be32(iap->ia_mode & S_IALLUGO); @@ -4272,11 +4273,11 @@ static int decode_attr_security_label(struct xdr_stream *xdr, uint32_t *bitmap, return -EIO; bitmap[2] &= ~FATTR4_WORD2_SECURITY_LABEL; if (len < NFS4_MAXLABELLEN) { - if (label && label->len) { - if (label->len < len) + if (label && label->lsmctx.len) { + if (label->lsmctx.len < len) return -ERANGE; - memcpy(label->label, p, len); - label->len = len; + memcpy(label->lsmctx.context, p, len); + label->lsmctx.len = len; label->pi = pi; label->lfs = lfs; status = NFS_ATTR_FATTR_V4_SECURITY_LABEL; @@ -4284,10 +4285,11 @@ static int decode_attr_security_label(struct xdr_stream *xdr, uint32_t *bitmap, } else printk(KERN_WARNING "%s: label too long (%u)!\n", __func__, len); - if (label && label->label) + if (label && label->lsmctx.context) dprintk("%s: label=%.*s, len=%d, PI=%d, LFS=%d\n", - __func__, label->len, (char *)label->label, - label->len, label->pi, label->lfs); + __func__, label->lsmctx.len, + (char *)label->lsmctx.context, + label->lsmctx.len, label->pi, label->lfs); } return status; } diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index 69e1076448c6..e2f1ce37c41e 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -83,7 +83,7 @@ LSM_HOOK(int, 0, move_mount, const struct path *from_path, const struct path *to_path) LSM_HOOK(int, -EOPNOTSUPP, dentry_init_security, struct dentry *dentry, int mode, const struct qstr *name, const char **xattr_name, - void **ctx, u32 *ctxlen) + struct lsm_context *cp) LSM_HOOK(int, 0, dentry_create_files_as, struct dentry *dentry, int mode, struct qstr *name, const struct cred *old, struct cred *new) diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index 8d7430d9f218..22032b0f6022 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -44,10 +45,9 @@ struct nfs4_acl { #define NFS4_MAXLABELLEN 2048 struct nfs4_label { - uint32_t lfs; - uint32_t pi; - u32 len; - char *label; + uint32_t lfs; + uint32_t pi; + struct lsm_context lsmctx; }; typedef struct { char data[NFS4_VERIFIER_SIZE]; } nfs4_verifier; diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 039898d70954..47652d217d05 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -457,7 +457,7 @@ static inline void nfs4_label_free(struct nfs4_label *label) { #ifdef CONFIG_NFS_V4_SECURITY_LABEL if (label) { - kfree(label->label); + kfree(label->lsmctx.context); kfree(label); } #endif diff --git a/include/linux/security.h b/include/linux/security.h index 7d0adc1833ab..3ad59666e56c 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -237,25 +237,6 @@ struct lsm_context { int id; /* 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 - * @id: Which LSM provided the context - * - * Fill in the lsmcontext from the provided information. - * This is a scaffolding function that will be removed when - * lsm_context integration is complete. - */ -static inline void lsmcontext_init(struct lsm_context *cp, char *context, - u32 size, int id) -{ - cp->id = id; - cp->context = context; - cp->len = size; -} - /* * Values used in the task_security_ops calls */ @@ -409,8 +390,8 @@ int security_sb_clone_mnt_opts(const struct super_block *oldsb, int security_move_mount(const struct path *from_path, const struct path *to_path); int security_dentry_init_security(struct dentry *dentry, int mode, const struct qstr *name, - const char **xattr_name, void **ctx, - u32 *ctxlen); + const char **xattr_name, + struct lsm_context *lsmcxt); int security_dentry_create_files_as(struct dentry *dentry, int mode, struct qstr *name, const struct cred *old, @@ -883,8 +864,7 @@ static inline int security_dentry_init_security(struct dentry *dentry, int mode, const struct qstr *name, const char **xattr_name, - void **ctx, - u32 *ctxlen) + struct lsm_context *lsmcxt) { return -EOPNOTSUPP; } diff --git a/security/security.c b/security/security.c index 4ca3c9e28b6f..1d57e4e1bceb 100644 --- a/security/security.c +++ b/security/security.c @@ -1734,8 +1734,7 @@ void security_inode_free(struct inode *inode) * @mode: mode used to determine resource type * @name: name of the last path component * @xattr_name: name of the security/LSM xattr - * @ctx: pointer to the resulting LSM context - * @ctxlen: length of @ctx + * @lsmctx: pointer to the resulting LSM context * * Compute a context for a dentry as the inode is not yet available since NFSv4 * has no label backed by an EA anyway. It is important to note that @@ -1745,11 +1744,11 @@ void security_inode_free(struct inode *inode) */ int security_dentry_init_security(struct dentry *dentry, int mode, const struct qstr *name, - const char **xattr_name, void **ctx, - u32 *ctxlen) + const char **xattr_name, + struct lsm_context *lsmctx) { return call_int_hook(dentry_init_security, dentry, mode, name, - xattr_name, ctx, ctxlen); + xattr_name, lsmctx); } EXPORT_SYMBOL(security_dentry_init_security); diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index ce5e45abd8d3..79776a5e651d 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2869,8 +2869,8 @@ static void selinux_inode_free_security(struct inode *inode) static int selinux_dentry_init_security(struct dentry *dentry, int mode, const struct qstr *name, - const char **xattr_name, void **ctx, - u32 *ctxlen) + const char **xattr_name, + struct lsm_context *cp) { u32 newsid; int rc; @@ -2885,8 +2885,9 @@ static int selinux_dentry_init_security(struct dentry *dentry, int mode, if (xattr_name) *xattr_name = XATTR_NAME_SELINUX; - return security_sid_to_context(newsid, (char **)ctx, - ctxlen); + cp->id = LSM_ID_SELINUX; + return security_sid_to_context(newsid, (char **)cp->context, + &cp->len); } static int selinux_dentry_create_files_as(struct dentry *dentry, int mode, From patchwork Mon Oct 14 15:14:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 13835219 X-Patchwork-Delegate: paul@paul-moore.com Received: from sonic305-27.consmr.mail.ne1.yahoo.com (sonic305-27.consmr.mail.ne1.yahoo.com [66.163.185.153]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9755A1AC887 for ; Mon, 14 Oct 2024 15:16:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=66.163.185.153 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728919006; cv=none; b=LvZ21S7pHSVLI4EFzl3YlPYAdVCd+EHS5TVzJ7klX9SPjQIt2R9Ofi2Wnvp9loGJPPHT8AFTRP1mSBRPzBk6V/a5GV0Bh0UF1t8ke8iEl4CPN1nqSu7Vl8gMmeirPrXz2a9KsrZc14P8XWMcG7FC1zXBBoN18Oh2zuCwzbsNIio= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728919006; c=relaxed/simple; bh=7/1FXUJwvlcxt6vdNjwfBmeConrT3KM7jGMe9A/9bmM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=F8JF9W0RC22nwmdJrj6XP8U10p7YAub5BY0NAWyzUr/gvr0/yJL5t2cDzvuWc/dF98M5Tx2SgUHsDg/CfPg7833/HIVmyF5qsbku7uTqMNsKBwJ2ty2XsercNqWkOvXk3B2Cx6lE0qL3MYe9GM5BEdPZFAqrYhTW5TLqB/vE1mc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=schaufler-ca.com; spf=none smtp.mailfrom=schaufler-ca.com; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b=mBI2m+b+; arc=none smtp.client-ip=66.163.185.153 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=schaufler-ca.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=schaufler-ca.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="mBI2m+b+" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1728918998; bh=TV4v7cqRw3JBLh3olvqrTMzRkPf7tP/c20WTH9ANVLw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=mBI2m+b+1XzCVC8JvmT5LNXRm4BhUQPiA9ae4xwSifS0WE9aNHb7MrhpEkupo4k04L3gYvvF+8/rRXBmbs5SOoCnv3WTbMAr0EKQZAYh+R5UR+J5HKPOIG49PktmM9qodfrl7ZRgk2A1cJHE7T2l1eoJn1wik1DszIEBVP935pO88ktO6dGdMHsns5jYuR4KyCvggTa1Pfs0Kxj0oIGiKP3vUM6j0euyn4epnUGQwQwpVNB1zYyIzOyUnemFMYKy4OsewhfTQ+S83XPG9NYo9TRkPZvpsLZI+n0VUnP1kq9zgTuYE4WmiuP4sWBpt7gz/unYZF/9s+axUiBYhd/nwg== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1728918998; bh=HThXJxfQ4/rBqT5pk7pZU0Wtkj5bnQfH6VJrVEhc6ZU=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=l5jGpeMKlfiX74U6FxrYfE8KR6zt89o2N5T/yqoZGzsyybbk4i+IIlfE02oODZwyBAubCbyYusVmt8lVlgUYoszKcKzUZhTKcjkjRiKievvcLoLMlt0K5AR30NOVAfCFkvXBQfrfWAU7hd75XellNH0buhAXb5YHGLezd3UWkjFpA2jUIAdxqL5HHelGprfGv3/gdKuBEe/WhWv0sDSlPHCM3B+7ScOqlhqlthVlVZ6IPCWInk1OGv9Bq9ZvIwkF04b2ib+VVOqsFY5Rbd8X8J/JGF/Avco7IxqzrTlGbHQ388yarYOzx6pan1NOVqK2WH0E6se66fst6hdnnr0w5g== X-YMail-OSG: mQnTyMUVM1ny4VG6i3ZHvC2r6y3lUuLuQrO_.uspqViuS3MW7AimDhwoc.TILEE nqPMywQ..yC3K68tHOrHLNpwb7n0vTBi8iNQeKogC6EKw7BhLiXqzoYbpq0ma4X8hd0lQnPH_19q lnddTHCRkKC4WvsO7QlkASDa8Erjp7MaoaT7lZ9j6O.RgzY8L4bRclx9LTvlsBKgX5V3OaQxb3Vs klw3B9KV3GWxC.1vmN.IgtYOfjVgjtXemT7XLWHqARbnjOqped6yUg4kftuRJKIsrppzZBsoXC40 1uqgGaZJqXzJ1uSPDSJwKzdPiEMbujmeju6OmrTPFa6wxOanQlFKqY7zEFNUg0_PjR6ZO8qIz8IU e88Yb4NOSLEvH11oRo7XSKImA6teF7SNH0c4F0PSdwmDH_8enuLV7e28ylgzSwRiyraNRSuYoLZ1 RI5jX1u0J.mou4I8vsFKynixMifym_d21MviEq00shnze2BhZtSFgi0ywQbfYwBFbDLbtHTIVAjF njBTqZC2CNUL7uXD4ruDnWDCbi1WUk0MKJ_e5wUlgDwUbUIhZMPkM6p9a8JbKIZTKayzSyS4oXJA JxYwEjf6sgkie1NZBg8XeZJ8I7xJyWMfxpnyUNhQaMLDFRDE2Q3IiqkUtT.CYfzZuTma_A1JXCb2 3SjdoRSiDAvYRqdmEnzIfpxGh6gMYYfKevtZDBopiuaWP.K3jjcLFoImVszr.UfheaFGmp5hI9DO 5vs.3SVaIdYDlWe_XbZ8.GqtDKi3_X0vPuShlTeQ2PSWXH9yupZMhl5.CB2Pi1Pyq.smDTpa46.g HGFwwHSZdLU0YPYfeS9QTyGnYZDBu.ebrvb_978dTKwzggmxiNHsotoDczTWqNrFIIAecWaDz15Q 3v0i4.HGaRK8BxZi2EeD2t6wXB4_cmTcgfeeRgyrw1xyLHCMmslPWZga1i4S1is3xtgbyngzq5mr _zmQEElBAgMm0YbZILdLv5sK1o7U6H.tUEfXIpIZJcITi20Tgb.jW3nib9WCj25YBQxowQZwoEMC NxDXhr3P3OzYozTza0kIulYASgMJQsvgFFqg_oDvZWdYucpm0W8TL38VHTu9vJhK0K.uB6it4Nfd WH4ZiAJRpmmWg4015drrcPZVHNbfGgv3.WWNq0Hzla5FUqv5BiASQ4KstuHdJ9mv2H6Fudjrvg_W d6Kt9VsXK5NKOSrZcq7IsayD2vlMH1q9XnCfPujxC80zCxOWU2lN1CtcjFXFlILf93aA9XSkuCXz Bv0cUBhcFbp0GJxwVvRDSKqtl5TOPq4mOR3sKCZPyqPJNHiOltokGQnkV8TouWSf8Q2xmWFRn9R2 1T5cU79t97AjhHBucIS4UPai1tc5_jrXB0bZzwu_elxqr3ONNajmX2VlATldM6sFwJJmLUedPfqG JHkgTsLPBgGRbjFy8a4cw5uQiseJcSCpcGMXjYx1iFYiIlFaLbgbw8DwrZxHjbhSF536W7eiO40V n3wNwoNVQrUySVmw67zo2AgKvtn9PMgZHd6gJfQx2KjYIDw66l.ju4ycDG.hpiaBvR6xdL5JnwMf gwVKzrQLr8utYgFZr37_mrDEeM4FM3q5KpwiCp2P6PYqpU14mNNZZ8QxP5CLFGopR0G2yMHdw5CS GIOyovNKNJSxjj0_LE6JU0wOWw__nOsrdum99LpDIlmTXBj4LJkjwPQiJ0oy.EAw25VeqR59.0J9 qYqO2ucf4VOtUSmoLBaPcPEO4w2rBSK_IwwmlV.h1izBo2X951xlR0KmJhgPvNXFUwS8qNaWDRVp jzhEyYsA11eBBb5OUm0MBQqJDhRWBNYVXm1BSVgEgz51s3LvrwfLMCIVQ3OldnKxmJBNVUcIgtez Z9GMxs7YC4G6zQN6icYyD8xknUPxcPzO91NI8q6VicKtWckaK2PC3Cfu3qRC1dR0dl7xYbzNSRS0 R.h.4hC4eNiDkBOzrWsmQemIpHpKMwMi87yJN.8M.c5xBAF7kF1d9FgDkEmL6bBT_ycCaNmd76c6 fq9JUA1MICytma7Nq6IX6sM6upNP7iDCkY4HV9eSZswra459HD0.LT.tAQ7NUAxHO_8y0zvQDYvQ kOOGIxB0BD5FGMBSsnPNr483OxCBmaRFRV7BDcsLB4f9b4hf.0I8p_3vJy3R3YfBfyTFddbGULDf sC6iN9O8pW4wMBQ6.sLRssvcmUetPWnacp5Y6O4WLuTN7T2mfjt796_Cyh4pLFYbKu9uUPHmZ7e1 CjVM8o0Df.BjgRnh_iVknwp0KWN50_cjNW7OtReQRM44BwiFI14x7ksfVZ0b735hwh7593JAc8Aq ljdSCobU3TgfjDrfrF0imWf4lBmlUjc45mw9XKQ-- X-Sonic-MF: X-Sonic-ID: 33ed5c9e-1488-459d-863f-83f24f420e6d Received: from sonic.gate.mail.ne1.yahoo.com by sonic305.consmr.mail.ne1.yahoo.com with HTTP; Mon, 14 Oct 2024 15:16:38 +0000 Received: by hermes--production-gq1-5d95dc458-4hqnr (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID 8dd3ed09a3dd7dbd0509b276d789cdef; Mon, 14 Oct 2024 15:16:36 +0000 (UTC) From: Casey Schaufler To: casey@schaufler-ca.com, paul@paul-moore.com, linux-security-module@vger.kernel.org Cc: jmorris@namei.org, serge@hallyn.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, stephen.smalley.work@gmail.com, linux-kernel@vger.kernel.org, selinux@vger.kernel.org, mic@digikod.net Subject: [PATCH v2 5/6] LSM: secctx provider check on release Date: Mon, 14 Oct 2024 08:14:49 -0700 Message-ID: <20241014151450.73674-6-casey@schaufler-ca.com> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20241014151450.73674-1-casey@schaufler-ca.com> References: <20241014151450.73674-1-casey@schaufler-ca.com> Precedence: bulk X-Mailing-List: linux-security-module@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Verify that the LSM releasing the secctx is the LSM that allocated it. This was not necessary when only one LSM could create a secctx, but once there can be more than one it is. Signed-off-by: Casey Schaufler --- security/apparmor/secid.c | 10 ++-------- security/selinux/hooks.c | 10 ++-------- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/security/apparmor/secid.c b/security/apparmor/secid.c index 5d92fc3ab8b4..974f802cbe5a 100644 --- a/security/apparmor/secid.c +++ b/security/apparmor/secid.c @@ -122,14 +122,8 @@ int apparmor_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) void apparmor_release_secctx(struct lsm_context *cp) { - /* - * stacking scaffolding: - * When it is possible for more than one LSM to provide a - * release hook, do this check: - * if (cp->id == LSM_ID_APPARMOR || cp->id == LSM_ID_UNDEF) - */ - - kfree(cp->context); + if (cp->id == LSM_ID_APPARMOR) + kfree(cp->context); } /** diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 79776a5e651d..b9286c2c5efe 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -6640,14 +6640,8 @@ static int selinux_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) static void selinux_release_secctx(struct lsm_context *cp) { - /* - * stacking scaffolding: - * When it is possible for more than one LSM to provide a - * release hook, do this check: - * if (cp->id == LSM_ID_SELINUX || cp->id == LSM_ID_UNDEF) - */ - - kfree(cp->context); + if (cp->id == LSM_ID_SELINUX) + kfree(cp->context); } static void selinux_inode_invalidate_secctx(struct inode *inode) From patchwork Mon Oct 14 15:14:50 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 13835220 X-Patchwork-Delegate: paul@paul-moore.com Received: from sonic306-26.consmr.mail.ne1.yahoo.com (sonic306-26.consmr.mail.ne1.yahoo.com [66.163.189.88]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 80D681CB53A for ; Mon, 14 Oct 2024 15:16:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=66.163.189.88 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728919009; cv=none; b=fnUMINgxgiMd3z4ZNFsmZUgMZz96KVJhEYICSg6LbWC4H5cxpEvKVBPZRLat4i7RG3BB7lUdCaurCfv5+NGdJT0JjRACIb1FbAaKGC8E2pQs5ieSl8zM67RonPwEdEq1Wb0JD2b2IiVCS+/tZmhCt72Olzo0OeOk7b+XEoK+wyo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728919009; c=relaxed/simple; bh=ere3Kik7ftPK6JxZZEH1M4sTcj2ctKVjykePBsYfvpM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=NABrs64og4yTxS1+oegXek0/TAjypDvtcQQhVQngB13jrEEnVdm9sGwcAkGyUll0kq0b85uJVryMDWCvMA1PyNDK3yRdRrSSmtfzDY9y5fUfwukn7ihOAqc3ySPma48/wR+TRSq9s1StFLlzF+U3xNtX6/dJiZS/yPXf3oC4KmE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=schaufler-ca.com; spf=none smtp.mailfrom=schaufler-ca.com; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b=gYSUmj87; arc=none smtp.client-ip=66.163.189.88 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=schaufler-ca.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=schaufler-ca.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="gYSUmj87" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1728919001; bh=4mPAELSUVvG9/ofHl8szvzOPyVtLeNBqQjj3M7dfO1s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=gYSUmj87/E4MaLUI3kYq+WTu4gWEBybgIBo0t2D5fx2b7QEhs6Vz+zwBEfXw6BfUfZ9NZDGkpeLshGwqUwduQZS3je0uCfn4mGbIWcdIj46Omtxr1LKGVSye2isEr+hu3PCHKjoKbW3y/QV9zBPdhgQMeMLquacMQiGL1DdwbH7DGp08fwhc1yVmyQpWQlFsAh2Hq9N6Xm/oFbsshVyuCN1sZIbS4gzf9h/+v6/cyMCqnmW98wURDNhw/ZwS6wk/TMARIefyvkjnecpwyCBpmsMRAxmXg7QIQpRNgIrV0Blhgtvc2HBuOoKi/uaqtFKXARRzs0XpDcoRFq5D+4GyKg== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1728919001; bh=jFa+mINhES7O4LMEYk9qLq+vQaOIKIkdPdzQH4HUFZ7=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=cqbxzyrKZDNVivxHNaPq2JWULQKNeXGcmThZzg8iO0cJQi7v8JxYTVxitxouMyMMNqTOTZiZ8TtjLgiCockx45odXVCX7kCdIx1pFRXG1z4IEiaJgqWhBQ4fzcwxddjJTyJynCHczFi1cAP7lSVxfLAwuGl/Ntf6iau2q+jl5ksIbsQc2LCO18YcUhqBlfR+hRx89E8tp41VMGn6AQCH3rd5o3+c5FyhlaJ5YbRMlq05HZm4GGC5ydub9irm9FvHURDQLLRAV4TgPz3VwRGZqp9syC6Grq4pA+depuluLAlVjJ+RXaPqCC1ijYr85GvihRZ+AypturFMqbV2dle/lA== X-YMail-OSG: HvSVcxsVM1nfLFDIqwzaKr1UAy3fczXkWcmuTFjBnolzySaKGN1egkZMDDKiDCc pK6imXmU2gK.evT2xE_H3YKyV64a1k4xSXsdnz23aTBlLOlazJuyuwBxkFp5Moznp7DjGtlpgWzY 69N9msQCzdK_2ayCXx_u3tYckwug8g4vulZC_7hfPjM4YJtZGP0gh8ze6lBbgCjIGDQo.tBLw15D uTFALTdKHjuAbApp4d09cerYx9N9AJb62UUdjDIj5e.v9Z2GSPHZMhnHt7DPDgNrDKZXHVXzdFUH TwjzfzW5_J5hukrLJslm1BnvTEgPWMxZgPVQmjqdEAQoX.qmed4T2.14.rEL.SIre8Gc2ZCU5cCU IWhiWgvOUwGzHt7aa05twc5oehUdmRdwpjJ2l0Ge8mEM4L_Tz9CcyAgKlIP0OeMin.NQZOSFd5lI GijP0ohouQ1HIzlzr2mN9NJ55DlEjHUdKnr8uw5gZITKSLkmtSdt47.1tA7XtMpkaogGI6oNOXoN ZGmoW4ep48t12eSzDFzqSAbqR2hhzkYXIFFXLoZEDraEhRnArPcfePqwM0A2WMuIPCoc7aH4IZ2D SB.dxCAaZwjaoit7odj1.5CWygjbGUsWpBvwgwRsgUQOcc9oPUTyrO8iMwjun4tg6Z0pXU46ckAb A83aUU93P1owxZCTtRV8o2m78qu8FK0Q4e5CVfsclYfFcz4etk7avcmSK_ahZm_TUiI7iin3KhFZ s9a2faXMQBd9x6CwdxcOn8yZ5oie1H_LvrawwaFc9dp5ut7COSCJSHenAE58XknPRPaGS1AS2ma3 eqN_Ok52Y2POr6BSuGarModugIzFOuvtecADK03qxynQ22tbupv0xu6panHb4lcpREXcA7PABCrd kMkk0MT8ebj0xM36RxOBFmZ70rMEDPDwrQNXgIGePTuXiBp9qCe8mav.3H_zxFZiukSHMGwBiFxr arIbuJVHgyWWLwnjfCNrKiOVTRGRatlVXwVY3L481mGa6uJiZPOETwWr4mUfoHDfobNOZulcDWvo 8I0enii__l0cwTrHSyPRNGOtJq4.SKnXV8srwZwpeR3NcqeQww72dXs8tiywSG06ceJr8M2zQJaQ rKOjZAECIFTvIHxIGFe_gcyc6P5ocBqdK4fgV1jAIOWtxiM7H0hWyteDy._DrZBLwuV2FKsveTIw 2a6oeFKpRiv8ItZaDiiWVWCwKc1XfcJKnNGl934M5KuV8XVV2SepXT7ovymLCrUgVyA3cH10ymzq FNCu84ec0knSyAUI.L1yK8bLEt16XbMF5u0i3AAik8V5VDu6ffs40qVqa.MW4jBa_x6ph627Cxx4 RpUhhU0ei3337QrGqDiqfWxDHs4izk_0jB1L4Z3PXFNzELnLRoBhCgymTq8R95fEfuT2f2evgdd9 d1kyi5BHnRgakvh23IluOGoOKe44DavJFBDFQPC8f9oXH8_XRwqwskBAKWlPvaS7F50N8V_8A8m0 _nea1MLVARkmSHqcFC149tkIxqGUyp_Ds4K4ZT_Py9MU45hLDz91TawwmvziOerRQK6f.bNoV7FU i3K7FYC9TNOIPmI.UJHrQpFvkzIeFQ.HA_SoCTFL_derM8Xq4LxQfPqtRclCZhyCk6UUDw0eSQyL J3F.4fmrN_GD6plralhnCrQnhf9NQfUuslSF2SOCdOD8edgDkqJs1OdW2Ji0yTJl8kfE9eE9us6t Qh3s6QoL5fis7AW.IUo0eGevisQTLRV9snfS4v9lddwwrpVyGwoyWthGu3WfkCdBjCVuqx8TRfNW OqhTwF4Q_4G6ftBppeEGjtYnJIlT4qOaYvVPhh6X1yNllwaetMU7PiddMtd91VhUyvj24_CBfTfV 3rCDPDOmwBiT.Rq2YNsQo3P2q4sYGwuSzGFzTfl.HGdWhN_aQ0RlgvmPrHjqOauCYi6yWORlC.1f x0hqGQllwDpKaCpXkCDXrWxqzWOGZsNHSkrE.nSGuRkZaqd5oo1eAP7UnZHedLdZtyV0ZJpxibLB HOMbLCMnOiLJZmwEzhhbHnuA.lMJIGN.bKxeS_nfC9.vVWZWZRO9hSKZNT4TBXJKljigTppohzh. .0RTnnAsEhzZwxEMNHn4ASQzhomtsWHLAhbRoBCnhz82NAa7q3fYUsglDtm4Jbe2KwcArCJdBTMN e5IV8KIfhbLpjX4cAUJAldSQLsO9S0vui8QVrgfpLbPEh6ASOh6KyOsfS21l1VKSk3QpW9hIbCJP fDYNX0FgTI5gPFyfzLnPORE7TTHTEEAIxkmOopYsbSljyP96Ad5e2aeYRyUk5kiu.KKK0.F49u3C Uqkj__sdZCg84cmA.uvFqdc4VET_SNDCywxiifQ-- X-Sonic-MF: X-Sonic-ID: 304cb278-0e6e-4e01-8cca-c232728638e4 Received: from sonic.gate.mail.ne1.yahoo.com by sonic306.consmr.mail.ne1.yahoo.com with HTTP; Mon, 14 Oct 2024 15:16:41 +0000 Received: by hermes--production-gq1-5d95dc458-4hqnr (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID 8dd3ed09a3dd7dbd0509b276d789cdef; Mon, 14 Oct 2024 15:16:38 +0000 (UTC) From: Casey Schaufler To: casey@schaufler-ca.com, paul@paul-moore.com, linux-security-module@vger.kernel.org Cc: jmorris@namei.org, serge@hallyn.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, stephen.smalley.work@gmail.com, linux-kernel@vger.kernel.org, selinux@vger.kernel.org, mic@digikod.net Subject: [PATCH v2 6/6] LSM: Use lsm_context in security_inode_notifysecctx Date: Mon, 14 Oct 2024 08:14:50 -0700 Message-ID: <20241014151450.73674-7-casey@schaufler-ca.com> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20241014151450.73674-1-casey@schaufler-ca.com> References: <20241014151450.73674-1-casey@schaufler-ca.com> Precedence: bulk X-Mailing-List: linux-security-module@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Use the lsm_context structure in the security_inode_notifysecctx() interface. Its sole user is already using lsm_context to store the data. Signed-off-by: Casey Schaufler --- fs/nfs/inode.c | 3 +-- include/linux/lsm_hook_defs.h | 3 ++- include/linux/security.h | 4 ++-- security/security.c | 7 +++---- security/selinux/hooks.c | 5 +++-- security/smack/smack_lsm.c | 6 +++--- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index d00a6304133a..9bd38c0f3b09 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -359,8 +359,7 @@ void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr) if ((fattr->valid & NFS_ATTR_FATTR_V4_SECURITY_LABEL) && inode->i_security) { error = security_inode_notifysecctx(inode, - fattr->label->lsmctx.context, - fattr->label->lsmctx.len); + &fattr->label->lsmctx); if (error) printk(KERN_ERR "%s() %s %d " "security_inode_notifysecctx() %d\n", diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index e2f1ce37c41e..afadbce8bb60 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -301,7 +301,8 @@ LSM_HOOK(int, -EOPNOTSUPP, lsmprop_to_secctx, struct lsm_prop *prop, LSM_HOOK(int, 0, secctx_to_secid, const char *secdata, u32 seclen, u32 *secid) LSM_HOOK(void, LSM_RET_VOID, release_secctx, struct lsm_context *cp) LSM_HOOK(void, LSM_RET_VOID, inode_invalidate_secctx, struct inode *inode) -LSM_HOOK(int, 0, inode_notifysecctx, struct inode *inode, void *ctx, u32 ctxlen) +LSM_HOOK(int, 0, inode_notifysecctx, struct inode *inode, + struct lsm_context *cp) LSM_HOOK(int, 0, inode_setsecctx, struct dentry *dentry, void *ctx, u32 ctxlen) LSM_HOOK(int, -EOPNOTSUPP, inode_getsecctx, struct inode *inode, struct lsm_context *cp) diff --git a/include/linux/security.h b/include/linux/security.h index 3ad59666e56c..6dcb0046531d 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -570,7 +570,7 @@ int security_lsmprop_to_secctx(struct lsm_prop *prop, struct lsm_context *cp); int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid); void security_release_secctx(struct lsm_context *cp); void security_inode_invalidate_secctx(struct inode *inode); -int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen); +int security_inode_notifysecctx(struct inode *inode, struct lsm_context *cp); int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen); int security_inode_getsecctx(struct inode *inode, struct lsm_context *cp); int security_locked_down(enum lockdown_reason what); @@ -1563,7 +1563,7 @@ static inline void security_inode_invalidate_secctx(struct inode *inode) { } -static inline int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) +static inline int security_inode_notifysecctx(struct inode *inode, struct lsm_context *cp); { return -EOPNOTSUPP; } diff --git a/security/security.c b/security/security.c index 1d57e4e1bceb..c961edb0af57 100644 --- a/security/security.c +++ b/security/security.c @@ -4387,8 +4387,7 @@ EXPORT_SYMBOL(security_inode_invalidate_secctx); /** * security_inode_notifysecctx() - Notify the LSM of an inode's security label * @inode: inode - * @ctx: secctx - * @ctxlen: length of secctx + * @ctx: LSM context * * Notify the security module of what the security context of an inode should * be. Initializes the incore security context managed by the security module @@ -4399,9 +4398,9 @@ EXPORT_SYMBOL(security_inode_invalidate_secctx); * * Return: Returns 0 on success, error on failure. */ -int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) +int security_inode_notifysecctx(struct inode *inode, struct lsm_context *cp) { - return call_int_hook(inode_notifysecctx, inode, ctx, ctxlen); + return call_int_hook(inode_notifysecctx, inode, cp); } EXPORT_SYMBOL(security_inode_notifysecctx); diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index b9286c2c5efe..6aeb8468e568 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -6656,10 +6656,11 @@ static void selinux_inode_invalidate_secctx(struct inode *inode) /* * called with inode->i_mutex locked */ -static int selinux_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) +static int selinux_inode_notifysecctx(struct inode *inode, + struct lsm_context *cp) { int rc = selinux_inode_setsecurity(inode, XATTR_SELINUX_SUFFIX, - ctx, ctxlen, 0); + cp->context, cp->len, 0); /* Do not return error when suppressing label (SBLABEL_MNT not set). */ return rc == -EOPNOTSUPP ? 0 : rc; } diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index c9ec4d93fb13..c5d7652395c1 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -4887,10 +4887,10 @@ static int smack_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) * Now that there's a list such a hook adds cost. */ -static int smack_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) +static int smack_inode_notifysecctx(struct inode *inode, struct lsm_context *cp) { - return smack_inode_setsecurity(inode, XATTR_SMACK_SUFFIX, ctx, - ctxlen, 0); + return smack_inode_setsecurity(inode, XATTR_SMACK_SUFFIX, cp->context, + cp->len, 0); } static int smack_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)