Re: RFC rdma cgroup

2015-11-02 Thread Haggai Eran
On 29/10/2015 20:46, Parav Pandit wrote:
> On Thu, Oct 29, 2015 at 8:27 PM, Haggai Eran  wrote:
>> On 28/10/2015 10:29, Parav Pandit wrote:
>>> 3. Resources are not defined by the RDMA cgroup. Resources are defined
>>> by RDMA/IB subsystem and optionally by HCA vendor device drivers.
>>> Rationale: This allows rdma cgroup to remain constant while RDMA/IB
>>> subsystem can evolve without the need of rdma cgroup update. A new
>>> resource can be easily added by the RDMA/IB subsystem without touching
>>> rdma cgroup.
>> Resources exposed by the cgroup are basically a UAPI, so we have to be
>> careful to make it stable when it evolves. I understand the need for
>> vendor specific resources, following the discussion on the previous
>> proposal, but could you write on how you plan to allow these set of
>> resources to evolve?
> 
> Its fairly simple.
> Here is the code snippet on how resources are defined in my tree.
> It doesn't have the RSS work queues yet, but can be added right after
> this patch.
> 
> Resource are defined as index and as match_table_t.
> 
> enum rdma_resource_type {
> RDMA_VERB_RESOURCE_UCTX,
> RDMA_VERB_RESOURCE_AH,
> RDMA_VERB_RESOURCE_PD,
> RDMA_VERB_RESOURCE_CQ,
> RDMA_VERB_RESOURCE_MR,
> RDMA_VERB_RESOURCE_MW,
> RDMA_VERB_RESOURCE_SRQ,
> RDMA_VERB_RESOURCE_QP,
> RDMA_VERB_RESOURCE_FLOW,
> RDMA_VERB_RESOURCE_MAX,
> };
> So UAPI RDMA resources can evolve by just adding more entries here.
Are the names that appear in userspace also controlled by uverbs? What
about the vendor specific resources?

>>> 8. Typically each RDMA cgroup will have 0 to 4 RDMA devices. Therefore
>>> each cgroup will have 0 to 4 verbs resource pool and optionally 0 to 4
>>> hw resource pool per such device.
>>> (Nothing stops to have more devices and pools, but design is around
>>> this use case).
>> In what way does the design depend on this assumption?
> 
> Current code when performs resource charging/uncharging, it needs to
> identify the resource pool which one to charge to.
> This resource pool is maintained as list_head and so its linear search
> per device.
> If we are thinking of 100 of RDMA devices per container, than liner
> search will not be good way and different data structure needs to be
> deployed.
Okay, sounds fine to me.

>>> (c) When process migrate from one to other cgroup, resource is
>>> continue to be owned by the creator cgroup (rather css).
>>> After process migration, whenever new resource is created in new
>>> cgroup, it will be owned by new cgroup.
>> It sounds a little different from how other cgroups behave. I agree that
>> mostly processes will create the resources in their cgroup and won't
>> migrate, but why not move the charge during migration?
>>
> With fork() process doesn't really own the resource (unlike other file
> and socket descriptors).
> Parent process might have died also.
> There is possibly no clear way to transfer resource to right child.
> Child that cgroup picks might not even want to own RDMA resources.
> RDMA resources might be allocated by one process and freed by other
> process (though this might not be the way they use it).
> Its pretty similar to other cgroups with exception in migration area,
> such exception comes from different behavior of how RDMA resources are
> owned, created and used.
> Recent unified hierarchy patch from Tejun equally highlights to not
> frequently migrate processes among cgroups.
> 
> So in current implementation, (like other),
> if process created a RDMA resource, forked a child.
> child and parent both can allocate and free more resources.
> child moved to different cgroup. But resource is shared among them.
> child can free also the resource. All crazy combinations are possible
> in theory (without much use cases).
> So at best they are charged to the first cgroup css in which
> parent/child are created and reference is hold to CSS.
> cgroup, process can die, cut css remains until RDMA resources are freed.
> This is similar to process behavior where task struct is release but
> id is hold up for a while.

I guess there aren't a lot of options when the resources can belong to
multiple cgroups. So after migrating, new resources will belong to the
new cgroup or the old one?

