diff mbox series

[v2,10/13] LSM: Create new security_cred_getlsmblob LSM hook

Message ID 20240830003411.16818-11-casey@schaufler-ca.com (mailing list archive)
State Handled Elsewhere
Delegated to: Paul Moore
Headers show
Series [v2,01/13] LSM: Add the lsmblob data structure. | expand

Commit Message

Casey Schaufler Aug. 30, 2024, 12:34 a.m. UTC
Create a new LSM hook security_cred_getlsmblob() which, like
security_cred_getsecid(), fetches LSM specific attributes from the
cred structure.  The associated data elements in the audit sub-system
are changed from a secid to a lsmblob to accommodate multiple possible
LSM audit users.

Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
Cc: linux-integrity@vger.kernel.org
Cc: audit@vger.kernel.org
Cc: selinux@vger.kernel.org
Cc: Todd Kjos <tkjos@google.com>
---
 include/linux/lsm_hook_defs.h     |  2 ++
 include/linux/security.h          |  7 +++++++
 security/integrity/ima/ima_main.c |  7 ++-----
 security/security.c               | 15 +++++++++++++++
 security/selinux/hooks.c          |  8 ++++++++
 security/smack/smack_lsm.c        | 18 ++++++++++++++++++
 6 files changed, 52 insertions(+), 5 deletions(-)

Comments

kernel test robot Aug. 30, 2024, 3:26 p.m. UTC | #1
Hi Casey,

kernel test robot noticed the following build warnings:

