From patchwork Wed Oct 23 21:21:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 13847982 Received: from sonic307-8.consmr.mail.bf2.yahoo.com (sonic307-8.consmr.mail.bf2.yahoo.com [74.6.134.47]) (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 328051E7C10 for ; Wed, 23 Oct 2024 21:22:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.6.134.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729718533; cv=none; b=PWDQ1C2/qzjar2kUeOClXOBD9q8d70ykiWRcRic3tiEKrG4ZWyRzvY/0JyeT++bitVn0ZHm5Ftx0RR/nGUZva9rJb8PnDwZ3xph4+mpoJxC26oFc01vYs0CUR6A2t1Pi0HoYcLVACBm//AVSEqSGrppM5F8qbM4sHzrBI8HoUB4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729718533; c=relaxed/simple; bh=YZWYVEpdDudKVViWqIIgs8eGsTpS1TRwYy6vpzmkKxw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=l7y/Y8OMdL9MgEOgEE5mhxQvQmR57WMddhIhdBnONOPr6SvZKSbG/VJiqkrz7AbOUg4/HXQfKZfxL9YwO7r1z0isTcF9LHVXpQjSbrakWwGCyy8KGpJKFvKp3KbyK0ZnZ8h+qk42s8FOUerJJIr8tlwfHlsT42vkFzmSWy1uSTc= 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=MiaIajkx; arc=none smtp.client-ip=74.6.134.47 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="MiaIajkx" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1729718527; bh=EAfsMeurPhmE2qzmidqx44B7cc3fBEKQHF530i2eVjM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=MiaIajkxffrpG4nUl9zCTUTre839aQGwYK3cdCfDjNR0rhJA3douwsv3jdUT+FaupsMkBqNQHSRX7YAfVr/RMra3tV8v1vFxuHRToeDlre6Jdk2fVJoqxva4Y2uQkXR4BdmqXjVaVngiMX+0+KkoTa5/1xtEgLJZ0deQ/eLIqq5rMummdeFn80wpP3O4wkeABsyXhWSV4Bch/Qgm7oOiOJhOgrm+2oMBCWgZDBxeLB20SKgI2W72CZfMJ0219Gj16QhRwJrayGR7sDLYav8KF033F4EA1PtOpC/hZi/itAmkrIoo0q7sv3UoGyUqtfZB8ITNbxmHvIy2u4I/1Y0OQg== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1729718527; bh=JPe8wcZBKEP/MekfOhS44DxMaqUowMBGpgWstOQkJlF=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=bhNz0zrBxlHWfda3w249tSlpuzUSq58mL3lQaJetVNwdp68RVyOlQXt42VVgDC9YigGD1MCGI5qo3J0AiSzhdWkupBLIbsNb/K/rl+2K7r8hAz+7na9jDZ4P+9n30cz60WKwM11UgyxL4Q7bUBYWvfCm3/stog+RuOt4fX5kDt6zmBF7y5qpoEwUtyCwIqV/yZUu90mk8HPY8+NqaP+iEKOPuXIJTdOd1ESYFB9t4Ib+kzBVs+/p5ixKXHcx3g7aO93mWdc3NLUHmtNg/5DfLzkpc+T7i8fQte+aFVZA/fHDRpPkALvBtJACFTAotrBO94vu75Z36wdEIAjmp27AjA== X-YMail-OSG: twIrnm4VM1mHcF4lqFK2P45CX.ZCI0VxSxXpLe.Smy21tuN9GsAwciG1zSyDsQo RnEMFXA8QicpXkB_sTdFuGsQc8ecRKV1hE6SVPYwI8gRT1iS8D_YeCR43k66jYjeMQdIgTtigKcq epF.CX8x6xPA2HFhahyq6HEI7YJtMLNMm2jyoJ7FuOST1SzdhxEkUE5MUlJFlxBPkojDhgeI8ZoD BdeXJaTov9CntK6oN2Jf_9Xp8cFBIXQ1oYS0JAe2WKzqcN0o4R1Fo5VuCJ..I_pAUcv_mdX2SwM9 .V.oBcdCGHMitSqvLQ1eNtHNna.GVGBppXZG6t23uwn2X4uRmvJVtYouVPnfJCBjzDIkvrZfeMtg ISzSX3apM1XjmQ_2fHEQD6eTxWTQdhlbdcxal31A19uVuNnsVhWSjGC1xmJlI37xd3N6WWPuGBKl Zf_U5Ew5RFBk76KjtW9WHAQDxU4JL98o5o5CH.zx9nWscMlzY9v1tBF.JBgRtX8GogxjnA6.fuoH Qhz_AFHtNcnvQiC6ZYikZx5_64TaUMUok7vWqxbGAj0pq4__yDgS5VRMF92Ba7O0TYc8gr9uqzwS iWIEEJUIeWtjTqenWYqxgCZFsG9IF.F5gEKV.cvB4WF.Op79W0YUykiVOAgdQT_HqOL0QoW3H5lT eIJkT2FZdjU8wb0BawzSedQRLb5XxaE0CDz3Yx3dG7cCjJCBMQuAlNHZ3dvPZcocK8tKK6jyay5w PT0s0TNvJMDnHKFlLOyeoSFI2ziggnc0eKfhVhn80iC.mhaENlDvNwOqqlX0jks4l0GQvGi0k0fY 2WJYUcITyTgR2YCyEsjguUPGSdP8thybw1oiuegdlEWnhfycNEYHfH9HryGvXWeOoPEm2Re13Let E7UzJTyYbHHbec9d7tr6fwcJlHmOfBs3KKy1nyiUYpYIOMgaK0Ah8S.wUKzeYC4NL2rCOO8Wj2Zg AGFwhl6Lz0bVa1AkLXMGe16tL.SkKVH4m.n0VuZV2o8HVY2qfDHIW7BADJf7iTC4f2t2XcYt0Zsd Lm9XAj0S5rzFuQlRNJbvDy3xN3mQZ3Bw_fvbqMx8OqKwRY1_TKvePWx7pjdgeum8.9I63x1iBhy4 wWRgS9VKZwo4dOWOoma6mmsld_cU5yMZjLQAjU6KeicDISLbqPNKL2eqaN_tY8rQ4nago4e8Dq3F K2Z_WtU_VO7L4mxNwFo18KBIEgSTiuvKaWT8AYeLLvKeE_ZEBRzP3VViVyz7pyqT2pDokrkmwxnC e3jxq2BlEpl0zUVRvYIjZ8QPe1_7C2blkfWE3uMr_IoDyRtDKw7DaUmkHd_NiDQ2e7jL5H4q9FpK CA0_65yY_8l_MKmIOuZmNuVr_8t5xa2oPiMMsu5NcPTSXubQSfmyC8zRAmEitsYSGaZ8zGv6LVd. OXXpm4rHlB_h9PRTPg2GUJs5fkQQiFTv4yue1wWxIbBoDMcfMkaMnOAVte5PufXxYieykDfu3x2p 6jK2a9ZPGBKLFNDJTIAJir5F0NkTtE_8IjdnPPXrF6QlEo.NGdTEKyhaGg7sS4WL5QLR4wDmzsND YPanQ27jtFmWs6AFv56ylCG1szJmgDpgYogECGnkXjdJIJWbV6F_pgRmP6og4sBn6MBjlM6SRcG9 opIWB_m5EeY.Rn1kWvfsjiC8cfCNXVbk0hQYPOl.gLgNtjfL1oHUiOQ60FTewvNLm.czz5E_nmki FHFnzcDwyxZL1vqyvP2oTPNBtTBupDwNAdvJZN9D6tdISBCpzGbH7rpM2VtFb7.QxCw7ykC21DO2 2xTDtJW_Fhb50Eps5djqVeE5iQPu7y3LfGiliSbsQVWiV.WwENiVRg7LeXvSfaXoW5aEQhuDbvDz 1tPmK_H18jFtk7DTgvGcg2ELzrQdaavApK9ys0vM3vsHGVqJUHm.Ba6GDNub0tjqltWRI0ouNj7U SCBZld6MF0eD3artlCeAevBXHhATCqJOBV4VIIP_Its_zs3T6ubKrknex_w2vKFf6aDXc7QeyiuH VMbTG7yRID6jqbujBDTV3mFbA3sGS1f6IJ33_eZUhs6gSxKie3NJsp.eSzYPbWWQHfy.BcrDvQqv C7XN8IRal5wQaOMsjnaEZGPdcFvckXi2NgI9uh..sl907sYfNIMbdSQ9HlfHzvE_adPRxAfC7oWt z.ilpK.DZyklxS59X7EKt.CYb9g5us2s3bDiYEy_AzBIHVrseseSfoMQJhA0K6o0M3kkIz_Y.K5L WGysBdRuhEb2_2iLiQYq47H2gGrqlLAwQ2HOb3wmwYm9ZrApHJ12HriGdJJgfOJa8anE5tE50HyV W0XmiPpjMPJvbQ5BSSkAqMiBPYacW964- X-Sonic-MF: X-Sonic-ID: 9f85a4ae-666d-4262-85e3-4e99743f8f73 Received: from sonic.gate.mail.ne1.yahoo.com by sonic307.consmr.mail.bf2.yahoo.com with HTTP; Wed, 23 Oct 2024 21:22:07 +0000 Received: by hermes--production-gq1-5dd4b47f46-5xsmt (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID 8a7972f72a0226c80fd86fd6bd5371c9; Wed, 23 Oct 2024 21:22:03 +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 v3 1/5] LSM: Ensure the correct LSM context releaser Date: Wed, 23 Oct 2024 14:21:54 -0700 Message-ID: <20241023212158.18718-2-casey@schaufler-ca.com> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20241023212158.18718-1-casey@schaufler-ca.com> References: <20241023212158.18718-1-casey@schaufler-ca.com> Precedence: bulk X-Mailing-List: selinux@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 --- 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 | 40 +++++++++++-------------- 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, 165 insertions(+), 107 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..921fa8eeb451 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)) @@ -439,10 +438,10 @@ int netlbl_unlhsh_add(struct net *net, 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); + &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 +472,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, @@ -495,9 +493,9 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, 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); + &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 +532,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); @@ -555,9 +552,9 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, 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); + &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 +1066,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 +1123,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 Wed Oct 23 21:21:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 13847983 Received: from sonic314-22.consmr.mail.bf2.yahoo.com (sonic314-22.consmr.mail.bf2.yahoo.com [74.6.132.196]) (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 DAB581FAC42 for ; Wed, 23 Oct 2024 21:22:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.6.132.196 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729718537; cv=none; b=ueh37TadHP8QNguorEx1bAWnl7+a6Wx6xTftNZBlCXwX29DLbHwCKXirNG1kWMSvpGZBnXprn+kPron+Tzd2kNDkZ0kKchHGIhiI9fSn24Qd0WALPpeFWn43c/y85Siz8qdDBJMe2sza3IzlLXsJAd94kukn03K0r3zZRl+dq/Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729718537; c=relaxed/simple; bh=P1bFdA8Imw/lI7Id+NXhq6gjKgzY8SZvX5qQ0U2pbe4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=OkWMKHsLX7+gA6ORDhrMyWHYeZcSRHt6vfSbF5vUD/jg/pJcgOsrErjHnDslmskvsdNfyNdSu54EypC+BTrD1DqFPW+57YCoX0BJUTthA23jUeeRoY4xKF0VSRxSct0sqhVNv6KjlOlKGmgHUOYl0AVh5FqrIzEydxi7EcaX7rs= 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=szqwokkl; arc=none smtp.client-ip=74.6.132.196 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="szqwokkl" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1729718532; bh=eFiFw87gTeflI6YpF/f724PdslN2RkDib+9BWmN1JP0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=szqwokklZEk24ijjmcZeEW1mGI3pN7XeuJQQDVmj3P+6Bp4z0nDu1b944t30ZqejML/8LdCXGEp2FqAzY1dpgvYBTvvUH0loT9FnSudd1jiRW5G6i4037DeZluNEaQz7V0qisH2N4OI/MhK9wBgOIzEe64pKaZELBkLSPhvScqQCqdy96eIjZllMQfm9P8AbN81h9CVtOGNvONEhKoeSSO3atKYRzFIZDqw74dAYynHcKv2f0caRH8WFktogFMLCD+eHHo9Qn0bfHubcYo7OsOhYfI9TppO7rNyQ1Rig2WL+x05+ugGZ2Un2dbTAtxJLou3PFwlWzJMMnvg2FKe+nw== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1729718532; bh=8/9K3PSORsDxdHRPLThouSpURIwSuYqnKYNr55IHpya=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=Auk0I7NvmkC88A62HtUMBtzoeNeAwrb5Q1/Bi5zuGdM9m+Uo6TRYaNwbPj8pd2a0g4LlI7v7AUUla4hqfIwWrpAYFcTl95CITnHGi+bzd9QLUim63Egqzu3mII/fiUuPeatTz64iOc7ZbxqY41Af78GqWfQ6LyIWX3jJFvvEebB7Fe5yaQzJGCVvlJ8WLkHYqGcbYd5heXzx71erHzTgV7ioSEiyL4F+bpCtPWgvkgHBY7UtR8fpMSicgGd8S0tvW2pqM8xXzHbVwC0SNu4+RxAdgLX7b3v1lWGlEqKn97SxMSHNUeH6l6/BriD/ibdRidCo55rErkob3mbQU37y2w== X-YMail-OSG: 5iiIuloVM1nynEk2dFsU46nra93DqKMreTtL0tMCD_S9tIWA.LcuD.LkRvDHONC NtsX4CRlK2n94bBgZ9x4rgutYUVZ.uRBiP5vqWjdEjv8WnsJjiTbVEjmXszI5pBSPlQfsVu08Vgh t9YBPA1cCQ6oMvnKU56Nm7sZoRhol5P6CDbLsptHCcmDY3eIhWVgyRUhjzz1pvSA.8MOJ3rLLRsy iOcdn0COWEPGxHWEO9idaHELepRfujKflwOs_jvQD3fR3Y7yFTVnNqHbKzEK5wS9TNTIyaOr65V1 t45sg3Sx6UV_ZtwNo0ipVaQbeQD1B6uH4Ikkja8NcL1rgg6YnWMqCtN4SYII7MdQ5m5bGuEKjU7I 0sstoY2YtXIS9rc8jHrtkkdxv8rPaEOtkJBTqUEcHxfFnEaaYufzlZ4szFh4qGxwantg9F4QWGQK mqjaDfhzg4tQRzxSYktXd.cbOdfg5jtqTHSn2tAYTZr8u._KrYhtKNG9li7.MZP1Nh4KMZFS.JnV HmDUyY7fpyhnaFoJsfLsJq73Kx2s75UKZ2IMV55AxXKZbqj1ktsSNcvBwbMIVac4JJEuJEBMV7_1 JgUBU7hFWNK0zHlElsae9p3_k3d9CgOypb1eHY1Nq8TpEXhlVMCUYMX9OCT2AhauYF6tB9Jql8HD ndTKBUvWd43VBakUcQVScbCQ9FQ46utS5xTZGGfOlf9WCZlIS9v8jTvzNkuhvpxyNjIwykMUXSTT VCsws9ZFDoUGfb0bPI_gvZQADnv9PyMir8SXmEaY1bRVdeN554GVLbiSoZcOgafEiH60uapSe8ru L2RJheF7GD39KrHGwFlehXDQvNacZKUpL3NG62VSA.d9yHFfElxq.PZAmr3py.Dhuhg2J9gA9dP6 fJTkY4u6z8_3iTPZ2hzWGnc9CQICZ.fLTTPOoVr7LsxMAzPCvnG3_JQnIkmo6xqH5hj33kYnqh9U ObcaeE5AB2ceGdZIq99uMDPmRyj3qgaZ3FAAyYMrXr07scbw0x_8Vmz5trwVIMdrjUk2Ux2XBKBv l3p6IMJ.WURuSJ9wVObKbLD8T8c4HWZaRq_3wbHkAg7okWvLYmqs6vbJjkDdtB0GAO2JXeH6NtHZ IkLY5BHGTGzFgaj4E6fIPgL87PwFynnl_Phe3dS.OBCW_xKkTJC1SaIFl4HJhhiqth3cw6Pkg0t0 eL60QNFVgel6__dYEmEo3BKeNUxZWt82QOW_y.xNS3SJHUSdu8PePVFJZlK70v2X1xinDPgA6nBO zhBT4a7UX6bgHIt4UKGSpvBiMiFzB9GARIENh27Gx90EBikrIZnxmO19YB5xhtn_0iLDLFFef8iJ 1GqnydDRPh7FU.PjHKcX_pWWcew_9Nzfcll0SexCdhfmaa.MHBxgaXaHmwr9UtXas7_smff4S4x7 E.jNLXl.zeIOduw8Jqptu6GTea0foS7RV_PAuxdrWH4bMJKcnsftM.nWY174CdQMssrigDSKyr_C MbmBKipG11iiI0YTtm0vAdv3wFaOdC5Y2ag0yRfRergJbB9b3ZniG5oRj9KypqAyT5JOTG00aIge RNB92d5MbzrTsRbKQ8R.U_7mHeWJ9MjhgV0EShB1F7d.k297TIInAiGaX_Ox9tKEkAX0KGyyr3M5 4PBl.UUxXFZCxWB1iAiojwW9fERHJqh9.GrQZIDDU.oj5Kn3gRDi0seG8dPanbBzAkn_TiRZxM2J HfONhP1usuFBjbMTwghuj7yCJXW4_2yXgi.1JLjXG2OQKdzSJbsWAs.tPpctka9R4aafXFqUAR3f lkQVzmQms1uqv.11xT53DWpz7Os9E7fXptbDeggLrxEpl6.ABxgkyj7kxZQaBh6ZnRBJiFkFnW3S O91z23p9OqXZnMvfnm8Wi11wRJ3_o3qPfxqixLZ.fHbcnt.vfW5quln6S6nasrunrd7Se1g3CcSW 5ggbzzVxKSrOWIXR.HP3mwDFFpRvZRRDxi8VRLsj9aCODsANOkRRt7_jG2cuCBFiZoHIPdYFTaXO d.TB71uf6fjSgUTtRWYbN4g9BRYeiNzBB0zjRAB_OcPQ0s5NvM9jj9I0LYwaaiGOMU1oJy0pvFjf nQn0Io.ynyS76kf59Qp8P2rytQGJrIAhX.q.8Kg4_1DumduoPIisnSHdNxrH9liB.LpC54yigUJi gIt_Iq792Hfc1TQDswCwjWpUlJHTSSO2V7vQQdfrHmbAB0nWJdQTD_NPJE_AwVDw7Z1LaciqNjJE pAC2tRJiEhJfcIQSF19.WAL6E4SdF9zI2EEo3OmHmEs2qBt6G7oZWU.WSKSA_KiW1UdRscLz6sLm W.SZRA_L07i87HZIskmiFZFFSFRs79nxo X-Sonic-MF: X-Sonic-ID: e613aa9a-a350-41c5-a8e7-1586dc32c6bc Received: from sonic.gate.mail.ne1.yahoo.com by sonic314.consmr.mail.bf2.yahoo.com with HTTP; Wed, 23 Oct 2024 21:22:12 +0000 Received: by hermes--production-gq1-5dd4b47f46-5xsmt (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID 8a7972f72a0226c80fd86fd6bd5371c9; Wed, 23 Oct 2024 21:22:05 +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 v3 2/5] LSM: Replace context+len with lsm_context Date: Wed, 23 Oct 2024 14:21:55 -0700 Message-ID: <20241023212158.18718-3-casey@schaufler-ca.com> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20241023212158.18718-1-casey@schaufler-ca.com> References: <20241023212158.18718-1-casey@schaufler-ca.com> Precedence: bulk X-Mailing-List: selinux@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 | 14 +++------ 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(+), 121 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 921fa8eeb451..bd7094f225d1 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -437,9 +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); } @@ -492,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); } @@ -551,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); } @@ -1123,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 Wed Oct 23 21:21:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 13847984 Received: from sonic306-9.consmr.mail.bf2.yahoo.com (sonic306-9.consmr.mail.bf2.yahoo.com [74.6.132.48]) (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 08F3E1FF03C for ; Wed, 23 Oct 2024 21:22:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.6.132.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729718540; cv=none; b=o75LueWZTYFmiOaal+PdlPDGofRTs+NLfaDf6xJZz2FI+Bc338GkvufppEdtql1UXTmZ5gXjw3/l/uBBX1GKSHh1PebE901boX0M+BJVctKxPX4a/Gm/mOyGEcy54DkyFCNy+f+GKZFKLmeM1YW0AbkKvMi2rCj/sk6VOtizEPs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729718540; c=relaxed/simple; bh=K+VmdhpCUdytTi8DRHz8Ar8BXNcPqnkXTLuH0kUYKvw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=foaIFurgaHF95US5C55tNR5kf2gxJc/j3BeMbCAkr36IN2kAXJfQ04x9h0B1dBEr/zb6lIodXL9ZZkUOvEt4v97RJSQ34zFNULM7DgehF13Xe3FjfBJdf10Q2U9CGL8cNMidXcYAYr8qRJNnLdjp0juddKsAdow68HrblPEtSyk= 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=hiP81NE6; arc=none smtp.client-ip=74.6.132.48 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="hiP81NE6" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1729718531; bh=bHv1UO7IMwvV06D+Xx0bjVVo9VkCj8df8TY8GRx7WvY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=hiP81NE6SrxUIkz4toQvrZncIE0iBfMjmEuWXLEx5zTDOiQ2kw0tGEzyK/vQZ+TQrcZYtLGaQWzaStZCjGBbUDQEHcC+f9YsZlA/syXa1SKvDHm3/NnU2JNMrQ7BB6xQts0TymTL683mRQQ6DybTR6vIfVsHB0Y8NeuVZb0ZLtR93pQTxgRMij4zMkNXVG4uq0S7cxLaUVEb3+ZkJ4tY+YXemQV1DeZOcuuLyDsE8UF0AaTIeQOma7q/4GILsHlt7qs4PzzJqCqeAAIszQRfFhHkXiALsv46GX8ZDZuIqBIvd+MsrJNx760MMVABlCna/G7R9qG/Wl3TW9e1FTT1BA== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1729718531; bh=Fsvel/4O5ZDHyADk92whCGECzGNMWVRvOCFW3yM9AZs=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=NGpIwlff4P+0xSYP3Nlqxs1coe8zKqzA1YY0xB8+IIBxkf+CEI2dcrayL4l4xCSvO1iHbkBn0fib3i1vZAEW76Wr0P46HN0P9+r0LNy4Ubxq1SY/sVuq8kD+4ZcjHze7WCGt3n6/6KFmT61hlI/rC5wjil3TURO37TSfWO+7srbSTwP1zRaChlvmYUpJbWZRYkbcck15FH+eN07RtdjdhCVw7lh94cf6+SCu2BYMrcnofWkv/o88+M64AG/+AsRyYgs3ZUs6z+pRKvgvIu7ovQu4sdL8QuBcM1nrtQG3PZi7ij5ko8A6gh4jjE6tBfMDNnu1x0DaAa5rJR4hZA6/yw== X-YMail-OSG: Klnj0vMVM1lkYgT6wJziQAeareGLgfi_G2PJNgmw42ed._92cIEvbSNMEgxgkWs F2tVNsq9FUrTPSqGs6xk9YFkjwhojXR0Jma0GlxXZ_j1W9CvN4LAdrXh7pfqXXxEeZyXJpIOcuWF CUg96iJZF2zHqfeQ_OzxgRfBcstZ7A7l432s3zFut4uNwadStIr7ibD53RJYwPi_VofpSEtCQ12L g_RZAxcxssTQj42pfJecb714WublIyoPgAQvWqjC2oqedZg26X7RTU5vMDOoxNBC9kPBa4uTIiii yQpDLJzWQVBQYvL_QDOSJy3FfKNFzpCDCfA4r_zObdFrpakTpkruXcJN_Cofysq7w9l13wIUGagG ctNa7X3DuknX7d8UNKiTkbyVErr3bG2KTqie6_IHQu8Um5n.BS8nHSceHiLtwttJfYajhTc9uIvK aUVxnnHWLaocKDgphskJxJ6.Of5JFOy33TWRsWogd.BUYqDOQC6fqgRZ9UXitYkleIdUh89av8.o e29gYJTP0ymVZqWOg4an5lWPFisEQm3aOWSjMKc45hx0xJIqQ6z7GXkhtiDC8yciMZ0VeUopbWmV mlsyLr0hRkQFYecmDrDDMXAfwnhhATbQAdEALNzxVPHhzbu7DaBc0xmN2xLA8gHmdMqEBwf6LfoU X.WuwhbDZRVbL2NEKajx1XLL1iihtFdVuJfMA.radOkZag3g7ZRPkIq0atC6nTIhp1kCf6QCo72K t_HlTDmI_yySPS_n1RyGc51fPbR1Mufx6hPJupelxYfo2vNVHmrLd9aHtY8_2PMtJpte6YN440km BSDyKGuX5Urmsqioj9qZ6OI1KFDtONfzAZY0K2ZUUT0gJ5sLh0yAj8_YJWxo.lKf3XzHaIMjo5w2 5NJFrJtPMOv9MncCajBkeQ6r67ilieEgXxeknf1YnmXKrWL7JeJkuJ19MZJ0vDVz3JG.9c3x19jT quzFiNiWvHMamYDpMjwurW_ewQOYI.pl62PICcIau7rinImKz6VfqGF0YtX0KCLPHXNNP0OcDfZz B5cLyQ..H.ei.kBqR3aGwYltxbjc5xaIZZLcu7qJmF4JVgXLkUM3q6VYILLon52EyX2jsvqVzowK qw9gpxOEkm3qB.trzuj3k3ZxubchMNSeqjIpzRthSxGjC1gqyNM2MDAsGn2FxWUm6OsMlYR6oDEd iRaIELmb4hYL59yHv__fZan9jqInq4WrtqwJalLnIJY.RQp.OtF_YbAaJZbn_gsJ66QYfKlQMmJK MhOi9cbmgsDBUkidrWWncp3MPcrJXjHylGpZ6ltDCdO1Gsp.IUcSKXGGEFd2oyeEEf7RPAvMCoKq 8bTrwC6KRCKWSM3kRp1dGLyVN13QVxER_.305HJ2WYCM2AGA3oIi2v4DvMvcOL.jKyQkM8uZfHSo VBfuV2zcXkHY_uKBhVuBjaCiKuBmGvZ3FfhIbrfsxpUtjonzyD51uo0EFbWZ4wYdmbQQltq3z4ha qdrwtwYlWAYDA6ppnp.8SntowpiTuAWMz_wtehDdSuY9gBlqqRR1fjSQAYPtgX2ZOEXa3UUbVOFm mvltW_WmBGxDk.YWY8.G3y36M_tV7DowAZXXwoucywIALJjD73xgRM6J8jkFEib1yjO4rSpli7J4 f.8j8Z2JL2dY.HY2fzkQmymtLMAq0fkVe1w2tad7ugiGJukZpur82L_cYg6ttS52DjfYQZ0FzhwS 7GzYn41sfiWToosc6jr9RcN19iH.r87yFD9JNuT6V9LCQ997YirIFx5bp2Uc0J00JixLkPKCgj1w 8Qm3O1R9ZCGulJPPISWd9TF.5dIhs57Bp3a7Pc_h1hmtt9uL.Xadddi0NT2ciaQWSQDNlJs08VVT sp1lQaebpozOfub1HW4OGF1bcAdS8QlY4TmRn6dbnyzIdNFLm.FwKh2KK1kugVZbxO1NVAuYyIAH 4qgppb8Jp5bU3VQX6k3h3k6cdTv7doaLlZH9loPiSiInWOHv.yrZ24f1TLN3ss70XNVfAysoQDVl z37eMHYIR8101.lw3Myq5y_3UcPSKRWePF18lO3BIIP9NQPPK57o4_2wyHk287QW3bzsCRLQdpHQ MVxmYYSP21evzyLDAQ_.FUVA7JRKzOMZDTaCXN6yb6Gb5n45QJsEU8V3iOQhNI894zWnyyHHylYH .dDRWeZGlx7AbB9MFO1oeVd7B4h7VvU9l9zI2VwhrjSXntKk0f2eH1OIfp_LjsLEdTxKEqYoOoQ6 kRf1TJ5bVk.cJkzfUOjPo2V2oE7Sad8g9sZkOieGq09Tswsw40DlJFOu7BZI57cz5Xam455YpY5V 3PykhGfbgyihlvVOvrtm5qJjC6G.XMQ-- X-Sonic-MF: X-Sonic-ID: 0d0faeb1-d71f-4c26-9e3e-b78883624e4a Received: from sonic.gate.mail.ne1.yahoo.com by sonic306.consmr.mail.bf2.yahoo.com with HTTP; Wed, 23 Oct 2024 21:22:11 +0000 Received: by hermes--production-gq1-5dd4b47f46-5xsmt (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID 8a7972f72a0226c80fd86fd6bd5371c9; Wed, 23 Oct 2024 21:22:07 +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 v3 3/5] LSM: Use lsm_context in security_inode_getsecctx Date: Wed, 23 Oct 2024 14:21:56 -0700 Message-ID: <20241023212158.18718-4-casey@schaufler-ca.com> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20241023212158.18718-1-casey@schaufler-ca.com> References: <20241023212158.18718-1-casey@schaufler-ca.com> Precedence: bulk X-Mailing-List: selinux@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 Wed Oct 23 21:21:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 13847985 Received: from sonic307-8.consmr.mail.bf2.yahoo.com (sonic307-8.consmr.mail.bf2.yahoo.com [74.6.134.47]) (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 557FE1E7C16 for ; Wed, 23 Oct 2024 21:23:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.6.134.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729718632; cv=none; b=ErTNJkP9PiI0V68KNpDpPewrGlnl9/b3W+wINEmf04OiFl/Pqk5DuiwcTmQf3WzUIpbK7NJ6gdh96Q89X3MLIHqcVcyaIp6Op1JvO7j9uqyBa+Dl48WrYbizmUjtizmag1gSjlvxSFGFQK826a4rIPfHfa7iyjwWhC34DYZlGN0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729718632; c=relaxed/simple; bh=Sup8gk0Jh9dp2tp0MS3GDtUxMfc7JJz0W6FXIbQqBeI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=j1dexi3xIABVitmbb+gASIBiLztUlD4BeiajGjfgpzOEWR3lsM55gQkNkDgCvVqZ5cR0s8QWx82T+0ZyBLAxWt01KYAsC+UgwkjckqtggMh9Pov1Qi3YAwEP4yo6k9Sg5MNulvsejr8XfzTDQ89XcALZOdXHLw05PtMlApGmN5I= 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=bJa7AJnr; arc=none smtp.client-ip=74.6.134.47 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="bJa7AJnr" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1729718627; bh=3aGNvorbrJQqUlvZprczBEHswF8znlJbxyXOeuCfEmI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=bJa7AJnrffVyloCsT8u/qij63QPc6BSUwHcYKTrczeTMjUXPHTHuP6shYuFoOxKxFUwZR3HDc/V7fD1vauHrxKRLOzjawCV14U88uaFocagbMiaT2zowWWXhfGxPeCTp3CWG8IKQf3b9gnaVE3l/4eCg48Ev6qc7ajxospBIogA0koayxAwGizypcFnFlrB0RHfxeDqvfLs98kUdDfnhlTEFj/wIJUFmS4j+mq6ydcNNeRO5qEv4d/uZDO4yK6VhGyAQqeVGL+pTJ5vBX6IwGFVd6S6TsCeU15NTkvQGqB3SgGgQ0Hu3cOhkhRgmpJcaiIFiZZkBhXqQ9yxRMe26Vw== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1729718627; bh=cP6HoVGuYJbYaK54knQHpRlie56YRTrdCQJZh6j5PZH=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=s+Ysv6HFNi0jsmdyzAw3HjJ9B3eEIkzBLffMGM5NBVV+y5a+aU1zckjLAIRUDOJVEn7fatMJtP+7gnm1DKs1AfCVgmMnruGPmVM2Dv+v5PcricCvPiZ4cAY9v68dxRpCCb2JQTbs34ok7cj7uZT3rwMzJpQoQbETFTLqtVfkWk12YlbiCTcoQkmntpeR7As3LIQUt4gjw6O9jPq4RXNCd0910Ch0MwfUyEFW1f1dV4rsyPisFknmzqnj/t3I696XnsAM2PRXIiI+Jprs3IjtMxOoDRe3BUCB6nnBdnj3rmDktPMGNxntcTN7iR7Ert89PQK3P/oBNVLn/7Ydg2sx0g== X-YMail-OSG: rMKaiQ8VM1mF3D0Q77wRlza1iij_wJRglWPL5RJbYMngyqc2.moBZvK1ylcv3gQ fysSizy23Phn7OnY9iDDxTth91j.VMlj7bdsErmzphLbt2KdifhTp5ofTgV2KeEdOM25UOLg9ZIl kXvyD2i4P43C7GHtpgFumIj.C2iby1cfIAwcvuCh8Y3BblgllULgEKErAQNM6ooLQwnP1Rd7Wpe8 sK8LGzy5LGM_7GYDEkSPk3fU2ozta3weeWHMUaJFrgggTN0NJyP.McSqXwI4MZVS0FW429H85m4W vPPiHTARxsJd51QmKszyYbtUaUd51QuI1nsfqyYOfPcilN.x4kAI.b6y0pWPP22IWWvAIh_Wf1il UMG8lCkKeD9nTOT3MoA4Zyr2A6v0OpFKoCIf0okfiATJWC48EOBdrC3.mqE4ZmqS0T3ExfCnzoDs wkEnBt0WKybabMBnYGAH43rkQJbHZJxKpE8BZa2o8.U2Mpl3DNEgSGE9R1iFQGPBF81EkFThyWQu u6SetXa6KJHE9qMlLH84ART2EWzQmbeQXVHL5dQo6txcNyClExeoIk2t0XMgeEl19ACLnRlXiP4J xaTT2IiUt1EzJ2w1bRLQiz41RslcAqjRpSrThVBucYkpQhOtn1Pye3MAa3gLeHV6pztqw59w5y27 g1bFJ2y3t5URwBpQTy92fKKals2HRP1eTfzzfTzuC_3kPm.i0JXBkvwwBY02KEfoj558vqxRTmom wjDVd45HR54Fs68gVip4ZrX3OuYFzkF2GHgNAHaS_PI0nZnAPxz_CV3dLy285DYGpL.JM5fbu_t3 SLRD3fIWYCSvr8vkqthURfv5bkSZ1nhhLGToRvebCZME1roOnIYqtgO7rbC6PQVcHaxeouwEfhKP s1X2XRKtBEaExBt96gg8dkRB_kHRW7UoW0ks45.ih5LEEjNFTb67HyW4.uzo0wEQGRgZvIEWK53d HA6rdX6ble8bqRIowV3cNhKLggsXpGpi14ksWTJNv0Twoqb7PlJIFSg0MnNNfMKf6QW4_kN8RzeA Hs266ki1NM0u4yVxlXECkbJ5hg0hguCq5p7ouvmVgUdzveT0jQ1TJj4YBvWrOkXZE_tB8xRTUHwd Ms4NvUpV4d8cU.ESEb7xp_KsfOXm_WQThVJZVLLbiAflew_CB0de0oLMGldeNBw9QBTVvt78TdoQ 309cpZ_v2joVkc6S9ollgYaZhz7vsp297GE0Qb.yPfOG7sQoR5ChDFmgmmgM6_J5mkxGyGvoMMSK gKQ9XTcE29v.o4lVj0F50tavgOfv1FI1TFnLcfmErwax7lRNfRB5D.xnOzESjiSK_euqIUTpGfo. aTvRiCGqmK2uhe2daTLi3DSGnwTkuDqEeC1C.rNwsNCaIWwGsN_cZR459u877giGrJu8le5fXTbR fwPMky9_cTU6u6uM1jJ8zKoedaeufVZCL9dn3V0ANWG6m9vHM4BMtNOeZBIqbGNziEi7XjAsoVhV AJA9SkSYAr3pnSK3leKcIQql0LC57Zi.MPU6iRmX4QW_IceMok3rIdq8OmSXZddBXhumR7qEyl0h JzcLgy5PfEGUX9kU.PpZOXcQOukq6P_a3BxYWhGaHhlaU7xT50epKST5Fi5AkO3lEdnm5rIrjD4r tBIzvJrhMdFcHU1CS_caCt4wokp3cGSYUEDHgpuO3nEI_sYa7jinxgHk_Ev1h.vt67hlWafJ1xzW QOu0uT5lIhsxONSGF1ymDdmNiE4Iwn0wiLpLD8IfBZozcLebdTrX1oxw4dq1pun90xJJzw99Mwfr S7BwGtBUFDSuptgyJ.H0y8yJglBaeB9SN8M1clhY9njZHiYhiZt1O5jFQJab45hTaLJ90YYzYv0M e1uE66KY.u0GvdagfURyC6Us3NUywrcoj71yl51sct4RPkO2dIcydYVLd2is4AD4TGA9jsUAs3nj _MovYCUwXfmvO3t8yaiwvXG_10Zo1Jcab4D3t211Xgq._ZolBYf_KYai6_nvhp5AfmN_PKaDliA6 iH.9nUBXaFKR5ENFCRzjKtuqnZ84Hf4GbVsNosVTB.CKLsDVOTcjGa47bfqY5bKrwG3gCWRlWRHu 4._oi_MmtwjqrfpSa2Qp.2KYyl6CaEnUr1DxGT.wjP5lNekTCmRhFC9Jsu_hp63hg2k15DZQm1sh 2YQJF_wh_wj.cc6oin6Ku7pA4FhX5mTPCAaWIcMIJPR2D.jOzr1NRu8BR6yY675cr0gncw.kDp2m FDwRtqqYIqdq8HFk22lHwIJ9L0AetvPNizLQrAIqCuPArSl.gmWmH6rkN3Ks9p14m_pTqhGbxyZg ZO_S5tBpp50l_RooLOni.srrB X-Sonic-MF: X-Sonic-ID: db6fdd30-de6b-4b5e-8649-08f948fd5c07 Received: from sonic.gate.mail.ne1.yahoo.com by sonic307.consmr.mail.bf2.yahoo.com with HTTP; Wed, 23 Oct 2024 21:23:47 +0000 Received: by hermes--production-gq1-5dd4b47f46-pfhh2 (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID d261940d1cdfc655543cc442dda3a810; Wed, 23 Oct 2024 21:23:42 +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 v3 4/5] LSM: lsm_context in security_dentry_init_security Date: Wed, 23 Oct 2024 14:21:57 -0700 Message-ID: <20241023212158.18718-5-casey@schaufler-ca.com> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20241023212158.18718-1-casey@schaufler-ca.com> References: <20241023212158.18718-1-casey@schaufler-ca.com> Precedence: bulk X-Mailing-List: selinux@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. 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/nfs4proc.c | 20 ++++++++++++-------- include/linux/lsm_hook_defs.h | 2 +- include/linux/security.h | 26 +++----------------------- security/security.c | 9 ++++----- security/selinux/hooks.c | 9 +++++---- 8 files changed, 50 insertions(+), 70 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/nfs4proc.c b/fs/nfs/nfs4proc.c index 76776d716744..0b116ef3a752 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -114,6 +114,7 @@ static inline struct nfs4_label * nfs4_label_init_security(struct inode *dir, struct dentry *dentry, struct iattr *sattr, struct nfs4_label *label) { + struct lsm_context shim; int err; if (label == NULL) @@ -128,21 +129,24 @@ nfs4_label_init_security(struct inode *dir, struct dentry *dentry, label->label = NULL; err = security_dentry_init_security(dentry, sattr->ia_mode, - &dentry->d_name, NULL, - (void **)&label->label, &label->len); - if (err == 0) - return label; + &dentry->d_name, NULL, &shim); + if (err) + return NULL; - return NULL; + label->label = shim.context; + label->len = shim.len; + return label; } static inline void nfs4_label_release_security(struct nfs4_label *label) { - struct lsm_context scaff; /* scaffolding */ + struct lsm_context shim; if (label) { - lsmcontext_init(&scaff, label->label, label->len, 0); - security_release_secctx(&scaff); + shim.context = label->label; + shim.len = label->len; + shim.id = LSM_ID_UNDEF; + security_release_secctx(&shim); } } static inline u32 *nfs4_bitmask(struct nfs_server *server, struct nfs4_label *label) 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/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 Wed Oct 23 21:21:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 13847986 Received: from sonic314-22.consmr.mail.bf2.yahoo.com (sonic314-22.consmr.mail.bf2.yahoo.com [74.6.132.196]) (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 D9B5E1FBF4C for ; Wed, 23 Oct 2024 21:23:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.6.132.196 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729718635; cv=none; b=LiVQtd7QTAudzP0E2nwu75Uqzqfvv5RujeZ/HVgoaCQ89OeDT8eP5krze9mdeUjr4grFZW3M9uiPq1gkZOaJXngA6kKRGL51yIfT3tSZk8UdbZO2V/YgER1yXSHR4RbepZUPZXr7MuyRE9Wog7Q2sx5JYIYs7i0HZW+3H52Th60= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729718635; c=relaxed/simple; bh=xI5Udp7+iPy8mZha0q7CIj13Ny/nmKfB0rckcmSATx4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=m8VD0y44SZfMooeWnDsVrehgTtD/V4KA3VSwo0/sD3ho4dv+3pDoa0o34zHYnspzzyNkDMCEhadq4PixcNGojGcUAgY0ltJ9sKy/YA781r4N7PMS90X1tZAnwVOKrzydmQsvoJws4uxu0SkgKTj2gxeWUMrhDmwQBAHLQNUxP2w= 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=fr7uK6et; arc=none smtp.client-ip=74.6.132.196 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="fr7uK6et" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1729718632; bh=UnQ0rI2w33MXrRKYOUPZC8/87Ao4K9IiWmtcpAV7+bI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=fr7uK6et/YAx+qyUKA6eygkZedeebOOL6bKeY2Sndbhjumpk95padF92MsLEvYfv+nczDAThs9IgoCyts0C/lItVJdCsbgh0ZbWjm1EfxUqANMtLtSgZQ7bqaH5+qCw3CR4/Z1yDXpdL2oqJxVMKGYdjBA1U0lyapksb4gmyLquy0SLXNez5aLue1+ymRq2/WJnr5gtKAdMkgB8D2pGREqaant+MBP1BBiSwwuYuzH4eFakhIZQ/SDYL3FbTuGtCYd7K1cG8G4OuOOhm6aM0frYO9OVPD8k+o0As3wD5rVI2mKCPExhmjQ7ln6nRu2f1bn6smUQ2VmNzib9KqpZ9eA== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1729718632; bh=BtzF3sJGDcYWa7OTjtwH1ZCDRrlzg+6XoLpnavP8yrW=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=qqHEoFeRaQO+PRJ6aEUO/jCkTdizp4xQEI4RwOQdCl3oSoPEiiyjC8Edx2xmY+jFz+duZtL/2CtbvsWZq6lbvQgk7cadQdWzlaMMW4HA3T9VPZi4Y84hxKhiC/y9e5JUexpIQa719PjYg3kdblSr1VFHHlg0sPKowy1wdVKdJS+0xC/gzi7P/DWUL8eYvBB7zpwtOfS74BQS3L3YgHx5qeu1oXwBwtYcKBNCymJ1QwBhbrAckrgbOAUpG5TKFj5FRh3roH54QM2Eio/oVyjufg/0pwevatHW0vcWadSdGdyuALJ1eSImYeHs0maf4Q0dN2uWzREj3pHXRRC2FVUzFw== X-YMail-OSG: DYTnJWUVM1nuMpFoEsfs9VW7mCAzIzNOUfaT6wet0nBcvqIzpI6zQpBsEkyLSHS LBSZkPUVNZQwH4PCdqwqey6eZ5Ha6btUjGs9CRUMj4e_ii3qur.dcLLuC_h9L0B6VFUUUR42OdY5 J4aUpkOL_2J9mb6oQxEgFyGXoXNd5LOFdDQj3arTOxWoczEq0TZWX2CmU9UewVLYr2ep1mxsdCi2 Q8kd_7d507eAd3UgzH.2d7vuijBjvX9E098.4IpGhCxlHIO5jVe9.0LZeJ2tOFqRo9_UqR.ncj58 he0bIhV6QnBLv5RKxYWhrtT98ECFCG0zkovfxpNBPRYBNBW2UCefRKNKyuzrxVPsWejYckzv_FeG Z8oX53z7lqdXomVUMNOtnYI.njw_WIdSb5UIzuFnV9zGba9iSzZ5E97RvdmykNbYeBkaH8P.O8wI pM0QPQ8IOq_YfboQqohCNBB1Q_W9sxChWMSOavo_UGBf4VeuO8jFAgN5pCKL0bdVmOJL7q5BNYjf XzENkJj9BOvF9bsd6Lb0AKbu3rwdKwC58Cn6ZUzxGpIoYbwrSSmpFafaFzDZHdV2tofohqaAfEaj N8NzaQoHo_2YYvcJ6mpVN5VKpCm7LBN72Ypq65tCm_vTC_DvFfnQpFew32XpcKGSptiFRIPSXlKA MiQfNU8N43SVvgd7U8UVoZsuVDRMRUqtko10f6PdP_LfrQJEYbpLPL012YqJM45ZJmNmyrLDyseO OspWQcvxDsAPMwsM1o85WKzAREPUolCEILYJy279n7u0xy5Xo6DwE3UVRnkrC2Rz8RHQ9H4zQ0er enJ5xXKWW2I1qhJN2rY7WNKJGeHti04gFKta7D2fqLwhqxbdlLSBMt.RqVRaNNLznJ6j8XzAPxDo S1GUGdFe58E4NjsdtyX_cDx0qIgsBcl29FZ0U_yTvWDAH0FM.fmjA4CdiLTrSejFAERe7ftTRl5I 3hZIh46uURW1Uvde99rgjzQl2WRInYZELT1lZVZQTvsxHSesHTsUSLm6KLCgvocbRJ1T8.0CzVO6 A1_pSod3p3w2DJF.ag_RObL3Qt4RnK_.WZdZhoB3m2TZ3PX_vL4cTISPuRKotVZJgFA5vrjAOXsc ERIcvkxBTp7ZxgGICdyUDigX4RlbtThOKztYEKJY.TsnJEe5at4HNqGDWtoMIBQfqZ.WRzK55Yk0 YeWXAktwTg63mO5vZyIrEQjyZPQLM18wkxJVsDsh7NBbooUirke6H45PYFed9LtYwcWD6txMbEGd IK8BUDtNjDFRHwusbq78INyOQaceCguh_OX7V5AnRzR.Dg0B6EhX.xOo2E1RNHjqkhm0r556HE52 5B1R.og1bGGbYkhtXznVrloql.qL5aZyUYdCUNzMqXXTiu9qDBIX5hss9de4wXULR9lGfUZ.CAJV hBi6TedEiaC2zEHw4HhBjCerAntGTANOxuIdLOOCJV89MlvbUq1kYzTAsuUm4XlShB.h0yWcXbCa IsMnFeIm._9wS7h32vzdpPbuIOrQjQdquYfGyD6K_tZ4Wj0UGsvA9sirU8ZX1cwWQuTqPThxpkp1 eKKvs5nyRlVf2CVy5fELFd5LHlBxfb8WzlUPlkvg.vLUuUmw1b92teD649Gvrpd5XVD61mjBAyIl LHyZzqU2Jz2fJvpo.VndfSwbTrR44bRcMBJRm9WSwwJyGi9i2LBRaDiVha0q1xp5Z_pSBAR7VLC. spG8YU2uj2wzXa97AeZ7T5SGHI2CAblS8zhwie3cSngh1gLr7hJ.ulnZEmLlr_fCy0u2f_6BcjmM bQw00GFMwBqpq_QJA_Y7Wzc_Kccku9fIYeCIkchxWvRkkRNG_YQVVst9u6qQdzAEuNlgKqq0gpYA x2VTVFg_MQkbUSvTFPRJtVAx.bbQZAraCwdTue3Nbhx0q0HjlCwXR._edJ75RNojyJx_Kz9bT.Uv rEZbPRBwssicwFQHxg2IIuQiR80wEQapNiXbslI9ylCtAZ9CI9Yf3pRLmfMjqNiTfqFQDgYkphBt iOOWRegwp5RvJYdQdwNE.Wzm9vV3i8FPJMAYE3bsJCOYIOVhpFyDmkNyfh1JtOFAed9S_xM9xNGB rqN99HBamaTkHjyD5RDRreqoQUumCKLOo9ZN31pJ1gbqZmZni0Rm0loLHfKAjsVM8TmxR_bmfrBj j2lcliA4ECttSVgnVFsiWuKCsf9v23Xmd9fLocOxrDaZfv0hox0inNmtrwxhcZ0KWWxnxkXh4x14 bqRDOEcd4ujewUfd1G9qMixyGYYHohAl1onzTTIA6Pjm2_cjU0VXkZqZQtv9.j5myKezWRzOJGkf lXKH8pJX5ziTsN.V.Zkv4gScJdQ4- X-Sonic-MF: X-Sonic-ID: 0349e8d1-6b76-498c-9fd1-a59c85c93dce Received: from sonic.gate.mail.ne1.yahoo.com by sonic314.consmr.mail.bf2.yahoo.com with HTTP; Wed, 23 Oct 2024 21:23:52 +0000 Received: by hermes--production-gq1-5dd4b47f46-pfhh2 (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID d261940d1cdfc655543cc442dda3a810; Wed, 23 Oct 2024 21:23:44 +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 v3 5/5] LSM: secctx provider check on release Date: Wed, 23 Oct 2024 14:21:58 -0700 Message-ID: <20241023212158.18718-6-casey@schaufler-ca.com> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20241023212158.18718-1-casey@schaufler-ca.com> References: <20241023212158.18718-1-casey@schaufler-ca.com> Precedence: bulk X-Mailing-List: selinux@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 | 13 +++++-------- security/selinux/hooks.c | 13 +++++-------- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/security/apparmor/secid.c b/security/apparmor/secid.c index 5d92fc3ab8b4..854613e58e34 100644 --- a/security/apparmor/secid.c +++ b/security/apparmor/secid.c @@ -122,14 +122,11 @@ 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); + cp->context = NULL; + cp->id = LSM_ID_UNDEF; + } } /** diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 79776a5e651d..996e765b6823 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -6640,14 +6640,11 @@ 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); + cp->context = NULL; + cp->id = LSM_ID_UNDEF; + } } static void selinux_inode_invalidate_secctx(struct inode *inode)