>> I finally wanted to ask about other limitations an RDMA cgroup could
>> handle. It would be great to be able to limit a container to be allowed
>> to use only a subset of the MAC/VLAN pairs programmed to a device,
> 
> Truly. I agree. That was one of the prime reason I originally has it
> as part of the device cgroup.
> Where RDMA was just one category.
> But Tejun's opinion was to have rdma's own cgroup.
> Current internal data structure and interface between rdma cgroup and
> uverbs are tied to ib_device structure.
> which I think easy to overcome by abstracting out as new
> resource_device which can be used beyond RDMA as well.
> 
> However my bigger concern 

Re: [PATCH v2 1/3] keys, trusted: select the hash algorithm

2015-11-02 Thread Jarkko Sakkinen
On Mon, Nov 02, 2015 at 07:16:49AM -0500, Mimi Zohar wrote:
> On Fri, 2015-10-30 at 13:35 +0200, Jarkko Sakkinen wrote:
> 
> > @@ -787,6 +791,20 @@ static int getoptions(char *c, struct 
> > trusted_key_payload *pay,
> > return -EINVAL;
> > opt->pcrlock = lock;
> > break;
> > +   case Opt_hash:
> > +   for (i = 0; i < HASH_ALGO__LAST; i++) {
> > +   if (!strcmp(args[0].from, hash_algo_name[i])) {
> > +   opt->hash = i;
> > +   break;
> > +   }
> > +   }
> > +   res = tpm_is_tpm2(TPM_ANY_NUM);
> 
> While looking at this, I wanted to verify that chips are still added to
> the tail of the tpm_chip_list.  Unfortunately, commit "afb5abc tpm:
> two-phase chip management functions" reverted David Howell's commit
> "770ab65 TPM: Add new TPMs to the tail of the list to prevent
> inadvertent change of dev".

Ouch. I'll send a fix that reverts the behavior. Good catch and
apologies.  Platforms that I've used BIOS let choose either dTPM 1.2 or
fTPM and platforms that have dTPM 2.0 do not have fTPM option at all.
That's why it went unnoticed.

> > +   if (res < 0)
> > +   return res;
> > +   if (i == HASH_ALGO__LAST ||
> > +   (!res && i != HASH_ALGO_SHA1))
> > +   return -EINVAL;
> > +   break;
> 
> If the first TPM registered is a TPM 1.2, then changing the default TPM
> 2.0 hash algorithm will fail.

Yup.

> Mimi
> 
> > default:
> > return -EINVAL;
> > }

/Jarkko
--
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH RFC] tpm: seal with a policy

2015-11-02 Thread Jarkko Sakkinen
On Mon, Nov 02, 2015 at 07:48:42AM -0500, Mimi Zohar wrote:
> On Sat, 2015-10-31 at 17:53 +0200, Jarkko Sakkinen wrote:
> > Support for sealing with a policy.
> > 
> > Two new options for trusted keys:
> > 
> > * 'policydigest=': provide a policydigest for the seal operation.
> > * 'policyhandle=': provide handle for a policy session for unsealing.
> 
> Please expand the patch description explaining the motivation for these
> new options.  In what cases are they needed?  Are they system or session
> policies? 

They are session policies. By using TPM2 commands you can specify
conditions in which unseal should work like auth value, PCRs, localities
and so forth and combine these with logical connectors.

I'll think about this and write proper documentation.

> Mimi

/Jarkko
--
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 1/3] keys, trusted: select the hash algorithm

2015-11-02 Thread Jarkko Sakkinen
On Mon, Nov 02, 2015 at 07:16:49AM -0500, Mimi Zohar wrote:
> On Fri, 2015-10-30 at 13:35 +0200, Jarkko Sakkinen wrote:
> 
> > @@ -787,6 +791,20 @@ static int getoptions(char *c, struct 
> > trusted_key_payload *pay,
> > return -EINVAL;
> > opt->pcrlock = lock;
> > break;
> > +   case Opt_hash:
> > +   for (i = 0; i < HASH_ALGO__LAST; i++) {
> > +   if (!strcmp(args[0].from, hash_algo_name[i])) {
> > +   opt->hash = i;
> > +   break;
> > +   }
> > +   }
> > +   res = tpm_is_tpm2(TPM_ANY_NUM);
> 
> While looking at this, I wanted to verify that chips are still added to
> the tail of the tpm_chip_list.  Unfortunately, commit "afb5abc tpm:
> two-phase chip management functions" reverted David Howell's commit
> "770ab65 TPM: Add new TPMs to the tail of the list to prevent
> inadvertent change of dev".
> 
> > +   if (res < 0)
> > +   return res;
> > +   if (i == HASH_ALGO__LAST ||
> > +   (!res && i != HASH_ALGO_SHA1))
> > +   return -EINVAL;
> > +   break;
> 
> If the first TPM registered is a TPM 1.2, then changing the default TPM
> 2.0 hash algorithm will fail.

Now that we are going fix this issue in 4.3 and 4.4 do you find this
patch otherwise acceptable?

PS. In other options that we don't support in TPM2 I'm planning to
submit a fix that they will return -EINVAL (like pcrinfo).

> Mimi

/Jarkko
--
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v5 6/7] selinux: Revalidate invalid inode security labels

