All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Mickaël Salaün" <mic@digikod.net>
To: linux-kernel@vger.kernel.org
Cc: "Mickaël Salaün" <mic@digikod.net>,
	"Alexei Starovoitov" <ast@kernel.org>,
	"Andy Lutomirski" <luto@amacapital.net>,
	"Arnaldo Carvalho de Melo" <acme@kernel.org>,
	"Casey Schaufler" <casey@schaufler-ca.com>,
	"Daniel Borkmann" <daniel@iogearbox.net>,
	"David Drysdale" <drysdale@google.com>,
	"David S . Miller" <davem@davemloft.net>,
	"Eric W . Biederman" <ebiederm@xmission.com>,
	"James Morris" <james.l.morris@oracle.com>,
	"Jann Horn" <jann@thejh.net>, "Jonathan Corbet" <corbet@lwn.net>,
	"Michael Kerrisk" <mtk.manpages@gmail.com>,
	"Kees Cook" <keescook@chromium.org>,
	"Paul Moore" <paul@paul-moore.com>,
	"Sargun Dhillon" <sargun@sargun.me>,
	"Serge E . Hallyn" <serge@hallyn.com>,
	"Shuah Khan" <shuah@kernel.org>, "Tejun Heo" <tj@kernel.org>,
	"Thomas Graf" <tgraf@suug.ch>, "Tycho Andersen" <tycho@tycho.ws>,
	"Will Drewry" <wad@chromium.org>,
	kernel-hardening@lists.openwall.com, linux-api@vger.kernel.org,
	linux-security-module@vger.kernel.org, netdev@vger.kernel.org,
	"Alexander Viro" <viro@zeniv.linux.org.uk>,
	"James Morris" <jmorris@namei.org>,
	"John Johansen" <john.johansen@canonical.com>,
	"Stephen Smalley" <sds@tycho.nsa.gov>,
	"Tetsuo Handa" <penguin-kernel@I-love.SAKURA.ne.jp>,
	linux-fsdevel@vger.kernel.org
Subject: [PATCH bpf-next v8 01/11] fs,security: Add a security blob to nameidata
Date: Tue, 27 Feb 2018 01:41:11 +0100	[thread overview]
Message-ID: <20180227004121.3633-2-mic@digikod.net> (raw)
In-Reply-To: <20180227004121.3633-1-mic@digikod.net>

The function current_nameidata_security(struct inode *) can be used to
retrieve a blob's pointer address tied to the inode being walk through.
This enable to follow a path lookup and know where an inode access come
from. This is needed for the Landlock LSM to be able to restrict access
to file path.

The LSM hook nameidata_free_security(struct inode *) is called before
freeing the associated nameidata.

Signed-off-by: Mickaël Salaün <mic@digikod.net>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Casey Schaufler <casey@schaufler-ca.com>
Cc: James Morris <jmorris@namei.org>
Cc: John Johansen <john.johansen@canonical.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Paul Moore <paul@paul-moore.com>
Cc: "Serge E. Hallyn" <serge@hallyn.com>
Cc: Stephen Smalley <sds@tycho.nsa.gov>
Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Cc: linux-fsdevel@vger.kernel.org
---
 fs/namei.c                | 39 +++++++++++++++++++++++++++++++++++++++
 include/linux/lsm_hooks.h |  7 +++++++
 include/linux/namei.h     | 14 +++++++++++++-
 include/linux/security.h  |  7 +++++++
 security/security.c       |  7 +++++++
 5 files changed, 73 insertions(+), 1 deletion(-)

diff --git a/fs/namei.c b/fs/namei.c
index 921ae32dbc80..d592b3fb0d1e 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -505,6 +505,9 @@ struct nameidata {
 	struct inode	*link_inode;
 	unsigned	root_seq;
 	int		dfd;
+#ifdef CONFIG_SECURITY
+	struct nameidata_lookup lookup;
+#endif
 } __randomize_layout;
 
 static void set_nameidata(struct nameidata *p, int dfd, struct filename *name)
@@ -515,6 +518,9 @@ static void set_nameidata(struct nameidata *p, int dfd, struct filename *name)
 	p->name = name;
 	p->total_link_count = old ? old->total_link_count : 0;
 	p->saved = old;
+#ifdef CONFIG_SECURITY
+	p->lookup.security = NULL;
+#endif
 	current->nameidata = p;
 }
 
@@ -522,6 +528,7 @@ static void restore_nameidata(void)
 {
 	struct nameidata *now = current->nameidata, *old = now->saved;
 
+	security_nameidata_put_lookup(&now->lookup, now->inode);
 	current->nameidata = old;
 	if (old)
 		old->total_link_count = now->total_link_count;
@@ -549,6 +556,27 @@ static int __nd_alloc_stack(struct nameidata *nd)
 	return 0;
 }
 
