Re: [RFC PATCH v9 09/16] block|security: add LSM blob to block_device
On Mon, Jan 30, 2023 at 5:58 PM Fan Wu wrote: > > From: Deven Bowers > > block_device structures can have valuable security properties, > based on how they are created, and what subsystem manages them. > > By adding LSM storage to this structure, this data can be accessed > at the LSM layer. > > Signed-off-by: Deven Bowers > Signed-off-by: Fan Wu > Reviewed-by: Casey Schaufler ... > --- > block/bdev.c | 7 > include/linux/blk_types.h | 3 ++ > include/linux/lsm_hook_defs.h | 5 +++ > include/linux/lsm_hooks.h | 12 ++ > include/linux/security.h | 22 +++ > security/security.c | 70 +++ > 6 files changed, 119 insertions(+) > > diff --git a/block/bdev.c b/block/bdev.c > index edc110d90df4..f8db53b47c00 100644 > --- a/block/bdev.c > +++ b/block/bdev.c > @@ -24,6 +24,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -396,6 +397,11 @@ static struct inode *bdev_alloc_inode(struct super_block > *sb) > if (!ei) > return NULL; > memset(>bdev, 0, sizeof(ei->bdev)); > + > + if (security_bdev_alloc(>bdev)) { > + kmem_cache_free(bdev_cachep, ei); > + return NULL; > + } > return >vfs_inode; > } > > @@ -405,6 +411,7 @@ static void bdev_free_inode(struct inode *inode) > > free_percpu(bdev->bd_stats); > kfree(bdev->bd_meta_info); > + security_bdev_free(bdev); > > if (!bdev_is_partition(bdev)) { > if (bdev->bd_disk && bdev->bd_disk->bdi) > diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h > index 99be590f952f..137a04f45c17 100644 > --- a/include/linux/blk_types.h > +++ b/include/linux/blk_types.h > @@ -68,6 +68,9 @@ struct block_device { > #ifdef CONFIG_FAIL_MAKE_REQUEST > boolbd_make_it_fail; > #endif > +#ifdef CONFIG_SECURITY > + void*security; > +#endif > } __randomize_layout; > > #define bdev_whole(_bdev) \ > diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h > index ed6cb2ac55fa..1f79029c9e28 100644 > --- a/include/linux/lsm_hook_defs.h > +++ b/include/linux/lsm_hook_defs.h > @@ -417,3 +417,8 @@ LSM_HOOK(int, 0, uring_override_creds, const struct cred > *new) > LSM_HOOK(int, 0, uring_sqpoll, void) > LSM_HOOK(int, 0, uring_cmd, struct io_uring_cmd *ioucmd) > #endif /* CONFIG_IO_URING */ > + > +LSM_HOOK(int, 0, bdev_alloc_security, struct block_device *bdev) > +LSM_HOOK(void, LSM_RET_VOID, bdev_free_security, struct block_device *bdev) > +LSM_HOOK(int, 0, bdev_setsecurity, struct block_device *bdev, const char > *name, > +const void *value, size_t size) > diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h > index 0a5ba81f7367..b622ceb57d83 100644 > --- a/include/linux/lsm_hooks.h > +++ b/include/linux/lsm_hooks.h > @@ -1618,6 +1618,17 @@ > * @what: kernel feature being accessed. > * Return 0 if permission is granted. > * > + * @bdev_alloc_security: > + * Initialize the security field inside a block_device structure. > + * > + * @bdev_free_security: > + * Cleanup the security information stored inside a block_device > structure. > + * > + * @bdev_setsecurity: > + * Set a security property associated with @name for @bdev with > + * value @value. @size indicates the size of @value in bytes. > + * If a @name is not implemented, return -EOPNOTSUPP. > + * Just a heads-up that the LSM hook comment blocks are moving to security/security.c very soon now (if they are not already there by the time you read this). https://lore.kernel.org/linux-security-module/20230217032625.678457-1-p...@paul-moore.com > diff --git a/security/security.c b/security/security.c > index d1571900a8c7..5c81dd3b1350 100644 > --- a/security/security.c > +++ b/security/security.c > @@ -2705,6 +2730,51 @@ int security_locked_down(enum lockdown_reason what) > } > EXPORT_SYMBOL(security_locked_down); > > +int security_bdev_alloc(struct block_device *bdev) > +{ > + int rc = 0; > + > + rc = lsm_bdev_alloc(bdev); > + if (unlikely(rc)) > + return rc; > + > + rc = call_int_hook(bdev_alloc_security, 0, bdev); > + if (unlikely(rc)) > + security_bdev_free(bdev); > + > + return LSM_RET_DEFAULT(bdev_alloc_security); > +} > +EXPORT_SYMBOL(security_bdev_alloc); > + > +void security_bdev_free(struct block_device *bdev) > +{ > + if (!bdev->security) > + return; > + > + call_void_hook(bdev_free_security, bdev); > + > + kfree(bdev->security); > + bdev->security = NULL; > +} > +EXPORT_SYMBOL(security_bdev_free); > + > +int security_bdev_setsecurity(struct block_device *bdev, > + const char *name, const void *value, > + size_t size) > +{ > + int rc = 0; > + struct
Re: [RFC PATCH v9 09/16] block|security: add LSM blob to block_device
On Tue, Jan 31, 2023 at 12:53:59AM -0800, Christoph Hellwig wrote: > On Mon, Jan 30, 2023 at 02:57:24PM -0800, Fan Wu wrote: > > From: Deven Bowers > > > > block_device structures can have valuable security properties, > > based on how they are created, and what subsystem manages them. > > That's a lot of cloudy talk but no real explanation. Sorry for being too general here. Currently the only use target of this hook is dm-verity. We use the newly added security hook to save the dm-verity roothash and signature to the new bdev security blob during the bdev creation time, so LSMs can leverage this information to protect the system. I will add this example in the next version. -Fan -- Linux-audit mailing list Linux-audit@redhat.com https://listman.redhat.com/mailman/listinfo/linux-audit
Re: [RFC PATCH v9 09/16] block|security: add LSM blob to block_device
On Mon, Jan 30, 2023 at 02:57:24PM -0800, Fan Wu wrote: > From: Deven Bowers > > block_device structures can have valuable security properties, > based on how they are created, and what subsystem manages them. That's a lot of cloudy talk but no real explanation. -- Linux-audit mailing list Linux-audit@redhat.com https://listman.redhat.com/mailman/listinfo/linux-audit
[RFC PATCH v9 09/16] block|security: add LSM blob to block_device
From: Deven Bowers block_device structures can have valuable security properties, based on how they are created, and what subsystem manages them. By adding LSM storage to this structure, this data can be accessed at the LSM layer. Signed-off-by: Deven Bowers Signed-off-by: Fan Wu Reviewed-by: Casey Schaufler --- v2: + No Changes v3: + Minor style changes from checkpatch --strict v4: + No Changes v5: + Allow multiple callers to call security_bdev_setsecurity v6: + Simplify security_bdev_setsecurity break condition v7: + Squash all dm-verity related patches to two patches, the additions to dm-verity/fs, and the consumption of the additions. v8: + Split dm-verity related patches squashed in v7 to 3 commits based on topic: + New LSM hook + Consumption of hook outside LSM + Consumption of hook inside LSM. + change return of security_bdev_alloc / security_bdev_setsecurity to LSM_RET_DEFAULT instead of 0. + Change return code to -EOPNOTSUPP, bring inline with other setsecurity hooks. v9: + Add Reviewed-by: Casey Schaufler + Remove unlikely when calling LSM hook + Make the security field dependent on CONFIG_SECURITY --- block/bdev.c | 7 include/linux/blk_types.h | 3 ++ include/linux/lsm_hook_defs.h | 5 +++ include/linux/lsm_hooks.h | 12 ++ include/linux/security.h | 22 +++ security/security.c | 70 +++ 6 files changed, 119 insertions(+) diff --git a/block/bdev.c b/block/bdev.c index edc110d90df4..f8db53b47c00 100644 --- a/block/bdev.c +++ b/block/bdev.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -396,6 +397,11 @@ static struct inode *bdev_alloc_inode(struct super_block *sb) if (!ei) return NULL; memset(>bdev, 0, sizeof(ei->bdev)); + + if (security_bdev_alloc(>bdev)) { + kmem_cache_free(bdev_cachep, ei); + return NULL; + } return >vfs_inode; } @@ -405,6 +411,7 @@ static void bdev_free_inode(struct inode *inode) free_percpu(bdev->bd_stats); kfree(bdev->bd_meta_info); + security_bdev_free(bdev); if (!bdev_is_partition(bdev)) { if (bdev->bd_disk && bdev->bd_disk->bdi) diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index 99be590f952f..137a04f45c17 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h @@ -68,6 +68,9 @@ struct block_device { #ifdef CONFIG_FAIL_MAKE_REQUEST boolbd_make_it_fail; #endif +#ifdef CONFIG_SECURITY + void*security; +#endif } __randomize_layout; #define bdev_whole(_bdev) \ diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index ed6cb2ac55fa..1f79029c9e28 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -417,3 +417,8 @@ LSM_HOOK(int, 0, uring_override_creds, const struct cred *new) LSM_HOOK(int, 0, uring_sqpoll, void) LSM_HOOK(int, 0, uring_cmd, struct io_uring_cmd *ioucmd) #endif /* CONFIG_IO_URING */ + +LSM_HOOK(int, 0, bdev_alloc_security, struct block_device *bdev) +LSM_HOOK(void, LSM_RET_VOID, bdev_free_security, struct block_device *bdev) +LSM_HOOK(int, 0, bdev_setsecurity, struct block_device *bdev, const char *name, +const void *value, size_t size) diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index 0a5ba81f7367..b622ceb57d83 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -1618,6 +1618,17 @@ * @what: kernel feature being accessed. * Return 0 if permission is granted. * + * @bdev_alloc_security: + * Initialize the security field inside a block_device structure. + * + * @bdev_free_security: + * Cleanup the security information stored inside a block_device structure. + * + * @bdev_setsecurity: + * Set a security property associated with @name for @bdev with + * value @value. @size indicates the size of @value in bytes. + * If a @name is not implemented, return -EOPNOTSUPP. + * * Security hooks for perf events * * @perf_event_open: @@ -1687,6 +1698,7 @@ struct lsm_blob_sizes { int lbs_ipc; int lbs_msg_msg; int lbs_task; + int lbs_bdev; }; /* diff --git a/include/linux/security.h b/include/linux/security.h index 479e154a12b8..7dea630bff5f 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -487,6 +487,11 @@ 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_locked_down(enum lockdown_reason what); +int security_bdev_alloc(struct block_device *bdev); +void security_bdev_free(struct block_device *bdev); +int