2015-11-02 Thread Stephen Smalley

On 11/02/2015 02:27 PM, Paul Moore wrote:

On Sunday, November 01, 2015 06:24:32 PM Andreas Gruenbacher wrote:

When fetching an inode's security label, check if it is still valid, and
try reloading it if it is not. Reloading will fail when we are in RCU
context which doesn't allow sleeping, or when we can't find a dentry for
the inode.  (Reloading happens via iop->getxattr which takes a dentry
parameter.)  When reloading fails, continue using the old, invalid
label.

Signed-off-by: Andreas Gruenbacher 
Acked-by: Stephen Smalley 


Generally I would say that you made enough changes between v4 and v5 that
Stephen's ACK should have been dropped, but considering that he suggested the
changes I think's it's okay to leave it as-is.

Stephen, I'm reviewing/merging these changes now for the selinux#next-queue,
speak up if you have want your ACK removed.


Revised patch looks fine to me; no need to remove the Acked-by.




diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index dcac6dc..0f94c2d 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -241,11 +241,63 @@ static int inode_alloc_security(struct inode *inode)
return 0;
  }

+static int inode_doinit_with_dentry(struct inode *inode, struct dentry
*opt_dentry); +
+/*
+ * Try reloading inode security labels that have been marked as invalid.
The + * @may_sleep parameter indicates when sleeping and thus reloading
labels is + * allowed; when set to false, returns ERR_PTR(-ECHILD) when the
label is + * invalid.  The @opt_dentry parameter should be set to a dentry
of the inode; + * when no dentry is available, set it to NULL instead.
+ */
+static int __inode_security_revalidate(struct inode *inode,
+  struct dentry *opt_dentry,
+  bool may_sleep)
+{
+   struct inode_security_struct *isec = inode->i_security;
+
+   might_sleep_if(may_sleep);
+
+   if (isec->initialized == LABEL_INVALID) {
+   if (!may_sleep)
+   return -ECHILD;
+
+   /*
+* Try reloading the inode security label.  This will fail if
+* @opt_dentry is NULL and no dentry for this inode can be
+* found; in that case, continue using the old label.
+*/
+   inode_doinit_with_dentry(inode, opt_dentry);
+   }
+   return 0;
+}
+
+static void inode_security_revalidate(struct inode *inode)
+{
+   __inode_security_revalidate(inode, NULL, true);
+}
+
+static struct inode_security_struct *inode_security_novalidate(struct inode
*inode) +{
+   return inode->i_security;
+}
+
+static struct inode_security_struct *inode_security_rcu(struct inode
*inode, bool rcu) +{
+   int error;
+
+   error = __inode_security_revalidate(inode, NULL, !rcu);
+   if (error)
+   return ERR_PTR(error);
+   return inode->i_security;
+}
+
  /*
   * Get the security label of an inode.
   */
  static struct inode_security_struct *inode_security(struct inode *inode)
  {
+   __inode_security_revalidate(inode, NULL, true);
return inode->i_security;
  }

