diff mbox

[04/17] Security: Add hook to calculate context based on a negative dentry.

Message ID 1366834683-29075-5-git-send-email-SteveD@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Steve Dickson April 24, 2013, 8:17 p.m. UTC
From: David Quigley <dpquigl@davequigley.com>

There is a time where we need to calculate a context without the
inode having been created yet. To do this we take the negative dentry and
calculate a context based on the process and the parent directory contexts.

Signed-off-by: Matthew N. Dodd <Matthew.Dodd@sparta.com>
Signed-off-by: Miguel Rodel Felipe <Rodel_FM@dsi.a-star.edu.sg>
Signed-off-by: Phua Eu Gene <PHUA_Eu_Gene@dsi.a-star.edu.sg>
Signed-off-by: Khin Mi Mi Aung <Mi_Mi_AUNG@dsi.a-star.edu.sg>
---
 include/linux/security.h | 27 +++++++++++++++++++++++++++
 security/capability.c    |  8 ++++++++
 security/security.c      | 10 ++++++++++
 security/selinux/hooks.c | 35 +++++++++++++++++++++++++++++++++++
 4 files changed, 80 insertions(+)

Comments

J. Bruce Fields April 24, 2013, 10:02 p.m. UTC | #1
On Wed, Apr 24, 2013 at 04:17:50PM -0400, Steve Dickson wrote:
> From: David Quigley <dpquigl@davequigley.com>
> 
> There is a time where we need to calculate a context without the
> inode having been created yet. To do this we take the negative dentry and
> calculate a context based on the process and the parent directory contexts.

How can we get review from security/selinux folks?  I can't apply these
without....

--b.

