linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC 1/1] xattr: provide integrity. namespace to read real values
@ 2013-02-13  9:07 Dmitry Kasatkin
  2013-02-14  7:48 ` Kasatkin, Dmitry
  2013-02-14 20:05 ` Vivek Goyal
  0 siblings, 2 replies; 4+ messages in thread
From: Dmitry Kasatkin @ 2013-02-13  9:07 UTC (permalink / raw)
  To: linux-security-module; +Cc: linux-kernel, casey, zohar, viro, linux-fsdevel

User space tools use getxattr() system call to read values of extended
attributes. getxattr() system call uses vfs_getattr(), which for "security."
namespace might get a value of the xattr indirectly from LSM via calling
xattr_getsecurity(). For that reason value set by setxattr and read by getxattr
might differ.

Here is an example of SMACK label, which shows that set and read values are
different:

  setfattr -n security.SMACK64 -v "hello world" foo
  getfattr -n security.SMACK64 foo
  # file: foo
  security.SMACK64="hello"

EVM uses vfs_getxattr_alloc(), which directly reads xattr values from the file
system. When performing the file system labeling with digital signatures, it is
necessary to read real xattr values in order to generate the correct signatures.

This patch adds the virtual "integrity." name space, which allows to bypass
calling LSM and read real extended attribute values.

  getfattr -e text -n integrity.SMACK64 foo
  # file: foo
  integrity.SMACK64="hello world"

Suggested-by: Casey Schaufler <casey@schaufler-ca.com>
Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
---
 fs/xattr.c                 |   22 +++++++++++++++++++---
 include/uapi/linux/xattr.h |    4 ++++
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/fs/xattr.c b/fs/xattr.c
index 3377dff..76c2620 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -232,12 +232,28 @@ vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size)
 {
 	struct inode *inode = dentry->d_inode;
 	int error;
+	char *usename = (char *)name, name_buf[XATTR_NAME_MAX];
+
+	/* because this function calls LSM for "security." namespace,
+	 * it may be impossible to get real value stored in xattr.
+	 * An LSM may mangle the attribute value to its own ends.
+	 * Smack is known to do this.
+	 * virtual namespace "integrity." is used to fetch real
+	 * security attributes without talking to LSM
+	 */
+	if (!strncmp(name, XATTR_INTEGRITY_PREFIX,
+				XATTR_INTEGRITY_PREFIX_LEN)) {
+		/* replace "integrity. with security. */
+		snprintf(name_buf, sizeof(name_buf), "security.%s",
+			 name + XATTR_INTEGRITY_PREFIX_LEN);
+		usename = name_buf;
+	}
 
-	error = xattr_permission(inode, name, MAY_READ);
+	error = xattr_permission(inode, usename, MAY_READ);
 	if (error)
 		return error;
 
-	error = security_inode_getxattr(dentry, name);
+	error = security_inode_getxattr(dentry, usename);
 	if (error)
 		return error;
 
@@ -255,7 +271,7 @@ vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size)
 	}
 nolsm:
 	if (inode->i_op->getxattr)
-		error = inode->i_op->getxattr(dentry, name, value, size);
+		error = inode->i_op->getxattr(dentry, usename, value, size);
 	else
 		error = -EOPNOTSUPP;
 
diff --git a/include/uapi/linux/xattr.h b/include/uapi/linux/xattr.h
index 26607bd..133998b 100644
--- a/include/uapi/linux/xattr.h
+++ b/include/uapi/linux/xattr.h
@@ -20,6 +20,10 @@
 #define XATTR_SECURITY_PREFIX	"security."
 #define XATTR_SECURITY_PREFIX_LEN (sizeof (XATTR_SECURITY_PREFIX) - 1)
 
+/* integrity - security mirror namespace for integrity purpose */
+#define XATTR_INTEGRITY_PREFIX	"integrity."
+#define XATTR_INTEGRITY_PREFIX_LEN (sizeof (XATTR_INTEGRITY_PREFIX) - 1)
+
 #define XATTR_SYSTEM_PREFIX "system."
 #define XATTR_SYSTEM_PREFIX_LEN (sizeof (XATTR_SYSTEM_PREFIX) - 1)
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [RFC 1/1] xattr: provide integrity. namespace to read real values
  2013-02-13  9:07 [RFC 1/1] xattr: provide integrity. namespace to read real values Dmitry Kasatkin
@ 2013-02-14  7:48 ` Kasatkin, Dmitry
  2013-02-14 20:05 ` Vivek Goyal
  1 sibling, 0 replies; 4+ messages in thread