@@ -256,6 +308,7 @@ static struct inode_security_struct
*backing_inode_security(struct dentry *dentr {
struct inode *inode = d_backing_inode(dentry);

+   __inode_security_revalidate(inode, dentry, true);
return inode->i_security;
  }

@@ -362,8 +415,6 @@ static const char *labeling_behaviors[7] = {
"uses native labeling",
  };

-static int inode_doinit_with_dentry(struct inode *inode, struct dentry
*opt_dentry); -
  static inline int inode_doinit(struct inode *inode)
  {
return inode_doinit_with_dentry(inode, NULL);
@@ -1655,6 +1706,7 @@ static inline int dentry_has_perm(const struct cred
*cred,

ad.type = LSM_AUDIT_DATA_DENTRY;
ad.u.dentry = dentry;
+   __inode_security_revalidate(inode, dentry, true);
return inode_has_perm(cred, inode, av, );
  }

@@ -1670,6 +1722,7 @@ static inline int path_has_perm(const struct cred
*cred,

ad.type = LSM_AUDIT_DATA_PATH;
ad.u.path = *path;
+   __inode_security_revalidate(inode, path->dentry, true);
return inode_has_perm(cred, inode, av, );
  }

@@ -2874,7 +2927,9 @@ static int selinux_inode_follow_link(struct dentry
*dentry, struct inode *inode, ad.type = LSM_AUDIT_DATA_DENTRY;
ad.u.dentry = dentry;
sid = cred_sid(cred);
-   isec = inode_security(inode);
+   isec = inode_security_rcu(inode, rcu);
+   if (IS_ERR(isec))
+   return PTR_ERR(isec);

return avc_has_perm_flags(sid, isec->sid, isec->sclass, FILE__READ, ,
  rcu ? MAY_NOT_BLOCK : 0);
@@ -2926,7 +2981,9 @@ static int selinux_inode_permission(struct inode
*inode, int mask) perms = file_mask_to_av(inode->i_mode, mask);

sid = cred_sid(cred);
-   isec = inode_security(inode);
+   

Re: [PATCH v5 6/7] selinux: Revalidate invalid inode security labels

2015-11-02 Thread Paul Moore
On Sunday, November 01, 2015 06:24:32 PM Andreas Gruenbacher wrote:
> When fetching an inode's security label, check if it is still valid, and
> try reloading it if it is not. Reloading will fail when we are in RCU
> context which doesn't allow sleeping, or when we can't find a dentry for
> the inode.  (Reloading happens via iop->getxattr which takes a dentry
> parameter.)  When reloading fails, continue using the old, invalid
> label.
> 
> Signed-off-by: Andreas Gruenbacher 
> Acked-by: Stephen Smalley 

Generally I would say that you made enough changes between v4 and v5 that 
Stephen's ACK should have been dropped, but considering that he suggested the 
changes I think's it's okay to leave it as-is.

Stephen, I'm reviewing/merging these changes now for the selinux#next-queue, 
speak up if you have want your ACK removed.

> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index dcac6dc..0f94c2d 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -241,11 +241,63 @@ static int inode_alloc_security(struct inode *inode)
>   return 0;
>  }
> 
> +static int inode_doinit_with_dentry(struct inode *inode, struct dentry
> *opt_dentry); +
> +/*
> + * Try reloading inode security labels that have been marked as invalid. 
> The + * @may_sleep parameter indicates when sleeping and thus reloading
> labels is + * allowed; when set to false, returns ERR_PTR(-ECHILD) when the
> label is + * invalid.  The @opt_dentry parameter should be set to a dentry
> of the inode; + * when no dentry is available, set it to NULL instead.
> + */
> +static int __inode_security_revalidate(struct inode *inode,
> +struct dentry *opt_dentry,
> +bool may_sleep)
> +{
> + struct inode_security_struct *isec = inode->i_security;
> +
> + might_sleep_if(may_sleep);
> +
> + if (isec->initialized == LABEL_INVALID) {
> + if (!may_sleep)
> + return -ECHILD;
> +
> + /*
> +  * Try reloading the inode security label.  This will fail if
> +  * @opt_dentry is NULL and no dentry for this inode can be
> +  * found; in that case, continue using the old label.
> +  */
> + inode_doinit_with_dentry(inode, opt_dentry);
> + }
> + return 0;
> +}
> +
> +static void inode_security_revalidate(struct inode *inode)
> +{
> + __inode_security_revalidate(inode, NULL, true);
> +}
> +
> +static struct inode_security_struct *inode_security_novalidate(struct inode
> *inode) +{
> + return inode->i_security;
> +}
> +
> +static struct inode_security_struct *inode_security_rcu(struct inode
> *inode, bool rcu) +{
> + int error;
> +
> + error = __inode_security_revalidate(inode, NULL, !rcu);
> + if (error)
> + return ERR_PTR(error);
> + return inode->i_security;
> +}
> +
>  /*
>   * Get the security label of an inode.
>   */
>  static struct inode_security_struct *inode_security(struct inode *inode)
>  {
> + __inode_security_revalidate(inode, NULL, true);
>   return inode->i_security;
>  }
> 
> @@ -256,6 +308,7 @@ static struct inode_security_struct
> *backing_inode_security(struct dentry *dentr {
>   struct inode *inode = d_backing_inode(dentry);
> 
> + __inode_security_revalidate(inode, dentry, true);
>   return inode->i_security;
>  }
> 
> @@ -362,8 +415,6 @@ static const char *labeling_behaviors[7] = {
>   "uses native labeling",
>  };
> 
> -static int inode_doinit_with_dentry(struct inode *inode, struct dentry
> *opt_dentry); -
>  static inline int inode_doinit(struct inode *inode)
>  {
>   return inode_doinit_with_dentry(inode, NULL);
> @@ -1655,6 +1706,7 @@ static inline int dentry_has_perm(const struct cred
> *cred,
> 
>   ad.type = LSM_AUDIT_DATA_DENTRY;
>   ad.u.dentry = dentry;
> + __inode_security_revalidate(inode, dentry, true);
>   return inode_has_perm(cred, inode, av, );
>  }
> 
> @@ -1670,6 +1722,7 @@ static inline int path_has_perm(const struct cred
> *cred,
> 
>   ad.type = LSM_AUDIT_DATA_PATH;
>   ad.u.path = *path;
> + __inode_security_revalidate(inode, path->dentry, true);
>   return inode_has_perm(cred, inode, av, );
>  }
> 
> @@ -2874,7 +2927,9 @@ static int selinux_inode_follow_link(struct dentry
> *dentry, struct inode *inode, ad.type = LSM_AUDIT_DATA_DENTRY;
>   ad.u.dentry = dentry;
>   sid = cred_sid(cred);
> - isec = inode_security(inode);
> + isec = inode_security_rcu(inode, rcu);
> + if (IS_ERR(isec))
> + return PTR_ERR(isec);
> 
>   return avc_has_perm_flags(sid, isec->sid, isec->sclass, FILE__READ, ,
> rcu ? MAY_NOT_BLOCK : 0);
> @@ -2926,7 +2981,9 @@ static int selinux_inode_permission(struct inode
> *inode, int mask) perms = file_mask_to_av(inode->i_mode, mask);
> 
>   sid = cred_sid(cred);
> - isec 

Re: [PATCH v2 1/3] keys, trusted: select the hash algorithm

2015-11-02 Thread Mimi Zohar
On Fri, 2015-10-30 at 13:35 +0200, Jarkko Sakkinen wrote:

> @@ -787,6 +791,20 @@ static int getoptions(char *c, struct 
> trusted_key_payload *pay,
>   return -EINVAL;
>   opt->pcrlock = lock;
>   break;
> + case Opt_hash:
> + for (i = 0; i < HASH_ALGO__LAST; i++) {
> + if (!strcmp(args[0].from, hash_algo_name[i])) {
> + opt->hash = i;
> + break;
> + }
> + }
> + res = tpm_is_tpm2(TPM_ANY_NUM);

While looking at this, I wanted to verify that chips are still added to
the tail of the tpm_chip_list.  Unfortunately, commit "afb5abc tpm:
two-phase chip management functions" reverted David Howell's commit
"770ab65 TPM: Add new TPMs to the tail of the list to prevent
inadvertent change of dev".

> + if (res < 0)
> + return res;
> + if (i == HASH_ALGO__LAST ||
> + (!res && i != HASH_ALGO_SHA1))
> + return -EINVAL;
> + break;

If the first TPM registered is a TPM 1.2, then changing the default TPM
2.0 hash algorithm will fail.

Mimi

>   default:
>   return -EINVAL;
>   }
 

--
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH RFC] tpm: seal with a policy

2015-11-02 Thread Mimi Zohar
On Sat, 2015-10-31 at 17:53 +0200, Jarkko Sakkinen wrote:
> Support for sealing with a policy.
> 
> Two new options for trusted keys:
> 
> * 'policydigest=': provide a policydigest for the seal operation.
> * 'policyhandle=': provide handle for a policy session for unsealing.

Please expand the patch description explaining the motivation for these
new options.  In what cases are they needed?  Are they system or session
policies? 

Mimi

> 
> Signed-off-by: Jarkko Sakkinen 
> ---
>  drivers/char/tpm/Kconfig|  1 +
>  drivers/char/tpm/tpm2-cmd.c | 20 +---
>  include/keys/trusted-type.h |  3 +++
>  security/keys/trusted.c | 26 --
>  4 files changed, 45 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig
> index 3b84a8b..bd86261 100644
> --- a/drivers/char/tpm/Kconfig
> +++ b/drivers/char/tpm/Kconfig
> @@ -6,6 +6,7 @@ menuconfig TCG_TPM
>   tristate "TPM Hardware Support"
>   depends on HAS_IOMEM
>   select SECURITYFS
> + select CRYPTO_HASH_INFO
>   ---help---
> If you have a TPM security chip in your system, which
> implements the Trusted Computing Group's specification,
> diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
> index b08a0b4..6f567c3 100644
> --- a/drivers/char/tpm/tpm2-cmd.c
> +++ b/drivers/char/tpm/tpm2-cmd.c
> @@ -463,6 +463,9 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
>   return -EINVAL;
>   }
> 
> + if (options->policydigest_len > hash_digest_size[options->hash])
> + return -EINVAL;
> +
>   rc = tpm_buf_init(, TPM2_ST_SESSIONS, TPM2_CC_CREATE);
>   if (rc)
>   return rc;
> @@ -488,8 +491,17 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
> 
>   tpm_buf_append_u16(, TPM2_ALG_KEYEDHASH);
>   tpm_buf_append_u16(, hash);
> - tpm_buf_append_u32(, TPM2_ATTR_USER_WITH_AUTH);
> - tpm_buf_append_u16(, 0); /* policy digest size */
> +
> + if (options->policydigest_len) {
> + tpm_buf_append_u32(, 0);
> + tpm_buf_append_u16(, options->policydigest_len);
> + tpm_buf_append(, options->policydigest,
> +options->policydigest_len);
> + } else {
> + tpm_buf_append_u32(, TPM2_ATTR_USER_WITH_AUTH);
> + tpm_buf_append_u16(, 0);
> + }
> +
>   tpm_buf_append_u16(, TPM2_ALG_NULL);
>   tpm_buf_append_u16(, 0);
> 
> @@ -617,7 +629,9 @@ static int tpm2_unseal(struct tpm_chip *chip,
>   return rc;
> 
>   tpm_buf_append_u32(, blob_handle);
> - tpm2_buf_append_auth(, TPM2_RS_PW,
> + tpm2_buf_append_auth(,
> +  options->policyhandle ?
> +  options->policyhandle : TPM2_RS_PW,
>NULL /* nonce */, 0,
>0 /* session_attributes */,
>options->blobauth /* hmac */,
> diff --git a/include/keys/trusted-type.h b/include/keys/trusted-type.h
> index a6a1008..e4beeca 100644
> --- a/include/keys/trusted-type.h
> +++ b/include/keys/trusted-type.h
> @@ -37,6 +37,9 @@ struct trusted_key_options {
>   unsigned char pcrinfo[MAX_PCRINFO_SIZE];
>   int pcrlock;
>   uint32_t hash;
> + uint32_t policydigest_len;
> + unsigned char *policydigest;
> + uint32_t policyhandle;
>  };
> 
>  extern struct key_type key_type_trusted;
> diff --git a/security/keys/trusted.c b/security/keys/trusted.c
> index 7a87bcd..ea043ff 100644
> --- a/security/keys/trusted.c
> +++ b/security/keys/trusted.c
> @@ -713,6 +713,8 @@ enum {
>   Opt_keyhandle, Opt_keyauth, Opt_blobauth,
>   Opt_pcrinfo, Opt_pcrlock, Opt_migratable,
>   Opt_hash,
> + Opt_policydigest,
> + Opt_policyhandle,
>  };
> 
>  static const match_table_t key_tokens = {
> @@ -726,6 +728,8 @@ static const match_table_t key_tokens = {
>   {Opt_pcrlock, "pcrlock=%s"},
>   {Opt_migratable, "migratable=%s"},
>   {Opt_hash, "hash=%s"},
> + {Opt_policydigest, "policydigest=%s"},
> + {Opt_policyhandle, "policyhandle=%s"},
>   {Opt_err, NULL}
>  };
> 
> @@ -804,6 +808,17 @@ static int getoptions(char *c, struct 
> trusted_key_payload *pay,
>   if (i == HASH_ALGO__LAST ||
>   (!res && i != HASH_ALGO_SHA1))
>   return -EINVAL;
> + case Opt_policydigest:
> + opt->policydigest_len = strlen(args[0].from);
> + opt->policydigest = kstrdup(args[0].from, GFP_KERNEL);
> + if (!opt->policydigest)
> + return -ENOMEM;
> + break;
> + case Opt_policyhandle:
> + res = kstrtoul(args[0].from, 16, );
> + if (res < 0)
> + return -EINVAL;
> + opt->policyhandle =