+#ifdef CONFIG_SECURITY
+/**
+ * current_nameidata_lookup - get the state of the current path walk
+ *
+ * @inode: inode associated to the path walk
+ *
+ * Used by LSM modules for access restriction based on path walk. The LSM is in
+ * charge of the lookup->security blob allocation and management. The hook
+ * security_nameidata_put_lookup() will be called after the path walk end.
+ *
+ * Return ERR_PTR(-ENOENT) if there is no match.
+ */
+struct nameidata_lookup *current_nameidata_lookup(const struct inode *inode)
+{
+	if (!current->nameidata || current->nameidata->inode != inode)
+		return ERR_PTR(-ENOENT);
+	return &current->nameidata->lookup;
+}
+EXPORT_SYMBOL(current_nameidata_lookup);
+#endif
+
 /**
  * path_connected - Verify that a path->dentry is below path->mnt.mnt_root
  * @path: nameidate to verify
@@ -2009,6 +2037,13 @@ static inline u64 hash_name(const void *salt, const char *name)
 
 #endif
 
+static inline void refresh_lookup(struct nameidata *nd)
+{
+#ifdef CONFIG_SECURITY
+	nd->lookup.type = nd->last_type;
+#endif
+}
+
 /*
  * Name resolution.
  * This is the basic name resolution function, turning a pathname into
@@ -2025,6 +2060,8 @@ static int link_path_walk(const char *name, struct nameidata *nd)
 		name++;
 	if (!*name)
 		return 0;
+	/* be ready for may_lookup() */
+	refresh_lookup(nd);
 
 	/* At this point we know we have a real path component. */
 	for(;;) {
@@ -2064,6 +2101,8 @@ static int link_path_walk(const char *name, struct nameidata *nd)
 		nd->last.hash_len = hash_len;
 		nd->last.name = name;
 		nd->last_type = type;
+		/* be ready for the next security_inode_permission() */
+		refresh_lookup(nd);
 
 		name += hashlen_len(hash_len);
 		if (!*name)
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 7161d8e7ee79..d71cf183f0be 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -428,6 +428,10 @@
  *	security module does not know about attribute or a negative error code
  *	to abort the copy up. Note that the caller is responsible for reading
  *	and writing the xattrs as this hook is merely a filter.
+ * @nameidata_put_lookup:
+ *	Deallocate and clear the current's nameidata->lookup.security field.
+ *	@lookup->security contains the security structure to be freed.
+ *	@inode is the last associated inode to the path walk
  *
  * Security hooks for file operations
  *
@@ -1514,6 +1518,8 @@ union security_list_options {
 	void (*inode_getsecid)(struct inode *inode, u32 *secid);
 	int (*inode_copy_up)(struct dentry *src, struct cred **new);
 	int (*inode_copy_up_xattr)(const char *name);
+	void (*nameidata_put_lookup)(struct nameidata_lookup *lookup,
+					struct inode *inode);
 
 	int (*file_permission)(struct file *file, int mask);
 	int (*file_alloc_security)(struct file *file);
@@ -1805,6 +1811,7 @@ struct security_hook_heads {
 	struct list_head inode_getsecid;
 	struct list_head inode_copy_up;
 	struct list_head inode_copy_up_xattr;
+	struct list_head nameidata_put_lookup;
 	struct list_head file_permission;
 	struct list_head file_alloc_security;
 	struct list_head file_free_security;
diff --git a/include/linux/namei.h b/include/linux/namei.h
index a982bb7cd480..ba08cbb41f97 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -14,7 +14,19 @@ enum { MAX_NESTED_LINKS = 8 };
 /*
  * Type of the last component on LOOKUP_PARENT
  */
-enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND};
+enum namei_type {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND};
+
+#ifdef CONFIG_SECURITY
+struct nameidata_lookup {
+	void *security;
+	enum namei_type type;
+};
+
+struct inode;
+
+extern struct nameidata_lookup *current_nameidata_lookup(
+		const struct inode *inode);
+#endif
 
 /*
  * The bitmask for a lookup event:
diff --git a/include/linux/security.h b/include/linux/security.h
index 73f1ef625d40..b1fd4370daf8 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -31,6 +31,7 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/fs.h>
+#include <linux/namei.h>
 
 struct linux_binprm;
 struct cred;
@@ -302,6 +303,8 @@ int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer
 void security_inode_getsecid(struct inode *inode, u32 *secid);
 int security_inode_copy_up(struct dentry *src, struct cred **new);
 int security_inode_copy_up_xattr(const char *name);
+void security_nameidata_put_lookup(struct nameidata_lookup *lookup,
+					struct inode *inode);
 int security_file_permission(struct file *file, int mask);
 int security_file_alloc(struct file *file);
 void security_file_free(struct file *file);
@@ -808,6 +811,10 @@ static inline int security_inode_copy_up_xattr(const char *name)
 	return -EOPNOTSUPP;
 }
 
+static inline void security_nameidata_put_lookup(
+		struct nameidata_lookup *lookup, struct inode *inode)
+{ }
+
 static inline int security_file_permission(struct file *file, int mask)
 {
 	return 0;
diff --git a/security/security.c b/security/security.c
index 1cd8526cb0b7..17053c7a1a77 100644
--- a/security/security.c
+++ b/security/security.c
@@ -857,6 +857,13 @@ int security_inode_copy_up_xattr(const char *name)
 }
 EXPORT_SYMBOL(security_inode_copy_up_xattr);
 
+void security_nameidata_put_lookup(struct nameidata_lookup *lookup,
+					struct inode *inode)
+{
+	call_void_hook(nameidata_put_lookup, lookup, inode);
+}
+EXPORT_SYMBOL(security_nameidata_put_lookup);
+
 int security_file_permission(struct file *file, int mask)
 {
 	int ret;
-- 
2.16.2

WARNING: multiple messages have this Message-ID (diff)
From: "Mickaël Salaün" <mic@digikod.net>
To: linux-kernel@vger.kernel.org
Cc: "Mickaël Salaün" <mic@digikod.net>,
	"Alexei Starovoitov" <ast@kernel.org>,
	"Andy Lutomirski" <luto@amacapital.net>,
	"Arnaldo Carvalho de Melo" <acme@kernel.org>,
	"Casey Schaufler" <casey@schaufler-ca.com>,
	"Daniel Borkmann" <daniel@iogearbox.net>,
	"David Drysdale" <drysdale@google.com>,
	"David S . Miller" <davem@davemloft.net>,
	"Eric W . Biederman" <ebiederm@xmission.com>,
	"James Morris" <james.l.morris@oracle.com>,
	"Jann Horn" <jann@thejh.net>, "Jonathan Corbet" <corbet@lwn.net>,
	"Michael Kerrisk" <mtk.manpages@gmail.com>,
	"Kees Cook" <keescook@chromium.org>,
	"Paul Moore" <paul@paul-moore.com>,
	"Sargun Dhillon" <sargun@sargun.me>,
	"Serge E . Hallyn" <serge@hallyn.com>,
	"Shuah Khan" <shuah@kernel.org>, "Tejun Heo" <tj@kernel.org>,
	"Thomas Graf" <tgraf@suug.ch>
Subject: [PATCH bpf-next v8 01/11] fs,security: Add a security blob to nameidata
Date: Tue, 27 Feb 2018 01:41:11 +0100	[thread overview]
Message-ID: <20180227004121.3633-2-mic@digikod.net> (raw)
In-Reply-To: <20180227004121.3633-1-mic@digikod.net>

The function current_nameidata_security(struct inode *) can be used to
retrieve a blob's pointer address tied to the inode being walk through.
This enable to follow a path lookup and know where an inode access come
from. This is needed for the Landlock LSM to be able to restrict access
to file path.

The LSM hook nameidata_free_security(struct inode *) is called before
freeing the associated nameidata.

Signed-off-by: Mickaël Salaün <mic@digikod.net>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Casey Schaufler <casey@schaufler-ca.com>
Cc: James Morris <jmorris@namei.org>
Cc: John Johansen <john.johansen@canonical.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Paul Moore <paul@paul-moore.com>
Cc: "Serge E. Hallyn" <serge@hallyn.com>
Cc: Stephen Smalley <sds@tycho.nsa.gov>
Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Cc: linux-fsdevel@vger.kernel.org
---
 fs/namei.c                | 39 +++++++++++++++++++++++++++++++++++++++
 include/linux/lsm_hooks.h |  7 +++++++
 include/linux/namei.h     | 14 +++++++++++++-
 include/linux/security.h  |  7 +++++++
 security/security.c       |  7 +++++++
 5 files changed, 73 insertions(+), 1 deletion(-)

diff --git a/fs/namei.c b/fs/namei.c
index 921ae32dbc80..d592b3fb0d1e 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -505,6 +505,9 @@ struct nameidata {
 	struct inode	*link_inode;
 	unsigned	root_seq;
 	int		dfd;
+#ifdef CONFIG_SECURITY
+	struct nameidata_lookup lookup;
+#endif
 } __randomize_layout;
 
 static void set_nameidata(struct nameidata *p, int dfd, struct filename *name)
@@ -515,6 +518,9 @@ static void set_nameidata(struct nameidata *p, int dfd, struct filename *name)
 	p->name = name;
 	p->total_link_count = old ? old->total_link_count : 0;
 	p->saved = old;
+#ifdef CONFIG_SECURITY
+	p->lookup.security = NULL;
+#endif
 	current->nameidata = p;
 }
 
@@ -522,6 +528,7 @@ static void restore_nameidata(void)
 {
 	struct nameidata *now = current->nameidata, *old = now->saved;
 
+	security_nameidata_put_lookup(&now->lookup, now->inode);
 	current->nameidata = old;
 	if (old)
 		old->total_link_count = now->total_link_count;
@@ -549,6 +556,27 @@ static int __nd_alloc_stack(struct nameidata *nd)
 	return 0;
 }
 
+#ifdef CONFIG_SECURITY
+/**
+ * current_nameidata_lookup - get the state of the current path walk
+ *
+ * @inode: inode associated to the path walk
+ *
+ * Used by LSM modules for access restriction based on path walk. The LSM is in
+ * charge of the lookup->security blob allocation and management. The hook
+ * security_nameidata_put_lookup() will be called after the path walk end.
+ *
+ * Return ERR_PTR(-ENOENT) if there is no match.
+ */
+struct nameidata_lookup *current_nameidata_lookup(const struct inode *inode)
+{
+	if (!current->nameidata || current->nameidata->inode != inode)
+		return ERR_PTR(-ENOENT);
+	return &current->nameidata->lookup;
+}
+EXPORT_SYMBOL(current_nameidata_lookup);
+#endif
+
 /**
  * path_connected - Verify that a path->dentry is below path->mnt.mnt_root
  * @path: nameidate to verify
@@ -2009,6 +2037,13 @@ static inline u64 hash_name(const void *salt, const char *name)
 
 #endif
 
+static inline void refresh_lookup(struct nameidata *nd)
+{
+#ifdef CONFIG_SECURITY
+	nd->lookup.type = nd->last_type;
+#endif
+}
+
 /*
  * Name resolution.
  * This is the basic name resolution function, turning a pathname into
@@ -2025,6 +2060,8 @@ static int link_path_walk(const char *name, struct nameidata *nd)
 		name++;
 	if (!*name)
 		return 0;
+	/* be ready for may_lookup() */
+	refresh_lookup(nd);
 
 	/* At this point we know we have a real path component. */
 	for(;;) {
@@ -2064,6 +2101,8 @@ static int link_path_walk(const char *name, struct nameidata *nd)
 		nd->last.hash_len = hash_len;
 		nd->last.name = name;
 		nd->last_type = type;
+		/* be ready for the next security_inode_permission() */
+		refresh_lookup(nd);
 
 		name += hashlen_len(hash_len);
 		if (!*name)
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 7161d8e7ee79..d71cf183f0be 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -428,6 +428,10 @@
  *	security module does not know about attribute or a negative error code
  *	to abort the copy up. Note that the caller is responsible for reading
  *	and writing the xattrs as this hook is merely a filter.
+ * @nameidata_put_lookup:
+ *	Deallocate and clear the current's nameidata->lookup.security field.
+ *	@lookup->security contains the security structure to be freed.
+ *	@inode is the last associated inode to the path walk
  *
  * Security hooks for file operations
  *
@@ -1514,6 +1518,8 @@ union security_list_options {
 	void (*inode_getsecid)(struct inode *inode, u32 *secid);
 	int (*inode_copy_up)(struct dentry *src, struct cred **new);
 	int (*inode_copy_up_xattr)(const char *name);
+	void (*nameidata_put_lookup)(struct nameidata_lookup *lookup,
+					struct inode *inode);
 
 	int (*file_permission)(struct file *file, int mask);
 	int (*file_alloc_security)(struct file *file);
@@ -1805,6 +1811,7 @@ struct security_hook_heads {
 	struct list_head inode_getsecid;
 	struct list_head inode_copy_up;
 	struct list_head inode_copy_up_xattr;
+	struct list_head nameidata_put_lookup;
 	struct list_head file_permission;
 	struct list_head file_alloc_security;
 	struct list_head file_free_security;
diff --git a/include/linux/namei.h b/include/linux/namei.h
index a982bb7cd480..ba08cbb41f97 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -14,7 +14,19 @@ enum { MAX_NESTED_LINKS = 8 };
 /*
  * Type of the last component on LOOKUP_PARENT
  */
-enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND};
+enum namei_type {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND};
+
+#ifdef CONFIG_SECURITY
+struct nameidata_lookup {
+	void *security;
+	enum namei_type type;
+};
+
+struct inode;
+
+extern struct nameidata_lookup *current_nameidata_lookup(
+		const struct inode *inode);
+#endif
 
 /*
  * The bitmask for a lookup event:
diff --git a/include/linux/security.h b/include/linux/security.h
index 73f1ef625d40..b1fd4370daf8 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -31,6 +31,7 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/fs.h>
+#include <linux/namei.h>
 
 struct linux_binprm;
 struct cred;
@@ -302,6 +303,8 @@ int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer
 void security_inode_getsecid(struct inode *inode, u32 *secid);
 int security_inode_copy_up(struct dentry *src, struct cred **new);
 int security_inode_copy_up_xattr(const char *name);
+void security_nameidata_put_lookup(struct nameidata_lookup *lookup,
+					struct inode *inode);
 int security_file_permission(struct file *file, int mask);
 int security_file_alloc(struct file *file);
 void security_file_free(struct file *file);
@@ -808,6 +811,10 @@ static inline int security_inode_copy_up_xattr(const char *name)
 	return -EOPNOTSUPP;
 }
 
+static inline void security_nameidata_put_lookup(
+		struct nameidata_lookup *lookup, struct inode *inode)
+{ }
+
 static inline int security_file_permission(struct file *file, int mask)
 {
 	return 0;
diff --git a/security/security.c b/security/security.c
index 1cd8526cb0b7..17053c7a1a77 100644
--- a/security/security.c
+++ b/security/security.c
@@ -857,6 +857,13 @@ int security_inode_copy_up_xattr(const char *name)
 }
 EXPORT_SYMBOL(security_inode_copy_up_xattr);
 
+void security_nameidata_put_lookup(struct nameidata_lookup *lookup,
+					struct inode *inode)
+{
+	call_void_hook(nameidata_put_lookup, lookup, inode);
+}
+EXPORT_SYMBOL(security_nameidata_put_lookup);
+
 int security_file_permission(struct file *file, int mask)
 {
 	int ret;
-- 
2.16.2

WARNING: multiple messages have this Message-ID (diff)
From: mic@digikod.net (Mickaël Salaün)
To: linux-security-module@vger.kernel.org
Subject: [PATCH bpf-next v8 01/11] fs, security: Add a security blob to nameidata
Date: Tue, 27 Feb 2018 01:41:11 +0100	[thread overview]
Message-ID: <20180227004121.3633-2-mic@digikod.net> (raw)
In-Reply-To: <20180227004121.3633-1-mic@digikod.net>

The function current_nameidata_security(struct inode *) can be used to
retrieve a blob's pointer address tied to the inode being walk through.
This enable to follow a path lookup and know where an inode access come
from. This is needed for the Landlock LSM to be able to restrict access
to file path.

The LSM hook nameidata_free_security(struct inode *) is called before
freeing the associated nameidata.

Signed-off-by: Micka?l Sala?n <mic@digikod.net>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Casey Schaufler <casey@schaufler-ca.com>
Cc: James Morris <jmorris@namei.org>
Cc: John Johansen <john.johansen@canonical.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Paul Moore <paul@paul-moore.com>
Cc: "Serge E. Hallyn" <serge@hallyn.com>
Cc: Stephen Smalley <sds@tycho.nsa.gov>
Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Cc: linux-fsdevel at vger.kernel.org
---
 fs/namei.c                | 39 +++++++++++++++++++++++++++++++++++++++
 include/linux/lsm_hooks.h |  7 +++++++
 include/linux/namei.h     | 14 +++++++++++++-
 include/linux/security.h  |  7 +++++++
 security/security.c       |  7 +++++++
 5 files changed, 73 insertions(+), 1 deletion(-)

diff --git a/fs/namei.c b/fs/namei.c
index 921ae32dbc80..d592b3fb0d1e 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -505,6 +505,9 @@ struct nameidata {
 	struct inode	*link_inode;
 	unsigned	root_seq;
 	int		dfd;
+#ifdef CONFIG_SECURITY
+	struct nameidata_lookup lookup;
+#endif
 } __randomize_layout;
 
 static void set_nameidata(struct nameidata *p, int dfd, struct filename *name)
@@ -515,6 +518,9 @@ static void set_nameidata(struct nameidata *p, int dfd, struct filename *name)
 	p->name = name;
 	p->total_link_count = old ? old->total_link_count : 0;
 	p->saved = old;
+#ifdef CONFIG_SECURITY
+	p->lookup.security = NULL;
+#endif
 	current->nameidata = p;
 }
 
@@ -522,6 +528,7 @@ static void restore_nameidata(void)
 {
 	struct nameidata *now = current->nameidata, *old = now->saved;
 
+	security_nameidata_put_lookup(&now->lookup, now->inode);
 	current->nameidata = old;
 	if (old)
 		old->total_link_count = now->total_link_count;
@@ -549,6 +556,27 @@ static int __nd_alloc_stack(struct nameidata *nd)
 	return 0;
 }
 
+#ifdef CONFIG_SECURITY
+/**
+ * current_nameidata_lookup - get the state of the current path walk
+ *
+ * @inode: inode associated to the path walk
+ *
+ * Used by LSM modules for access restriction based on path walk. The LSM is in
+ * charge of the lookup->security blob allocation and management. The hook
+ * security_nameidata_put_lookup() will be called after the path walk end.
+ *
+ * Return ERR_PTR(-ENOENT) if there is no match.
+ */
+struct nameidata_lookup *current_nameidata_lookup(const struct inode *inode)
+{
+	if (!current->nameidata || current->nameidata->inode != inode)
+		return ERR_PTR(-ENOENT);
+	return &current->nameidata->lookup;
+}
+EXPORT_SYMBOL(current_nameidata_lookup);
+#endif
+
 /**
  * path_connected - Verify that a path->dentry is below path->mnt.mnt_root
  * @path: nameidate to verify
@@ -2009,6 +2037,13 @@ static inline u64 hash_name(const void *salt, const char *name)
 
 #endif
 
+static inline void refresh_lookup(struct nameidata *nd)
+{
+#ifdef CONFIG_SECURITY
+	nd->lookup.type = nd->last_type;
+#endif
+}
+
 /*
  * Name resolution.
  * This is the basic name resolution function, turning a pathname into
@@ -2025,6 +2060,8 @@ static int link_path_walk(const char *name, struct nameidata *nd)
 		name++;
 	if (!*name)
 		return 0;
+	/* be ready for may_lookup() */
+	refresh_lookup(nd);
 
 	/* At this point we know we have a real path component. */
 	for(;;) {
@@ -2064,6 +2101,8 @@ static int link_path_walk(const char *name, struct nameidata *nd)
 		nd->last.hash_len = hash_len;
 		nd->last.name = name;
 		nd->last_type = type;
+		/* be ready for the next security_inode_permission() */
+		refresh_lookup(nd);
 
 		name += hashlen_len(hash_len);
 		if (!*name)
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 7161d8e7ee79..d71cf183f0be 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -428,6 +428,10 @@
  *	security module does not know about attribute or a negative error code
  *	to abort the copy up. Note that the caller is responsible for reading
  *	and writing the xattrs as this hook is merely a filter.
+ * @nameidata_put_lookup:
+ *	Deallocate and clear the current's nameidata->lookup.security field.
+ *	@lookup->security contains the security structure to be freed.
+ *	@inode is the last associated inode to the path walk
  *
  * Security hooks for file operations
  *
@@ -1514,6 +1518,8 @@ union security_list_options {
 	void (*inode_getsecid)(struct inode *inode, u32 *secid);
 	int (*inode_copy_up)(struct dentry *src, struct cred **new);
 	int (*inode_copy_up_xattr)(const char *name);
+	void (*nameidata_put_lookup)(struct nameidata_lookup *lookup,
+					struct inode *inode);
 
 	int (*file_permission)(struct file *file, int mask);
 	int (*file_alloc_security)(struct file *file);
@@ -1805,6 +1811,7 @@ struct security_hook_heads {
 	struct list_head inode_getsecid;
 	struct list_head inode_copy_up;
 	struct list_head inode_copy_up_xattr;
+	struct list_head nameidata_put_lookup;
 	struct list_head file_permission;
 	struct list_head file_alloc_security;
 	struct list_head file_free_security;
diff --git a/include/linux/namei.h b/include/linux/namei.h
index a982bb7cd480..ba08cbb41f97 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -14,7 +14,19 @@ enum { MAX_NESTED_LINKS = 8 };
 /*
  * Type of the last component on LOOKUP_PARENT
  */
-enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND};
+enum namei_type {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND};
+
+#ifdef CONFIG_SECURITY
+struct nameidata_lookup {
+	void *security;
+	enum namei_type type;
+};
+
+struct inode;
+
+extern struct nameidata_lookup *current_nameidata_lookup(
+		const struct inode *inode);
+#endif
 
 /*
  * The bitmask for a lookup event:
diff --git a/include/linux/security.h b/include/linux/security.h
index 73f1ef625d40..b1fd4370daf8 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -31,6 +31,7 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/fs.h>
+#include <linux/namei.h>
 
 struct linux_binprm;
 struct cred;
@@ -302,6 +303,8 @@ int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer
 void security_inode_getsecid(struct inode *inode, u32 *secid);
 int security_inode_copy_up(struct dentry *src, struct cred **new);
 int security_inode_copy_up_xattr(const char *name);
+void security_nameidata_put_lookup(struct nameidata_lookup *lookup,
+					struct inode *inode);
 int security_file_permission(struct file *file, int mask);
 int security_file_alloc(struct file *file);
 void security_file_free(struct file *file);
@@ -808,6 +811,10 @@ static inline int security_inode_copy_up_xattr(const char *name)
 	return -EOPNOTSUPP;
 }
 
+static inline void security_nameidata_put_lookup(
+		struct nameidata_lookup *lookup, struct inode *inode)
+{ }
+
 static inline int security_file_permission(struct file *file, int mask)
 {
 	return 0;
diff --git a/security/security.c b/security/security.c
index 1cd8526cb0b7..17053c7a1a77 100644
--- a/security/security.c
+++ b/security/security.c
@@ -857,6 +857,13 @@ int security_inode_copy_up_xattr(const char *name)
 }
 EXPORT_SYMBOL(security_inode_copy_up_xattr);
 
+void security_nameidata_put_lookup(struct nameidata_lookup *lookup,
+					struct inode *inode)
+{
+	call_void_hook(nameidata_put_lookup, lookup, inode);
+}
+EXPORT_SYMBOL(security_nameidata_put_lookup);
+
 int security_file_permission(struct file *file, int mask)
 {
 	int ret;
-- 
2.16.2

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

  reply	other threads:[~2018-02-27  0:41 UTC|newest]

Thread overview: 191+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-02-27  0:41 [PATCH bpf-next v8 00/11] Landlock LSM: Toward unprivileged sandboxing Mickaël Salaün
2018-02-27  0:41 ` Mickaël Salaün
2018-02-27  0:41 ` Mickaël Salaün
2018-02-27  0:41 ` Mickaël Salaün [this message]
2018-02-27  0:41   ` [PATCH bpf-next v8 01/11] fs, security: Add a security blob to nameidata Mickaël Salaün
2018-02-27  0:41   ` [PATCH bpf-next v8 01/11] fs,security: " Mickaël Salaün
2018-02-27  0:57   ` Al Viro
2018-02-27  0:57     ` Al Viro
2018-02-27  0:57     ` Al Viro
2018-02-27  0:57     ` Al Viro
2018-02-27  0:57     ` Al Viro
2018-02-27  1:23     ` Al Viro
2018-02-27  1:23       ` Al Viro
2018-02-27  1:23       ` Al Viro
2018-02-27  1:23       ` Al Viro
2018-02-27  1:23       ` Al Viro
2018-03-11 20:14       ` Mickaël Salaün
2018-03-11 20:14         ` Mickaël Salaün
2018-03-11 20:14         ` Mickaël Salaün
2018-02-28 16:27   ` kbuild test robot
2018-02-28 16:27     ` kbuild test robot
2018-02-28 16:27     ` kbuild test robot
2018-02-28 16:27     ` kbuild test robot
2018-02-28 16:27     ` kbuild test robot
2018-02-28 16:27     ` kbuild test robot
2018-02-28 16:58   ` kbuild test robot
2018-02-28 16:58     ` kbuild test robot
2018-02-28 16:58     ` kbuild test robot
2018-02-28 16:58     ` kbuild test robot
2018-02-28 16:58     ` kbuild test robot
2018-02-28 16:58     ` kbuild test robot
2018-02-27  0:41 ` [PATCH bpf-next v8 02/11] fs,security: Add a new file access type: MAY_CHROOT Mickaël Salaün
2018-02-27  0:41   ` [PATCH bpf-next v8 02/11] fs, security: " Mickaël Salaün
2018-02-27  0:41   ` [PATCH bpf-next v8 02/11] fs,security: " Mickaël Salaün
2018-02-27  0:41 ` [PATCH bpf-next v8 03/11] bpf: Add eBPF program subtype and is_valid_subtype() verifier Mickaël Salaün
2018-02-27  0:41   ` Mickaël Salaün
2018-02-27  0:41   ` Mickaël Salaün
2018-02-27  0:41 ` [PATCH bpf-next v8 04/11] bpf,landlock: Define an eBPF program type for Landlock hooks Mickaël Salaün
2018-02-27  0:41   ` [PATCH bpf-next v8 04/11] bpf, landlock: " Mickaël Salaün
2018-02-27  0:41   ` [PATCH bpf-next v8 04/11] bpf,landlock: " Mickaël Salaün
2018-02-27  0:41 ` [PATCH bpf-next v8 05/11] seccomp,landlock: Enforce Landlock programs per process hierarchy Mickaël Salaün
2018-02-27  0:41   ` [PATCH bpf-next v8 05/11] seccomp, landlock: " Mickaël Salaün
2018-02-27  0:41   ` [PATCH bpf-next v8 05/11] seccomp,landlock: " Mickaël Salaün
2018-02-27  2:08   ` Alexei Starovoitov
2018-02-27  2:08     ` Alexei Starovoitov
2018-02-27  2:08     ` Alexei Starovoitov
2018-02-27  2:08     ` Alexei Starovoitov
2018-02-27  4:40     ` Andy Lutomirski
2018-02-27  4:40       ` Andy Lutomirski
2018-02-27  4:40       ` Andy Lutomirski
2018-02-27  4:54       ` Alexei Starovoitov
2018-02-27  4:54         ` Alexei Starovoitov
2018-02-27  4:54         ` Alexei Starovoitov
2018-02-27  5:20         ` Andy Lutomirski
2018-02-27  5:20           ` Andy Lutomirski
2018-02-27  5:20           ` Andy Lutomirski
2018-02-27  5:32           ` Alexei Starovoitov
2018-02-27  5:32             ` Alexei Starovoitov
2018-02-27  5:32             ` Alexei Starovoitov
2018-02-27 16:39             ` Andy Lutomirski
2018-02-27 16:39               ` Andy Lutomirski
2018-02-27 16:39               ` Andy Lutomirski
2018-02-27 17:30               ` Casey Schaufler
2018-02-27 17:30                 ` Casey Schaufler
2018-02-27 17:30                 ` Casey Schaufler
2018-02-27 17:36                 ` Andy Lutomirski
2018-02-27 17:36                   ` Andy Lutomirski
2018-02-27 17:36                   ` Andy Lutomirski
2018-02-27 18:03                   ` Casey Schaufler
2018-02-27 18:03                     ` Casey Schaufler
2018-02-27 18:03                     ` Casey Schaufler
2018-02-27 21:48               ` Mickaël Salaün
2018-02-27 21:48                 ` Mickaël Salaün
2018-02-27 21:48                 ` Mickaël Salaün
2018-04-08 13:13                 ` Mickaël Salaün
2018-04-08 13:13                   ` Mickaël Salaün
2018-04-08 13:13                   ` Mickaël Salaün
2018-04-08 21:06                   ` Andy Lutomirski
2018-04-08 21:06                     ` Andy Lutomirski
2018-04-08 21:06                     ` Andy Lutomirski
2018-04-08 21:06                     ` Andy Lutomirski
2018-04-08 22:01                     ` Mickaël Salaün
2018-04-08 22:01                       ` Mickaël Salaün
2018-04-08 22:01                       ` Mickaël Salaün
2018-04-10  4:48                       ` Alexei Starovoitov
2018-04-10  4:48                         ` Alexei Starovoitov
2018-04-10  4:48                         ` Alexei Starovoitov
2018-04-10  4:48                         ` Alexei Starovoitov
2018-04-10  4:48                         ` Alexei Starovoitov
2018-04-11 22:18                         ` Mickaël Salaün
2018-04-11 22:18                           ` Mickaël Salaün
2018-04-11 22:18                           ` Mickaël Salaün
2018-02-27  0:41 ` [PATCH bpf-next v8 06/11] bpf,landlock: Add a new map type: inode Mickaël Salaün
2018-02-27  0:41   ` Mickaël Salaün
2018-02-27  0:41   ` Mickaël Salaün
2018-02-28 17:35   ` kbuild test robot
2018-02-28 17:35     ` kbuild test robot
2018-02-28 17:35     ` kbuild test robot
2018-02-28 17:35     ` [PATCH bpf-next v8 06/11] bpf, landlock: " kbuild test robot
2018-02-28 17:35     ` [PATCH bpf-next v8 06/11] bpf,landlock: " kbuild test robot
2018-02-27  0:41 ` [PATCH bpf-next v8 07/11] landlock: Handle filesystem access control Mickaël Salaün
2018-02-27  0:41   ` Mickaël Salaün
2018-02-27  0:41   ` Mickaël Salaün
2018-02-27  0:41 ` [PATCH bpf-next v8 08/11] landlock: Add ptrace restrictions Mickaël Salaün
2018-02-27  0:41   ` Mickaël Salaün
2018-02-27  0:41   ` Mickaël Salaün
2018-02-27  4:17   ` Andy Lutomirski
2018-02-27  4:17     ` Andy Lutomirski
2018-02-27  4:17     ` Andy Lutomirski
2018-02-27  4:17     ` Andy Lutomirski
2018-02-27  5:01     ` Andy Lutomirski
2018-02-27  5:01       ` Andy Lutomirski
2018-02-27  5:01       ` Andy Lutomirski
2018-02-27  5:01       ` Andy Lutomirski
2018-02-27 22:14       ` Mickaël Salaün
2018-02-27 22:14         ` Mickaël Salaün
2018-02-27 22:14         ` Mickaël Salaün
2018-02-27 23:02         ` Andy Lutomirski
2018-02-27 23:02           ` Andy Lutomirski
2018-02-27 23:02           ` Andy Lutomirski
2018-02-27 23:02           ` Andy Lutomirski
2018-02-27 23:23           ` Andy Lutomirski
2018-02-27 23:23             ` Andy Lutomirski
2018-02-27 23:23             ` Andy Lutomirski
2018-02-28  0:00             ` Mickaël Salaün
2018-02-28  0:00               ` Mickaël Salaün
2018-02-28  0:00               ` Mickaël Salaün
2018-02-28  0:09               ` Andy Lutomirski
2018-02-28  0:09                 ` Andy Lutomirski
2018-02-28  0:09                 ` Andy Lutomirski
2018-02-28  0:09                 ` Andy Lutomirski
2018-03-06 22:28                 ` Mickaël Salaün
2018-03-06 22:28                   ` Mickaël Salaün
2018-03-06 22:28                   ` Mickaël Salaün
2018-04-01 22:48                   ` Mickaël Salaün
2018-04-01 22:48                     ` Mickaël Salaün
2018-04-01 22:48                     ` Mickaël Salaün
2018-02-27 22:18     ` Mickaël Salaün
2018-02-27 22:18       ` Mickaël Salaün
2018-02-27 22:18       ` Mickaël Salaün
2018-02-27  0:41 ` [PATCH bpf-next v8 09/11] bpf: Add a Landlock sandbox example Mickaël Salaün
2018-02-27  0:41   ` Mickaël Salaün
2018-02-27  0:41   ` Mickaël Salaün
2018-02-27  0:41 ` [PATCH bpf-next v8 10/11] bpf,landlock: Add tests for Landlock Mickaël Salaün
2018-02-27  0:41   ` Mickaël Salaün
2018-02-27  0:41   ` Mickaël Salaün
2018-02-27  0:41 ` [PATCH bpf-next v8 11/11] landlock: Add user and kernel documentation " Mickaël Salaün
2018-02-27  0:41   ` Mickaël Salaün
2018-02-27  0:41   ` Mickaël Salaün
2018-02-27  4:36 ` [PATCH bpf-next v8 00/11] Landlock LSM: Toward unprivileged sandboxing Andy Lutomirski
2018-02-27  4:36   ` Andy Lutomirski
2018-02-27  4:36   ` Andy Lutomirski
2018-02-27  4:36   ` Andy Lutomirski
2018-02-27 22:03   ` Mickaël Salaün
2018-02-27 22:03     ` Mickaël Salaün
2018-02-27 22:03     ` Mickaël Salaün
2018-02-27 23:09     ` Andy Lutomirski
2018-02-27 23:09       ` Andy Lutomirski
2018-02-27 23:09       ` Andy Lutomirski
2018-02-27 23:09       ` Andy Lutomirski
2018-03-06 22:25       ` Mickaël Salaün
2018-03-06 22:25         ` Mickaël Salaün
2018-03-06 22:25         ` Mickaël Salaün
2018-03-06 22:33         ` Andy Lutomirski
2018-03-06 22:33           ` Andy Lutomirski
2018-03-06 22:33           ` Andy Lutomirski
2018-03-06 22:33           ` Andy Lutomirski
2018-03-06 22:46           ` Tycho Andersen
2018-03-06 22:46             ` Tycho Andersen
2018-03-06 22:46             ` Tycho Andersen
2018-03-06 23:06             ` Mickaël Salaün
2018-03-06 23:06               ` Mickaël Salaün
2018-03-06 23:06               ` Mickaël Salaün
2018-03-07  1:21               ` Andy Lutomirski
2018-03-07  1:21                 ` Andy Lutomirski
2018-03-07  1:21                 ` Andy Lutomirski
2018-03-07  1:21                 ` Andy Lutomirski
2018-03-08 23:51                 ` Mickaël Salaün
2018-03-08 23:51                   ` Mickaël Salaün
2018-03-08 23:51                   ` Mickaël Salaün
2018-03-08 23:53                   ` Andy Lutomirski
2018-03-08 23:53                     ` Andy Lutomirski
2018-03-08 23:53                     ` Andy Lutomirski
2018-03-08 23:53                     ` Andy Lutomirski
2018-04-01 22:04                     ` Mickaël Salaün
2018-04-01 22:04                       ` Mickaël Salaün
2018-04-01 22:04                       ` Mickaël Salaün
2018-04-02  0:39                       ` Tycho Andersen
2018-04-02  0:39                         ` Tycho Andersen
2018-04-02  0:39                         ` Tycho Andersen
2018-04-02  0:39                         ` Tycho Andersen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180227004121.3633-2-mic@digikod.net \
    --to=mic@digikod.net \
    --cc=acme@kernel.org \
    --cc=ast@kernel.org \
    --cc=casey@schaufler-ca.com \
    --cc=corbet@lwn.net \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=drysdale@google.com \
    --cc=ebiederm@xmission.com \
    --cc=james.l.morris@oracle.com \
    --cc=jann@thejh.net \
    --cc=jmorris@namei.org \
    --cc=john.johansen@canonical.com \
    --cc=keescook@chromium.org \
    --cc=kernel-hardening@lists.openwall.com \
    --cc=linux-api@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=luto@amacapital.net \
    --cc=mtk.manpages@gmail.com \
    --cc=netdev@vger.kernel.org \
    --cc=paul@paul-moore.com \
    --cc=penguin-kernel@I-love.SAKURA.ne.jp \
    --cc=sargun@sargun.me \
    --cc=sds@tycho.nsa.gov \
    --cc=serge@hallyn.com \
    --cc=shuah@kernel.org \
    --cc=tgraf@suug.ch \
    --cc=tj@kernel.org \
    --cc=tycho@tycho.ws \
    --cc=viro@zeniv.linux.org.uk \
    --cc=wad@chromium.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.