From: Kasatkin, Dmitry @ 2013-02-14  7:48 UTC (permalink / raw)
  To: linux-security-module, James Morris
  Cc: linux-kernel, casey, zohar, viro, linux-fsdevel

Hello,

Any comments about this patch and functionality?

Thanks,
Dmitry

On Wed, Feb 13, 2013 at 11:07 AM, Dmitry Kasatkin
<dmitry.kasatkin@intel.com> wrote:
> User space tools use getxattr() system call to read values of extended
> attributes. getxattr() system call uses vfs_getattr(), which for "security."
> namespace might get a value of the xattr indirectly from LSM via calling
> xattr_getsecurity(). For that reason value set by setxattr and read by getxattr
> might differ.
>
> Here is an example of SMACK label, which shows that set and read values are
> different:
>
>   setfattr -n security.SMACK64 -v "hello world" foo
>   getfattr -n security.SMACK64 foo
>   # file: foo
>   security.SMACK64="hello"
>
> EVM uses vfs_getxattr_alloc(), which directly reads xattr values from the file
> system. When performing the file system labeling with digital signatures, it is
> necessary to read real xattr values in order to generate the correct signatures.
>
> This patch adds the virtual "integrity." name space, which allows to bypass
> calling LSM and read real extended attribute values.
>
>   getfattr -e text -n integrity.SMACK64 foo
>   # file: foo
>   integrity.SMACK64="hello world"
>
> Suggested-by: Casey Schaufler <casey@schaufler-ca.com>
> Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
> ---
>  fs/xattr.c                 |   22 +++++++++++++++++++---
>  include/uapi/linux/xattr.h |    4 ++++
>  2 files changed, 23 insertions(+), 3 deletions(-)
>
> diff --git a/fs/xattr.c b/fs/xattr.c
> index 3377dff..76c2620 100644
> --- a/fs/xattr.c
> +++ b/fs/xattr.c
> @@ -232,12 +232,28 @@ vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size)
>  {
>         struct inode *inode = dentry->d_inode;
>         int error;
> +       char *usename = (char *)name, name_buf[XATTR_NAME_MAX];
> +
> +       /* because this function calls LSM for "security." namespace,
> +        * it may be impossible to get real value stored in xattr.
> +        * An LSM may mangle the attribute value to its own ends.
> +        * Smack is known to do this.
> +        * virtual namespace "integrity." is used to fetch real
> +        * security attributes without talking to LSM
> +        */
> +       if (!strncmp(name, XATTR_INTEGRITY_PREFIX,
> +                               XATTR_INTEGRITY_PREFIX_LEN)) {
> +               /* replace "integrity. with security. */
> +               snprintf(name_buf, sizeof(name_buf), "security.%s",
> +                        name + XATTR_INTEGRITY_PREFIX_LEN);
> +               usename = name_buf;
> +       }
>
> -       error = xattr_permission(inode, name, MAY_READ);
> +       error = xattr_permission(inode, usename, MAY_READ);
>         if (error)
>                 return error;
>
> -       error = security_inode_getxattr(dentry, name);
> +       error = security_inode_getxattr(dentry, usename);
>         if (error)
>                 return error;
>
> @@ -255,7 +271,7 @@ vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size)
>         }
>  nolsm:
>         if (inode->i_op->getxattr)
> -               error = inode->i_op->getxattr(dentry, name, value, size);
> +               error = inode->i_op->getxattr(dentry, usename, value, size);
>         else
>                 error = -EOPNOTSUPP;
>
> diff --git a/include/uapi/linux/xattr.h b/include/uapi/linux/xattr.h
> index 26607bd..133998b 100644
> --- a/include/uapi/linux/xattr.h
> +++ b/include/uapi/linux/xattr.h
> @@ -20,6 +20,10 @@
>  #define XATTR_SECURITY_PREFIX  "security."
>  #define XATTR_SECURITY_PREFIX_LEN (sizeof (XATTR_SECURITY_PREFIX) - 1)
>
> +/* integrity - security mirror namespace for integrity purpose */
> +#define XATTR_INTEGRITY_PREFIX "integrity."
> +#define XATTR_INTEGRITY_PREFIX_LEN (sizeof (XATTR_INTEGRITY_PREFIX) - 1)
> +
>  #define XATTR_SYSTEM_PREFIX "system."
>  #define XATTR_SYSTEM_PREFIX_LEN (sizeof (XATTR_SYSTEM_PREFIX) - 1)
>
> --
> 1.7.10.4
>

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RFC 1/1] xattr: provide integrity. namespace to read real values
  2013-02-13  9:07 [RFC 1/1] xattr: provide integrity. namespace to read real values Dmitry Kasatkin
  2013-02-14  7:48 ` Kasatkin, Dmitry
@ 2013-02-14 20:05 ` Vivek Goyal
  2013-02-25 12:25   ` Kasatkin, Dmitry
  1 sibling, 1 reply; 4+ messages in thread
From: Vivek Goyal @ 2013-02-14 20:05 UTC (permalink / raw)
  To: Dmitry Kasatkin
  Cc: linux-security-module, linux-kernel, casey, zohar, viro, linux-fsdevel

On Wed, Feb 13, 2013 at 11:07:49AM +0200, Dmitry Kasatkin wrote:
> User space tools use getxattr() system call to read values of extended
> attributes. getxattr() system call uses vfs_getattr(), which for "security."
> namespace might get a value of the xattr indirectly from LSM via calling
> xattr_getsecurity(). For that reason value set by setxattr and read by getxattr
> might differ.
> 
> Here is an example of SMACK label, which shows that set and read values are
> different:
> 
>   setfattr -n security.SMACK64 -v "hello world" foo
>   getfattr -n security.SMACK64 foo
>   # file: foo
>   security.SMACK64="hello"
> 
> EVM uses vfs_getxattr_alloc(), which directly reads xattr values from the file
> system. When performing the file system labeling with digital signatures, it is
> necessary to read real xattr values in order to generate the correct signatures.
> 
> This patch adds the virtual "integrity." name space, which allows to bypass
> calling LSM and read real extended attribute values.
> 
>   getfattr -e text -n integrity.SMACK64 foo
>   # file: foo
>   integrity.SMACK64="hello world"

Without knowing anything about xattr or LSM, to me it is odd that I
write an xattr using name "security.SMACK64" and read back the same
attribute using different name "integrity.SMACK64".

Thanks
Vivek

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RFC 1/1] xattr: provide integrity. namespace to read real values
  2013-02-14 20:05 ` Vivek Goyal