[auto build test WARNING on pcmoore-audit/next]
[also build test WARNING on pcmoore-selinux/next zohar-integrity/next-integrity linus/master v6.11-rc5 next-20240830]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Casey-Schaufler/LSM-Add-the-lsmblob-data-structure/20240830-085050
base:   https://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit.git next
patch link:    https://lore.kernel.org/r/20240830003411.16818-11-casey%40schaufler-ca.com
patch subject: [PATCH v2 10/13] LSM: Create new security_cred_getlsmblob LSM hook
config: i386-buildonly-randconfig-006-20240830 (https://download.01.org/0day-ci/archive/20240830/202408302309.08WssiJu-lkp@intel.com/config)
compiler: clang version 18.1.5 (https://github.com/llvm/llvm-project 617a15a9eac96088ae5e9134248d8236e34b91b1)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240830/202408302309.08WssiJu-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202408302309.08WssiJu-lkp@intel.com/

All warnings (new ones prefixed by >>):

   In file included from kernel/dma/swiotlb.c:53:
   In file included from include/trace/events/swiotlb.h:41:
   In file included from include/trace/define_trace.h:102:
   In file included from include/trace/trace_events.h:21:
   In file included from include/linux/trace_events.h:10:
   In file included from include/linux/perf_event.h:62:
   include/linux/security.h:1199:3: error: use of undeclared identifier 'secid'
    1199 |         *secid = 0;
         |          ^
>> kernel/dma/swiotlb.c:639:20: warning: shift count >= width of type [-Wshift-count-overflow]
     638 |                 if (IS_ENABLED(CONFIG_ZONE_DMA32) &&
         |                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     639 |                     phys_limit < DMA_BIT_MASK(64) &&
         |                     ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~
     640 |                     !(gfp & (__GFP_DMA32 | __GFP_DMA)))
         |                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/dma-mapping.h:77:54: note: expanded from macro 'DMA_BIT_MASK'
      77 | #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
         |                                                      ^
   include/linux/compiler.h:55:47: note: expanded from macro 'if'
      55 | #define if(cond, ...) if ( __trace_if_var( !!(cond , ## __VA_ARGS__) ) )
         |                            ~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/compiler.h:57:52: note: expanded from macro '__trace_if_var'
      57 | #define __trace_if_var(cond) (__builtin_constant_p(cond) ? (cond) : __trace_if_value(cond))
         |                                                    ^~~~
>> kernel/dma/swiotlb.c:639:20: warning: shift count >= width of type [-Wshift-count-overflow]
     638 |                 if (IS_ENABLED(CONFIG_ZONE_DMA32) &&
         |                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     639 |                     phys_limit < DMA_BIT_MASK(64) &&
         |                     ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~
     640 |                     !(gfp & (__GFP_DMA32 | __GFP_DMA)))
         |                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/dma-mapping.h:77:54: note: expanded from macro 'DMA_BIT_MASK'
      77 | #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
         |                                                      ^
   include/linux/compiler.h:55:47: note: expanded from macro 'if'
      55 | #define if(cond, ...) if ( __trace_if_var( !!(cond , ## __VA_ARGS__) ) )
         |                            ~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/compiler.h:57:61: note: expanded from macro '__trace_if_var'
      57 | #define __trace_if_var(cond) (__builtin_constant_p(cond) ? (cond) : __trace_if_value(cond))
         |                                                             ^~~~
>> kernel/dma/swiotlb.c:639:20: warning: shift count >= width of type [-Wshift-count-overflow]
     638 |                 if (IS_ENABLED(CONFIG_ZONE_DMA32) &&
         |                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     639 |                     phys_limit < DMA_BIT_MASK(64) &&
         |                     ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~
     640 |                     !(gfp & (__GFP_DMA32 | __GFP_DMA)))
         |                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/dma-mapping.h:77:54: note: expanded from macro 'DMA_BIT_MASK'
      77 | #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
         |                                                      ^
   include/linux/compiler.h:55:47: note: expanded from macro 'if'
      55 | #define if(cond, ...) if ( __trace_if_var( !!(cond , ## __VA_ARGS__) ) )
         |                            ~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/compiler.h:57:86: note: expanded from macro '__trace_if_var'
      57 | #define __trace_if_var(cond) (__builtin_constant_p(cond) ? (cond) : __trace_if_value(cond))
         |                                                                     ~~~~~~~~~~~~~~~~~^~~~~
   include/linux/compiler.h:68:3: note: expanded from macro '__trace_if_value'
      68 |         (cond) ?                                        \
         |          ^~~~
   3 warnings and 1 error generated.


vim +639 kernel/dma/swiotlb.c

79636caad3618e Petr Tesarik 2023-08-01  602  
79636caad3618e Petr Tesarik 2023-08-01  603  /**
79636caad3618e Petr Tesarik 2023-08-01  604   * swiotlb_alloc_tlb() - allocate a dynamic IO TLB buffer
79636caad3618e Petr Tesarik 2023-08-01  605   * @dev:	Device for which a memory pool is allocated.
79636caad3618e Petr Tesarik 2023-08-01  606   * @bytes:	Size of the buffer.
79636caad3618e Petr Tesarik 2023-08-01  607   * @phys_limit:	Maximum allowed physical address of the buffer.
79636caad3618e Petr Tesarik 2023-08-01  608   * @gfp:	GFP flags for the allocation.
79636caad3618e Petr Tesarik 2023-08-01  609   *
79636caad3618e Petr Tesarik 2023-08-01  610   * Return: Allocated pages, or %NULL on allocation failure.
79636caad3618e Petr Tesarik 2023-08-01  611   */
79636caad3618e Petr Tesarik 2023-08-01  612  static struct page *swiotlb_alloc_tlb(struct device *dev, size_t bytes,
79636caad3618e Petr Tesarik 2023-08-01  613  		u64 phys_limit, gfp_t gfp)
79636caad3618e Petr Tesarik 2023-08-01  614  {
79636caad3618e Petr Tesarik 2023-08-01  615  	struct page *page;
79636caad3618e Petr Tesarik 2023-08-01  616  
79636caad3618e Petr Tesarik 2023-08-01  617  	/*
79636caad3618e Petr Tesarik 2023-08-01  618  	 * Allocate from the atomic pools if memory is encrypted and
79636caad3618e Petr Tesarik 2023-08-01  619  	 * the allocation is atomic, because decrypting may block.
79636caad3618e Petr Tesarik 2023-08-01  620  	 */
79636caad3618e Petr Tesarik 2023-08-01  621  	if (!gfpflags_allow_blocking(gfp) && dev && force_dma_unencrypted(dev)) {
79636caad3618e Petr Tesarik 2023-08-01  622  		void *vaddr;
79636caad3618e Petr Tesarik 2023-08-01  623  
79636caad3618e Petr Tesarik 2023-08-01  624  		if (!IS_ENABLED(CONFIG_DMA_COHERENT_POOL))
79636caad3618e Petr Tesarik 2023-08-01  625  			return NULL;
79636caad3618e Petr Tesarik 2023-08-01  626  
79636caad3618e Petr Tesarik 2023-08-01  627  		return dma_alloc_from_pool(dev, bytes, &vaddr, gfp,
79636caad3618e Petr Tesarik 2023-08-01  628  					   dma_coherent_ok);
79636caad3618e Petr Tesarik 2023-08-01  629  	}
79636caad3618e Petr Tesarik 2023-08-01  630  
79636caad3618e Petr Tesarik 2023-08-01  631  	gfp &= ~GFP_ZONEMASK;
79636caad3618e Petr Tesarik 2023-08-01  632  	if (phys_limit <= DMA_BIT_MASK(zone_dma_bits))
79636caad3618e Petr Tesarik 2023-08-01  633  		gfp |= __GFP_DMA;
79636caad3618e Petr Tesarik 2023-08-01  634  	else if (phys_limit <= DMA_BIT_MASK(32))
79636caad3618e Petr Tesarik 2023-08-01  635  		gfp |= __GFP_DMA32;
79636caad3618e Petr Tesarik 2023-08-01  636  
a5e3b127455d07 Petr Tesarik 2023-11-02  637  	while (IS_ERR(page = alloc_dma_pages(gfp, bytes, phys_limit))) {
79636caad3618e Petr Tesarik 2023-08-01  638  		if (IS_ENABLED(CONFIG_ZONE_DMA32) &&
79636caad3618e Petr Tesarik 2023-08-01 @639  		    phys_limit < DMA_BIT_MASK(64) &&
79636caad3618e Petr Tesarik 2023-08-01  640  		    !(gfp & (__GFP_DMA32 | __GFP_DMA)))
79636caad3618e Petr Tesarik 2023-08-01  641  			gfp |= __GFP_DMA32;
79636caad3618e Petr Tesarik 2023-08-01  642  		else if (IS_ENABLED(CONFIG_ZONE_DMA) &&
79636caad3618e Petr Tesarik 2023-08-01  643  			 !(gfp & __GFP_DMA))
79636caad3618e Petr Tesarik 2023-08-01  644  			gfp = (gfp & ~__GFP_DMA32) | __GFP_DMA;
79636caad3618e Petr Tesarik 2023-08-01  645  		else
79636caad3618e Petr Tesarik 2023-08-01  646  			return NULL;
79636caad3618e Petr Tesarik 2023-08-01  647  	}
79636caad3618e Petr Tesarik 2023-08-01  648  
79636caad3618e Petr Tesarik 2023-08-01  649  	return page;
79636caad3618e Petr Tesarik 2023-08-01  650  }
79636caad3618e Petr Tesarik 2023-08-01  651
kernel test robot Aug. 30, 2024, 3:26 p.m. UTC | #2
Hi Casey,

kernel test robot noticed the following build errors:

[auto build test ERROR on pcmoore-audit/next]
[also build test ERROR on pcmoore-selinux/next zohar-integrity/next-integrity linus/master v6.11-rc5 next-20240830]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Casey-Schaufler/LSM-Add-the-lsmblob-data-structure/20240830-085050
base:   https://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit.git next
patch link:    https://lore.kernel.org/r/20240830003411.16818-11-casey%40schaufler-ca.com
patch subject: [PATCH v2 10/13] LSM: Create new security_cred_getlsmblob LSM hook
config: microblaze-allnoconfig (https://download.01.org/0day-ci/archive/20240830/202408302310.YKuNPXRT-lkp@intel.com/config)
compiler: microblaze-linux-gcc (GCC) 14.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240830/202408302310.YKuNPXRT-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202408302310.YKuNPXRT-lkp@intel.com/

All errors (new ones prefixed by >>):

   In file included from include/net/scm.h:9,
                    from include/linux/netlink.h:9,
                    from lib/kobject_uevent.c:24:
   include/linux/security.h: In function 'security_cred_getlsmblob':
>> include/linux/security.h:1199:10: error: 'secid' undeclared (first use in this function)
    1199 |         *secid = 0;
         |          ^~~~~
   include/linux/security.h:1199:10: note: each undeclared identifier is reported only once for each function it appears in
--
   In file included from include/net/scm.h:9,
                    from include/linux/netlink.h:9,
                    from include/uapi/linux/neighbour.h:6,
                    from include/linux/netdevice.h:45,
                    from include/net/sock.h:46,
                    from include/linux/tcp.h:19,
                    from include/linux/ipv6.h:101,
                    from include/net/addrconf.h:61,
                    from lib/vsprintf.c:41:
   include/linux/security.h: In function 'security_cred_getlsmblob':
>> include/linux/security.h:1199:10: error: 'secid' undeclared (first use in this function)
    1199 |         *secid = 0;
         |          ^~~~~
   include/linux/security.h:1199:10: note: each undeclared identifier is reported only once for each function it appears in
   lib/vsprintf.c: In function 'va_format':
   lib/vsprintf.c:1683:9: warning: function 'va_format' might be a candidate for 'gnu_printf' format attribute [-Wsuggest-attribute=format]
    1683 |         buf += vsnprintf(buf, end > buf ? end - buf : 0, va_fmt->fmt, va);
         |         ^~~


vim +/secid +1199 include/linux/security.h

  1195	
  1196	static inline void security_cred_getlsmblob(const struct cred *c,
  1197						    struct lsmblob *blob)
  1198	{
> 1199		*secid = 0;
  1200	}
  1201
diff mbox series

Patch

diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index 4fd508841a6e..4bdd36626633 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -215,6 +215,8 @@  LSM_HOOK(int, 0, cred_prepare, struct cred *new, const struct cred *old,
 LSM_HOOK(void, LSM_RET_VOID, cred_transfer, struct cred *new,
 	 const struct cred *old)
 LSM_HOOK(void, LSM_RET_VOID, cred_getsecid, const struct cred *c, u32 *secid)
+LSM_HOOK(void, LSM_RET_VOID, cred_getlsmblob, const struct cred *c,
+	 struct lsmblob *blob)
 LSM_HOOK(int, 0, kernel_act_as, struct cred *new, u32 secid)
 LSM_HOOK(int, 0, kernel_create_files_as, struct cred *new, struct inode *inode)
 LSM_HOOK(int, 0, kernel_module_request, char *kmod_name)
diff --git a/include/linux/security.h b/include/linux/security.h
index 4fe6f64cc3b4..111c1fc18f25 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -473,6 +473,7 @@  void security_cred_free(struct cred *cred);
 int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp);
 void security_transfer_creds(struct cred *new, const struct cred *old);
 void security_cred_getsecid(const struct cred *c, u32 *secid);
+void security_cred_getlsmblob(const struct cred *c, struct lsmblob *blob);
 int security_kernel_act_as(struct cred *new, u32 secid);
 int security_kernel_create_files_as(struct cred *new, struct inode *inode);
 int security_kernel_module_request(char *kmod_name);
@@ -1192,6 +1193,12 @@  static inline void security_cred_getsecid(const struct cred *c, u32 *secid)
 	*secid = 0;
 }
 
+static inline void security_cred_getlsmblob(const struct cred *c,
+					    struct lsmblob *blob)
+{
+	*secid = 0;
+}
+
 static inline int security_kernel_act_as(struct cred *cred, u32 secid)
 {
 	return 0;
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index d408a700fe6f..8171da96a4a4 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -541,8 +541,7 @@  static int ima_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot,
 static int ima_bprm_check(struct linux_binprm *bprm)
 {
 	int ret;
-	u32 secid;
-	struct lsmblob blob = { };
+	struct lsmblob blob;
 
 	security_current_getlsmblob_subj(&blob);
 	ret = process_measurement(bprm->file, current_cred(),
@@ -550,9 +549,7 @@  static int ima_bprm_check(struct linux_binprm *bprm)
 	if (ret)
 		return ret;
 
-	security_cred_getsecid(bprm->cred, &secid);
-	/* scaffolding */
-	blob.scaffold.secid = secid;
+	security_cred_getlsmblob(bprm->cred, &blob);
 	return process_measurement(bprm->file, bprm->cred, &blob, NULL, 0,
 				   MAY_EXEC, CREDS_CHECK);
 }
diff --git a/security/security.c b/security/security.c
index c2be9798c012..325030bc7112 100644
--- a/security/security.c
+++ b/security/security.c
@@ -3153,6 +3153,21 @@  void security_cred_getsecid(const struct cred *c, u32 *secid)
 }
 EXPORT_SYMBOL(security_cred_getsecid);
 
+/**
+ * security_cred_getlsmblob() - Get the LSM data from a set of credentials
+ * @c: credentials
+ * @blob: destination for the LSM data
+ *
+ * Retrieve the security data of the cred structure @c.  In case of
+ * failure, @blob will be cleared.
+ */
+void security_cred_getlsmblob(const struct cred *c, struct lsmblob *blob)
+{
+	lsmblob_init(blob);
+	call_void_hook(cred_getlsmblob, c, blob);
+}
+EXPORT_SYMBOL(security_cred_getlsmblob);
+
 /**
  * security_kernel_act_as() - Set the kernel credentials to act as secid
  * @new: credentials
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index f5d09beeef0f..076511c446bd 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -4029,6 +4029,13 @@  static void selinux_cred_getsecid(const struct cred *c, u32 *secid)
 	*secid = cred_sid(c);
 }
 
+static void selinux_cred_getlsmblob(const struct cred *c, struct lsmblob *blob)
+{
+	blob->selinux.secid = cred_sid(c);
+	/* scaffolding */
+	blob->scaffold.secid = blob->selinux.secid;
+}
+
 /*
  * set the security data for a kernel service
  * - all the creation contexts are set to unlabelled
@@ -7240,6 +7247,7 @@  static struct security_hook_list selinux_hooks[] __ro_after_init = {
 	LSM_HOOK_INIT(cred_prepare, selinux_cred_prepare),
 	LSM_HOOK_INIT(cred_transfer, selinux_cred_transfer),
 	LSM_HOOK_INIT(cred_getsecid, selinux_cred_getsecid),
+	LSM_HOOK_INIT(cred_getlsmblob, selinux_cred_getlsmblob),
 	LSM_HOOK_INIT(kernel_act_as, selinux_kernel_act_as),
 	LSM_HOOK_INIT(kernel_create_files_as, selinux_kernel_create_files_as),
 	LSM_HOOK_INIT(kernel_module_request, selinux_kernel_module_request),
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 88e7ac15ca62..a2445e4f906d 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -2150,6 +2150,23 @@  static void smack_cred_getsecid(const struct cred *cred, u32 *secid)
 	rcu_read_unlock();
 }
 
+/**
+ * smack_cred_getlsmblob - get the Smack label for a creds structure
+ * @cred: the object creds
+ * @blob: where to put the data
+ *
+ * Sets the Smack part of the blob
+ */
+static void smack_cred_getlsmblob(const struct cred *cred,
+				  struct lsmblob *blob)
+{
+	rcu_read_lock();
+	blob->smack.skp = smk_of_task(smack_cred(cred));
+	/* scaffolding */
+	blob->scaffold.secid = blob->smack.skp->smk_secid;
+	rcu_read_unlock();
+}
+
 /**
  * smack_kernel_act_as - Set the subjective context in a set of credentials
  * @new: points to the set of credentials to be modified.
@@ -5150,6 +5167,7 @@  static struct security_hook_list smack_hooks[] __ro_after_init = {
 	LSM_HOOK_INIT(cred_prepare, smack_cred_prepare),
 	LSM_HOOK_INIT(cred_transfer, smack_cred_transfer),
 	LSM_HOOK_INIT(cred_getsecid, smack_cred_getsecid),
+	LSM_HOOK_INIT(cred_getlsmblob, smack_cred_getlsmblob),
 	LSM_HOOK_INIT(kernel_act_as, smack_kernel_act_as),
 	LSM_HOOK_INIT(kernel_create_files_as, smack_kernel_create_files_as),
 	LSM_HOOK_INIT(task_setpgid, smack_task_setpgid),