On 7/24/20 1:32 PM, Casey Schaufler wrote:
 Change the security_kernel_act_as interface to use a lsmblob
 structure in place of the single u32 secid in support of
 module stacking. Change its only caller, set_security_override,
 to do the same. Change that one's only caller,
 set_security_override_from_ctx, to call it with the new
 parameter type.
 
 The security module hook is unchanged, still taking a secid.
 The infrastructure passes the correct entry from the lsmblob.
 lsmblob_init() is used to fill the lsmblob structure, however
 this will be removed later in the series when security_secctx_to_secid()
 is undated to provide a lsmblob instead of a secid.
  
 fix  ^ "undated" to updated
 Reviewed-by: Kees Cook <keescook(a)chromium.org>
 Reviewed-by: John Johansen <john.johansen(a)canonical.com>
 Acked-by: Stephen Smalley <sds(a)tycho.nsa.gov>
 Signed-off-by: Casey Schaufler <casey(a)schaufler-ca.com>
 ---
  include/linux/cred.h     |  3 ++-
  include/linux/security.h |  5 +++--
  kernel/cred.c            | 10 ++++++----
  security/security.c      | 14 ++++++++++++--
  4 files changed, 23 insertions(+), 9 deletions(-)
 
 diff --git a/include/linux/cred.h b/include/linux/cred.h
 index 18639c069263..03ae0182cba6 100644
 --- a/include/linux/cred.h
 +++ b/include/linux/cred.h
 @@ -18,6 +18,7 @@
  
  struct cred;
  struct inode;
 +struct lsmblob;
  
  /*
   * COW Supplementary groups list
 @@ -165,7 +166,7 @@ extern const struct cred *override_creds(const struct cred *);
  extern void revert_creds(const struct cred *);
  extern struct cred *prepare_kernel_cred(struct task_struct *);
  extern int change_create_files_as(struct cred *, struct inode *);
 -extern int set_security_override(struct cred *, u32);
 +extern int set_security_override(struct cred *, struct lsmblob *);
  extern int set_security_override_from_ctx(struct cred *, const char *);
  extern int set_create_files_as(struct cred *, struct inode *);
  extern int cred_fscmp(const struct cred *, const struct cred *);
 diff --git a/include/linux/security.h b/include/linux/security.h
 index 294410533b51..6d403a522918 100644
 --- a/include/linux/security.h
 +++ b/include/linux/security.h
 @@ -441,7 +441,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);
 -int security_kernel_act_as(struct cred *new, u32 secid);
 +int security_kernel_act_as(struct cred *new, struct lsmblob *blob);
  int security_kernel_create_files_as(struct cred *new, struct inode *inode);
  int security_kernel_module_request(char *kmod_name);
  int security_kernel_load_data(enum kernel_load_data_id id);
 @@ -1055,7 +1055,8 @@ static inline void security_transfer_creds(struct cred *new,
  {
  }
  
 -static inline int security_kernel_act_as(struct cred *cred, u32 secid)
 +static inline int security_kernel_act_as(struct cred *cred,
 +					 struct lsmblob *blob)
  {
  	return 0;
  }
 diff --git a/kernel/cred.c b/kernel/cred.c
 index 421b1149c651..22e0e7cbefde 100644
 --- a/kernel/cred.c
 +++ b/kernel/cred.c
 @@ -733,14 +733,14 @@ EXPORT_SYMBOL(prepare_kernel_cred);
  /**
   * set_security_override - Set the security ID in a set of credentials
   * @new: The credentials to alter
 - * @secid: The LSM security ID to set
 + * @blob: The LSM security information to set
   *
   * Set the LSM security ID in a set of credentials so that the subjective
   * security is overridden when an alternative set of credentials is used.
   */
 -int set_security_override(struct cred *new, u32 secid)
 +int set_security_override(struct cred *new, struct lsmblob *blob)
  {
 -	return security_kernel_act_as(new, secid);
 +	return security_kernel_act_as(new, blob);
  }
  EXPORT_SYMBOL(set_security_override);
  
 @@ -756,6 +756,7 @@ EXPORT_SYMBOL(set_security_override);
   */
  int set_security_override_from_ctx(struct cred *new, const char *secctx)
  {
 +	struct lsmblob blob;
  	u32 secid;
  	int ret;
  
 @@ -763,7 +764,8 @@ int set_security_override_from_ctx(struct cred *new, const char
*secctx)
  	if (ret < 0)
  		return ret;
  
 -	return set_security_override(new, secid);
 +	lsmblob_init(&blob, secid);
 +	return set_security_override(new, &blob);
  }
  EXPORT_SYMBOL(set_security_override_from_ctx);
  
 diff --git a/security/security.c b/security/security.c
 index f9a249a93215..d6d882b1f7d5 100644
 --- a/security/security.c
 +++ b/security/security.c
 @@ -1692,9 +1692,19 @@ void security_cred_getsecid(const struct cred *c, u32 *secid)
  }
  EXPORT_SYMBOL(security_cred_getsecid);
  
 -int security_kernel_act_as(struct cred *new, u32 secid)
 +int security_kernel_act_as(struct cred *new, struct lsmblob *blob)
  {
 -	return call_int_hook(kernel_act_as, 0, new, secid);
 +	struct security_hook_list *hp;
 +	int rc;
 +
 +	hlist_for_each_entry(hp, &security_hook_heads.kernel_act_as, list) {
 +		if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot))
 +			continue;
 +		rc = hp->hook.kernel_act_as(new, blob->secid[hp->lsmid->slot]);
 +		if (rc != 0)
 +			return rc;
 +	}
 +	return 0;
  }
  
  int security_kernel_create_files_as(struct cred *new, struct inode *inode)