@ 2013-02-25 12:25   ` Kasatkin, Dmitry
  0 siblings, 0 replies; 4+ messages in thread
From: Kasatkin, Dmitry @ 2013-02-25 12:25 UTC (permalink / raw)
  To: Vivek Goyal
  Cc: linux-security-module, linux-kernel, casey, zohar, viro, linux-fsdevel

On Thu, Feb 14, 2013 at 9:05 PM, Vivek Goyal <vgoyal@redhat.com> wrote:
> On Wed, Feb 13, 2013 at 11:07:49AM +0200, Dmitry Kasatkin wrote:
>> User space tools use getxattr() system call to read values of extended
>> attributes. getxattr() system call uses vfs_getattr(), which for "security."
>> namespace might get a value of the xattr indirectly from LSM via calling
>> xattr_getsecurity(). For that reason value set by setxattr and read by getxattr
>> might differ.
>>
>> Here is an example of SMACK label, which shows that set and read values are
>> different:
>>
>>   setfattr -n security.SMACK64 -v "hello world" foo
>>   getfattr -n security.SMACK64 foo
>>   # file: foo
>>   security.SMACK64="hello"
>>
>> EVM uses vfs_getxattr_alloc(), which directly reads xattr values from the file
>> system. When performing the file system labeling with digital signatures, it is
>> necessary to read real xattr values in order to generate the correct signatures.
>>
>> This patch adds the virtual "integrity." name space, which allows to bypass
>> calling LSM and read real extended attribute values.
>>
>>   getfattr -e text -n integrity.SMACK64 foo
>>   # file: foo
>>   integrity.SMACK64="hello world"
>
> Without knowing anything about xattr or LSM, to me it is odd that I
> write an xattr using name "security.SMACK64" and read back the same
> attribute using different name "integrity.SMACK64".
>

It might sound like that, but writing and reading security attributes,
might give different results in security. namespace.
We cannot break userspace and change semantics of calls.
This is a trivial workaround which:
(1) does not to break userspace and
(2) does not require user space modifications.

Please suggest anything else?

- Dmitry

> Thanks
> Vivek

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2013-02-25 12:25 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-13  9:07 [RFC 1/1] xattr: provide integrity. namespace to read real values Dmitry Kasatkin
2013-02-14  7:48 ` Kasatkin, Dmitry
2013-02-14 20:05 ` Vivek Goyal
2013-02-25 12:25   ` Kasatkin, Dmitry

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).