> 
> Signed-off-by: Matthew N. Dodd <Matthew.Dodd@sparta.com>
> Signed-off-by: Miguel Rodel Felipe <Rodel_FM@dsi.a-star.edu.sg>
> Signed-off-by: Phua Eu Gene <PHUA_Eu_Gene@dsi.a-star.edu.sg>
> Signed-off-by: Khin Mi Mi Aung <Mi_Mi_AUNG@dsi.a-star.edu.sg>
> ---
>  include/linux/security.h | 27 +++++++++++++++++++++++++++
>  security/capability.c    |  8 ++++++++
>  security/security.c      | 10 ++++++++++
>  security/selinux/hooks.c | 35 +++++++++++++++++++++++++++++++++++
>  4 files changed, 80 insertions(+)
> 
> diff --git a/include/linux/security.h b/include/linux/security.h
> index 032c366..f3d7956 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -26,6 +26,7 @@
>  #include <linux/capability.h>
>  #include <linux/slab.h>
>  #include <linux/err.h>
> +#include <linux/string.h>
>  
>  struct linux_binprm;
>  struct cred;
> @@ -306,6 +307,15 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
>   *	Parse a string of security data filling in the opts structure
>   *	@options string containing all mount options known by the LSM
>   *	@opts binary data structure usable by the LSM
> + * @dentry_init_security:
> + *	Compute a context for a dentry as the inode is not yet available
> + *	since NFSv4 has no label backed by an EA anyway.
> + *	@dentry dentry to use in calculating the context.
> + *	@mode mode used to determine resource type.
> + *	@name name of the last path component used to create file
> + *	@ctx pointer to place the pointer to the resulting context in.
> + *	@ctxlen point to place the length of the resulting context.
> + *
>   *
>   * Security hooks for inode operations.
>   *
> @@ -1443,6 +1453,10 @@ struct security_operations {
>  	void (*sb_clone_mnt_opts) (const struct super_block *oldsb,
>  				   struct super_block *newsb);
>  	int (*sb_parse_opts_str) (char *options, struct security_mnt_opts *opts);
> +	int (*dentry_init_security) (struct dentry *dentry, int mode,
> +					struct qstr *name, void **ctx,
> +					u32 *ctxlen);
> +
>  
>  #ifdef CONFIG_SECURITY_PATH
>  	int (*path_unlink) (struct path *dir, struct dentry *dentry);
> @@ -1729,6 +1743,9 @@ int security_sb_set_mnt_opts(struct super_block *sb, struct security_mnt_opts *o
>  void security_sb_clone_mnt_opts(const struct super_block *oldsb,
>  				struct super_block *newsb);
>  int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts);
> +int security_dentry_init_security(struct dentry *dentry, int mode,
> +					struct qstr *name, void **ctx,
> +					u32 *ctxlen);
>  
>  int security_inode_alloc(struct inode *inode);
>  void security_inode_free(struct inode *inode);
> @@ -2033,6 +2050,16 @@ static inline int security_inode_alloc(struct inode *inode)
>  static inline void security_inode_free(struct inode *inode)
>  { }
>  
> +static inline int security_dentry_init_security(struct dentry *dentry,
> +						 int mode,
> +						 struct qstr *name,
> +						 void **ctx,
> +						 u32 *ctxlen)
> +{
> +	return -EOPNOTSUPP;
> +}
> +
> +
>  static inline int security_inode_init_security(struct inode *inode,
>  						struct inode *dir,
>  						const struct qstr *qstr,
> diff --git a/security/capability.c b/security/capability.c
> index 6783c3e..782045e 100644
> --- a/security/capability.c
> +++ b/security/capability.c
> @@ -108,6 +108,13 @@ static int cap_sb_parse_opts_str(char *options, struct security_mnt_opts *opts)
>  	return 0;
>  }
>  
> +static int cap_dentry_init_security(struct dentry *dentry, int mode,
> +					struct qstr *name, void **ctx,
> +					u32 *ctxlen)
> +{
> +	return 0;
> +}
> +
>  static int cap_inode_alloc_security(struct inode *inode)
>  {
>  	return 0;
> @@ -930,6 +937,7 @@ void __init security_fixup_ops(struct security_operations *ops)
>  	set_to_cap_if_null(ops, sb_set_mnt_opts);
>  	set_to_cap_if_null(ops, sb_clone_mnt_opts);
>  	set_to_cap_if_null(ops, sb_parse_opts_str);
> +	set_to_cap_if_null(ops, dentry_init_security);
>  	set_to_cap_if_null(ops, inode_alloc_security);
>  	set_to_cap_if_null(ops, inode_free_security);
>  	set_to_cap_if_null(ops, inode_init_security);
> diff --git a/security/security.c b/security/security.c
> index 03f248b..7c18e3c 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -12,6 +12,7 @@
>   */
>  
>  #include <linux/capability.h>
> +#include <linux/dcache.h>
>  #include <linux/module.h>
>  #include <linux/init.h>
>  #include <linux/kernel.h>
> @@ -324,6 +325,15 @@ void security_inode_free(struct inode *inode)
>  	security_ops->inode_free_security(inode);
>  }
>  
> +int security_dentry_init_security(struct dentry *dentry, int mode,
> +					struct qstr *name, void **ctx,
> +					u32 *ctxlen)
> +{
> +	return security_ops->dentry_init_security(dentry, mode, name,
> +							ctx, ctxlen);
> +}
> +EXPORT_SYMBOL(security_dentry_init_security);
> +
>  int security_inode_init_security(struct inode *inode, struct inode *dir,
>  				 const struct qstr *qstr,
>  				 const initxattrs initxattrs, void *fs_data)
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 7171a95..622b205 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -2484,6 +2484,40 @@ static void selinux_inode_free_security(struct inode *inode)
>  	inode_free_security(inode);
>  }
>  
> +static int selinux_dentry_init_security(struct dentry *dentry, int mode,
> +					struct qstr *name, void **ctx,
> +					u32 *ctxlen)
> +{
> +	const struct cred *cred = current_cred();
> +	struct task_security_struct *tsec;
> +	struct inode_security_struct *dsec;
> +	struct superblock_security_struct *sbsec;
> +	struct inode *dir = dentry->d_parent->d_inode;
> +	u32 newsid;
> +	int rc;
> +
> +	tsec = cred->security;
> +	dsec = dir->i_security;
> +	sbsec = dir->i_sb->s_security;
> +
> +	if (tsec->create_sid && sbsec->behavior != SECURITY_FS_USE_MNTPOINT) {
> +		newsid = tsec->create_sid;
> +	} else {
> +		rc = security_transition_sid(tsec->sid, dsec->sid,
> +					     inode_mode_to_security_class(mode),
> +					     name,
> +					     &newsid);
> +		if (rc) {
> +			printk(KERN_WARNING
> +				"%s: security_transition_sid failed, rc=%d\n",
> +			       __func__, -rc);
> +			return rc;
> +		}
> +	}
> +
> +	return security_sid_to_context(newsid, (char **)ctx, ctxlen);
> +}
> +
>  static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
>  				       const struct qstr *qstr, char **name,
>  				       void **value, size_t *len)
> @@ -5531,6 +5565,7 @@ static struct security_operations selinux_ops = {
>  	.sb_clone_mnt_opts =		selinux_sb_clone_mnt_opts,
>  	.sb_parse_opts_str = 		selinux_parse_opts_str,
>  
> +	.dentry_init_security =		selinux_dentry_init_security,
>  
>  	.inode_alloc_security =		selinux_inode_alloc_security,
>  	.inode_free_security =		selinux_inode_free_security,
> -- 
> 1.8.1.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Dave Quigley April 24, 2013, 10:09 p.m. UTC | #2
I'll contact Eric Paris about reviewing the patches. I'm sure he would 
be happy to look them over. Hopefully we can get it done soon.

Dave
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Steve Dickson April 24, 2013, 10:12 p.m. UTC | #3
On 24/04/13 18:02, J. Bruce Fields wrote:
> n Wed, Apr 24, 2013 at 04:17:50PM -0400, Steve Dickson wrote:
>> > From: David Quigley <dpquigl@davequigley.com>
>> > 
>> > There is a time where we need to calculate a context without the
>> > inode having been created yet. To do this we take the negative dentry and
>> > calculate a context based on the process and the parent directory contexts.
> How can we get review from security/selinux folks?  I can't apply these
> without....
Its my understand they have been reviewed a number times... And they have not
change since I've working on these patches... 

steved.
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Dave Quigley April 24, 2013, 10:14 p.m. UTC | #4
On 04/24/2013 18:12, Steve Dickson wrote:
> On 24/04/13 18:02, J. Bruce Fields wrote:
>> n Wed, Apr 24, 2013 at 04:17:50PM -0400, Steve Dickson wrote:
>>> > From: David Quigley <dpquigl@davequigley.com>
>>> >
>>> > There is a time where we need to calculate a context without the
>>> > inode having been created yet. To do this we take the negative 
>>> dentry and
>>> > calculate a context based on the process and the parent directory 
>>> contexts.
>> How can we get review from security/selinux folks?  I can't apply 
>> these
>> without....
> Its my understand they have been reviewed a number times... And they 
> have not
> change since I've working on these patches...
>
> steved.
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" 
> in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

That is correct. They have been acked in the past and haven't changed 
at all since then. I have contacted Eric Paris about reviewing them 
anyway so you can have a more recent ack on the patches.

Dave
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
J. Bruce Fields April 24, 2013, 11:03 p.m. UTC | #5
On Wed, Apr 24, 2013 at 06:14:16PM -0400, David Quigley wrote:
> On 04/24/2013 18:12, Steve Dickson wrote:
> >On 24/04/13 18:02, J. Bruce Fields wrote:
> >>n Wed, Apr 24, 2013 at 04:17:50PM -0400, Steve Dickson wrote:
> >>>> From: David Quigley <dpquigl@davequigley.com>
> >>>>
> >>>> There is a time where we need to calculate a context without the
> >>>> inode having been created yet. To do this we take the
> >>>negative dentry and
> >>>> calculate a context based on the process and the parent
> >>>directory contexts.
> >>How can we get review from security/selinux folks?  I can't
> >>apply these
> >>without....
> >Its my understand they have been reviewed a number times... And
> >they have not
> >change since I've working on these patches...
> >
> >steved.
> >--
> >To unsubscribe from this list: send the line "unsubscribe
> >linux-nfs" in
> >the body of a message to majordomo@vger.kernel.org
> >More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> That is correct. They have been acked in the past and haven't
> changed at all since then.

Oh, OK, sorry--I lost track.  (Do you have a pointer?)

> I have contacted Eric Paris about
> reviewing them anyway so you can have a more recent ack on the
> patches.

But that would be helpful too, thanks.

--b.
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Dave Quigley April 24, 2013, 11:05 p.m. UTC | #6
On 04/24/2013 19:03, J. Bruce Fields wrote:
> On Wed, Apr 24, 2013 at 06:14:16PM -0400, David Quigley wrote:
>> On 04/24/2013 18:12, Steve Dickson wrote:
>> >On 24/04/13 18:02, J. Bruce Fields wrote:
>> >>n Wed, Apr 24, 2013 at 04:17:50PM -0400, Steve Dickson wrote:
>> >>>> From: David Quigley <dpquigl@davequigley.com>
>> >>>>
>> >>>> There is a time where we need to calculate a context without 
>> the
>> >>>> inode having been created yet. To do this we take the
>> >>>negative dentry and
>> >>>> calculate a context based on the process and the parent
>> >>>directory contexts.
>> >>How can we get review from security/selinux folks?  I can't
>> >>apply these
>> >>without....
>> >Its my understand they have been reviewed a number times... And
>> >they have not
>> >change since I've working on these patches...
>> >
>> >steved.
>> >--
>> >To unsubscribe from this list: send the line "unsubscribe
>> >linux-nfs" in
>> >the body of a message to majordomo@vger.kernel.org
>> >More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
>> That is correct. They have been acked in the past and haven't
>> changed at all since then.
>
> Oh, OK, sorry--I lost track.  (Do you have a pointer?)

I may be able to crawl through MARC.info for my old email address to 
see if I can find it but that is probably more effort than its worth. 
All of those ACKs and what not are saved in my old NSA email (assuming 
its still being kept around).

>
>> I have contacted Eric Paris about
>> reviewing them anyway so you can have a more recent ack on the
>> patches.
>
> But that would be helpful too, thanks.
>
> --b.


I think its a good idea to have Eric look through them anyway just to 
be sure.

Dave
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Casey Schaufler April 25, 2013, 1:27 a.m. UTC | #7
On 4/24/2013 4:05 PM, David Quigley wrote:
> On 04/24/2013 19:03, J. Bruce Fields wrote:
>> On Wed, Apr 24, 2013 at 06:14:16PM -0400, David Quigley wrote:
>>> On 04/24/2013 18:12, Steve Dickson wrote:
>>> >On 24/04/13 18:02, J. Bruce Fields wrote:
>>> >>n Wed, Apr 24, 2013 at 04:17:50PM -0400, Steve Dickson wrote:
>>> >>>> From: David Quigley <dpquigl@davequigley.com>
>>> >>>>
>>> >>>> There is a time where we need to calculate a context without the
>>> >>>> inode having been created yet. To do this we take the
>>> >>>negative dentry and
>>> >>>> calculate a context based on the process and the parent
>>> >>>directory contexts.
>>> >>How can we get review from security/selinux folks?  I can't
>>> >>apply these
>>> >>without....
>>> >Its my understand they have been reviewed a number times... And
>>> >they have not
>>> >change since I've working on these patches...
>>> >
>>> >steved.
>>> >--
>>> >To unsubscribe from this list: send the line "unsubscribe
>>> >linux-nfs" in
>>> >the body of a message to majordomo@vger.kernel.org
>>> >More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>
>>> That is correct. They have been acked in the past and haven't
>>> changed at all since then.

For the record, I haven't ACKed because I have been unable to
get the NFS labeling to work with Smack. I also note that I
am not NAKing, either, as I have not had the time to determine
what's wrong. I do know that the ideas floated at the time turned
out to not be the problem. Hopefully I'll have time to look
into this sometime.


>>
>> Oh, OK, sorry--I lost track.  (Do you have a pointer?)
>
> I may be able to crawl through MARC.info for my old email address to
> see if I can find it but that is probably more effort than its worth.
> All of those ACKs and what not are saved in my old NSA email (assuming
> its still being kept around).
>
>>
>>> I have contacted Eric Paris about
>>> reviewing them anyway so you can have a more recent ack on the
>>> patches.
>>
>> But that would be helpful too, thanks.
>>
>> --b.
>
>
> I think its a good idea to have Eric look through them anyway just to
> be sure.
>
> Dave
>
> -- 
> This message was distributed to subscribers of the selinux mailing list.
> If you no longer wish to subscribe, send mail to
> majordomo@tycho.nsa.gov with
> the words "unsubscribe selinux" without quotes as the message.
>

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
J. Bruce Fields April 25, 2013, 1:43 a.m. UTC | #8
On Wed, Apr 24, 2013 at 06:27:26PM -0700, Casey Schaufler wrote:
> On 4/24/2013 4:05 PM, David Quigley wrote:
> > On 04/24/2013 19:03, J. Bruce Fields wrote:
> >> On Wed, Apr 24, 2013 at 06:14:16PM -0400, David Quigley wrote:
> >>> On 04/24/2013 18:12, Steve Dickson wrote:
> >>> >On 24/04/13 18:02, J. Bruce Fields wrote:
> >>> >>n Wed, Apr 24, 2013 at 04:17:50PM -0400, Steve Dickson wrote:
> >>> >>>> From: David Quigley <dpquigl@davequigley.com>
> >>> >>>>
> >>> >>>> There is a time where we need to calculate a context without the
> >>> >>>> inode having been created yet. To do this we take the
> >>> >>>negative dentry and
> >>> >>>> calculate a context based on the process and the parent
> >>> >>>directory contexts.
> >>> >>How can we get review from security/selinux folks?  I can't
> >>> >>apply these
> >>> >>without....
> >>> >Its my understand they have been reviewed a number times... And
> >>> >they have not
> >>> >change since I've working on these patches...
> >>> >
> >>> >steved.
> >>> >--
> >>> >To unsubscribe from this list: send the line "unsubscribe
> >>> >linux-nfs" in
> >>> >the body of a message to majordomo@vger.kernel.org
> >>> >More majordomo info at  http://vger.kernel.org/majordomo-info.html
> >>>
> >>> That is correct. They have been acked in the past and haven't
> >>> changed at all since then.
> 
> For the record, I haven't ACKed because I have been unable to
> get the NFS labeling to work with Smack. I also note that I
> am not NAKing, either, as I have not had the time to determine
> what's wrong. I do know that the ideas floated at the time turned
> out to not be the problem. Hopefully I'll have time to look
> into this sometime.

OK, we'll add an:

neither-acked-nor-nacked-by: Casey Schaufler <casey@schaufler-ca.com>

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

Patch

diff --git a/include/linux/security.h b/include/linux/security.h
index 032c366..f3d7956 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -26,6 +26,7 @@ 
 #include <linux/capability.h>
 #include <linux/slab.h>
 #include <linux/err.h>
+#include <linux/string.h>
 
 struct linux_binprm;
 struct cred;
@@ -306,6 +307,15 @@  static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
  *	Parse a string of security data filling in the opts structure
  *	@options string containing all mount options known by the LSM
  *	@opts binary data structure usable by the LSM
+ * @dentry_init_security:
+ *	Compute a context for a dentry as the inode is not yet available
+ *	since NFSv4 has no label backed by an EA anyway.
+ *	@dentry dentry to use in calculating the context.
+ *	@mode mode used to determine resource type.
+ *	@name name of the last path component used to create file
+ *	@ctx pointer to place the pointer to the resulting context in.
+ *	@ctxlen point to place the length of the resulting context.
+ *
  *
  * Security hooks for inode operations.
  *
@@ -1443,6 +1453,10 @@  struct security_operations {
 	void (*sb_clone_mnt_opts) (const struct super_block *oldsb,
 				   struct super_block *newsb);
 	int (*sb_parse_opts_str) (char *options, struct security_mnt_opts *opts);
+	int (*dentry_init_security) (struct dentry *dentry, int mode,
+					struct qstr *name, void **ctx,
+					u32 *ctxlen);
+
 
 #ifdef CONFIG_SECURITY_PATH
 	int (*path_unlink) (struct path *dir, struct dentry *dentry);
@@ -1729,6 +1743,9 @@  int security_sb_set_mnt_opts(struct super_block *sb, struct security_mnt_opts *o
 void security_sb_clone_mnt_opts(const struct super_block *oldsb,
 				struct super_block *newsb);
 int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts);
+int security_dentry_init_security(struct dentry *dentry, int mode,
+					struct qstr *name, void **ctx,
+					u32 *ctxlen);
 
 int security_inode_alloc(struct inode *inode);
 void security_inode_free(struct inode *inode);
@@ -2033,6 +2050,16 @@  static inline int security_inode_alloc(struct inode *inode)
 static inline void security_inode_free(struct inode *inode)
 { }
 
+static inline int security_dentry_init_security(struct dentry *dentry,
+						 int mode,
+						 struct qstr *name,
+						 void **ctx,
+						 u32 *ctxlen)
+{
+	return -EOPNOTSUPP;
+}
+
+
 static inline int security_inode_init_security(struct inode *inode,
 						struct inode *dir,
 						const struct qstr *qstr,
diff --git a/security/capability.c b/security/capability.c
index 6783c3e..782045e 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -108,6 +108,13 @@  static int cap_sb_parse_opts_str(char *options, struct security_mnt_opts *opts)
 	return 0;
 }
 
+static int cap_dentry_init_security(struct dentry *dentry, int mode,
+					struct qstr *name, void **ctx,
+					u32 *ctxlen)
+{
+	return 0;
+}
+
 static int cap_inode_alloc_security(struct inode *inode)
 {
 	return 0;
@@ -930,6 +937,7 @@  void __init security_fixup_ops(struct security_operations *ops)
 	set_to_cap_if_null(ops, sb_set_mnt_opts);
 	set_to_cap_if_null(ops, sb_clone_mnt_opts);
 	set_to_cap_if_null(ops, sb_parse_opts_str);
+	set_to_cap_if_null(ops, dentry_init_security);
 	set_to_cap_if_null(ops, inode_alloc_security);
 	set_to_cap_if_null(ops, inode_free_security);
 	set_to_cap_if_null(ops, inode_init_security);
diff --git a/security/security.c b/security/security.c
index 03f248b..7c18e3c 100644
--- a/security/security.c
+++ b/security/security.c
@@ -12,6 +12,7 @@ 
  */
 
 #include <linux/capability.h>
+#include <linux/dcache.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -324,6 +325,15 @@  void security_inode_free(struct inode *inode)
 	security_ops->inode_free_security(inode);
 }
 
+int security_dentry_init_security(struct dentry *dentry, int mode,
+					struct qstr *name, void **ctx,
+					u32 *ctxlen)
+{
+	return security_ops->dentry_init_security(dentry, mode, name,
+							ctx, ctxlen);
+}
+EXPORT_SYMBOL(security_dentry_init_security);
+
 int security_inode_init_security(struct inode *inode, struct inode *dir,
 				 const struct qstr *qstr,
 				 const initxattrs initxattrs, void *fs_data)
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 7171a95..622b205 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2484,6 +2484,40 @@  static void selinux_inode_free_security(struct inode *inode)
 	inode_free_security(inode);
 }
 
+static int selinux_dentry_init_security(struct dentry *dentry, int mode,
+					struct qstr *name, void **ctx,
+					u32 *ctxlen)
+{
+	const struct cred *cred = current_cred();
+	struct task_security_struct *tsec;
+	struct inode_security_struct *dsec;
+	struct superblock_security_struct *sbsec;
+	struct inode *dir = dentry->d_parent->d_inode;
+	u32 newsid;
+	int rc;
+
+	tsec = cred->security;
+	dsec = dir->i_security;
+	sbsec = dir->i_sb->s_security;
+
+	if (tsec->create_sid && sbsec->behavior != SECURITY_FS_USE_MNTPOINT) {
+		newsid = tsec->create_sid;
+	} else {
+		rc = security_transition_sid(tsec->sid, dsec->sid,
+					     inode_mode_to_security_class(mode),
+					     name,
+					     &newsid);
+		if (rc) {
+			printk(KERN_WARNING
+				"%s: security_transition_sid failed, rc=%d\n",
+			       __func__, -rc);
+			return rc;
+		}
+	}
+
+	return security_sid_to_context(newsid, (char **)ctx, ctxlen);
+}
+
 static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
 				       const struct qstr *qstr, char **name,
 				       void **value, size_t *len)
@@ -5531,6 +5565,7 @@  static struct security_operations selinux_ops = {
 	.sb_clone_mnt_opts =		selinux_sb_clone_mnt_opts,
 	.sb_parse_opts_str = 		selinux_parse_opts_str,
 
+	.dentry_init_security =		selinux_dentry_init_security,
 
 	.inode_alloc_security =		selinux_inode_alloc_security,
 	.inode_free_security =		selinux_inode_free_security,