* [RFC PATCH 1/4] security: modify security_inode_init_security to return an array of xattrs
2011-06-17 14:46 [RFC PATCH 0/4] security_inode_init_security API change Mimi Zohar
@ 2011-06-17 14:46 ` Mimi Zohar
2011-06-17 14:46 ` [RFC PATCH 2/4] evm: call evm_inode_init_security from security_inode_init_security Mimi Zohar
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Mimi Zohar @ 2011-06-17 14:46 UTC (permalink / raw)
To: linux-security-module
Cc: Mimi Zohar, linux-fsdevel, Dave Chinner, Steven Whitehouse,
Mimi Zohar
Option 1:
In preparation for supporting the initialization of multiple LSM xattrs
and the EVM xattr, this patch defines an xattr structure and changes the
security_inode_init_security() API to return an array of xattrs.
Until multiple LSM support is upstreamed, to avoid allocating/freeing the
xattr array, define the xattr array in the security_inode_init_security()
caller, not security_inode_init_security.
Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
---
fs/ext3/xattr_security.c | 33 ++++++++++++++++++++-------------
fs/ext4/xattr_security.c | 33 ++++++++++++++++++++-------------
include/linux/security.h | 10 +++++-----
include/linux/xattr.h | 6 ++++++
mm/shmem.c | 7 +++----
security/security.c | 17 +++++++++++++----
6 files changed, 67 insertions(+), 39 deletions(-)
diff --git a/fs/ext3/xattr_security.c b/fs/ext3/xattr_security.c
index b8d9f83..cb26a02 100644
--- a/fs/ext3/xattr_security.c
+++ b/fs/ext3/xattr_security.c
@@ -52,22 +52,29 @@ int
ext3_init_security(handle_t *handle, struct inode *inode, struct inode *dir,
const struct qstr *qstr)
{
+ struct xattr new_xattrs[MAX_LSM_XATTR + 1];
+ struct xattr *xattr_array = &new_xattrs[0], *xattr;
int err;
- size_t len;
- void *value;
- char *name;
- err = security_inode_init_security(inode, dir, qstr, &name, &value, &len);
- if (err) {
- if (err == -EOPNOTSUPP)
- return 0;
- return err;
+ memset(new_xattrs, 0, sizeof new_xattrs);
+ err = security_inode_init_security(inode, dir, qstr, &xattr_array);
+ if (err)
+ goto out;
+
+ for (xattr = new_xattrs; xattr->name != NULL; xattr++) {
+ err = ext3_xattr_set_handle(handle, inode,
+ EXT3_XATTR_INDEX_SECURITY,
+ xattr->name, xattr->value,
+ xattr->value_len, 0);
+ if (err < 0)
+ break;
+ }
+out:
+ for (xattr = new_xattrs; xattr->name != NULL; xattr++) {
+ kfree(xattr->value);
+ kfree(xattr->name);
}
- err = ext3_xattr_set_handle(handle, inode, EXT3_XATTR_INDEX_SECURITY,
- name, value, len, 0);
- kfree(name);
- kfree(value);
- return err;
+ return (err == -EOPNOTSUPP) ? 0 : err;
}
const struct xattr_handler ext3_xattr_security_handler = {
diff --git a/fs/ext4/xattr_security.c b/fs/ext4/xattr_security.c
index 007c3bf..ccf3347 100644
--- a/fs/ext4/xattr_security.c
+++ b/fs/ext4/xattr_security.c
@@ -52,22 +52,29 @@ int
ext4_init_security(handle_t *handle, struct inode *inode, struct inode *dir,
const struct qstr *qstr)
{
+ struct xattr new_xattrs[MAX_LSM_XATTR + 1];
+ struct xattr *xattr_array = &new_xattrs[0], *xattr;
int err;
- size_t len;
- void *value;
- char *name;
- err = security_inode_init_security(inode, dir, qstr, &name, &value, &len);
- if (err) {
- if (err == -EOPNOTSUPP)
- return 0;
- return err;
+ memset(new_xattrs, 0, sizeof new_xattrs);
+ err = security_inode_init_security(inode, dir, qstr, &xattr_array);
+ if (err)
+ goto out;
+
+ for (xattr = new_xattrs; xattr->name != NULL; xattr++) {
+ err = ext4_xattr_set_handle(handle, inode,
+ EXT4_XATTR_INDEX_SECURITY,
+ xattr->name, xattr->value,
+ xattr->value_len, 0);
+ if (err < 0)
+ break;
+ }
+out:
+ for (xattr = new_xattrs; xattr->name != NULL; xattr++) {
+ kfree(xattr->name);
+ kfree(xattr->value);
}
- err = ext4_xattr_set_handle(handle, inode, EXT4_XATTR_INDEX_SECURITY,
- name, value, len, 0);
- kfree(name);
- kfree(value);
- return err;
+ return (err == -EOPNOTSUPP) ? 0 : err;
}
const struct xattr_handler ext4_xattr_security_handler = {
diff --git a/include/linux/security.h b/include/linux/security.h
index 8ce59ef..bf593c1 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -36,10 +36,12 @@
#include <linux/key.h>
#include <linux/xfrm.h>
#include <linux/slab.h>
+#include <linux/xattr.h>
#include <net/flow.h>
/* Maximum number of letters for an LSM name string */
#define SECURITY_NAME_MAX 10
+#define MAX_LSM_XATTR 1
/* If capable should audit the security request */
#define SECURITY_CAP_NOAUDIT 0
@@ -1704,8 +1706,8 @@ int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts);
int security_inode_alloc(struct inode *inode);
void security_inode_free(struct inode *inode);
int security_inode_init_security(struct inode *inode, struct inode *dir,
- const struct qstr *qstr, char **name,
- void **value, size_t *len);
+ const struct qstr *qstr,
+ struct xattr **xattr_array);
int security_inode_create(struct inode *dir, struct dentry *dentry, int mode);
int security_inode_link(struct dentry *old_dentry, struct inode *dir,
struct dentry *new_dentry);
@@ -2035,9 +2037,7 @@ static inline void security_inode_free(struct inode *inode)
static inline int security_inode_init_security(struct inode *inode,
struct inode *dir,
const struct qstr *qstr,
- char **name,
- void **value,
- size_t *len)
+ struct xattr **xattr_array)
{
return -EOPNOTSUPP;
}
diff --git a/include/linux/xattr.h b/include/linux/xattr.h
index aed54c5..7a37866 100644
--- a/include/linux/xattr.h
+++ b/include/linux/xattr.h
@@ -67,6 +67,12 @@ struct xattr_handler {
size_t size, int flags, int handler_flags);
};
+struct xattr {
+ char *name;
+ void *value;
+ size_t value_len;
+};
+
ssize_t xattr_getsecurity(struct inode *, const char *, void *, size_t);
ssize_t vfs_getxattr(struct dentry *, const char *, void *, size_t);
ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size);
diff --git a/mm/shmem.c b/mm/shmem.c
index d221a1c..1d585b3 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1877,8 +1877,7 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
inode = shmem_get_inode(dir->i_sb, dir, mode, dev, VM_NORESERVE);
if (inode) {
error = security_inode_init_security(inode, dir,
- &dentry->d_name, NULL,
- NULL, NULL);
+ &dentry->d_name, NULL);
if (error) {
if (error != -EOPNOTSUPP) {
iput(inode);
@@ -2017,8 +2016,8 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s
if (!inode)
return -ENOSPC;
- error = security_inode_init_security(inode, dir, &dentry->d_name, NULL,
- NULL, NULL);
+ error = security_inode_init_security(inode, dir, &dentry->d_name,
+ NULL);
if (error) {
if (error != -EOPNOTSUPP) {
iput(inode);
diff --git a/security/security.c b/security/security.c
index 4ba6d4c..28842f2 100644
--- a/security/security.c
+++ b/security/security.c
@@ -339,13 +339,22 @@ void security_inode_free(struct inode *inode)
}
int security_inode_init_security(struct inode *inode, struct inode *dir,
- const struct qstr *qstr, char **name,
- void **value, size_t *len)
+ const struct qstr *qstr,
+ struct xattr **xattr_array)
{
+ struct xattr *lsm_xattr;
+
if (unlikely(IS_PRIVATE(inode)))
return -EOPNOTSUPP;
- return security_ops->inode_init_security(inode, dir, qstr, name, value,
- len);
+
+ if (!xattr_array)
+ return security_ops->inode_init_security(inode, dir, qstr,
+ NULL, NULL, NULL);
+ lsm_xattr = *xattr_array;
+ return security_ops->inode_init_security(inode, dir, qstr,
+ &lsm_xattr->name,
+ &lsm_xattr->value,
+ &lsm_xattr->value_len);
}
EXPORT_SYMBOL(security_inode_init_security);
--
1.7.3.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [RFC PATCH 2/4] evm: call evm_inode_init_security from security_inode_init_security
2011-06-17 14:46 [RFC PATCH 0/4] security_inode_init_security API change Mimi Zohar
2011-06-17 14:46 ` [RFC PATCH 1/4] security: modify security_inode_init_security to return an array of xattrs Mimi Zohar
@ 2011-06-17 14:46 ` Mimi Zohar
2011-06-17 14:46 ` [RFC PATCH 3/4] security: add security_inode_init_security function callback parameter Mimi Zohar
2011-06-17 14:47 ` [RFC PATCH 4/4] evm: call evm_inode_init_security from security_inode_init_security Mimi Zohar
3 siblings, 0 replies; 6+ messages in thread
From: Mimi Zohar @ 2011-06-17 14:46 UTC (permalink / raw)
To: linux-security-module
Cc: Mimi Zohar, linux-fsdevel, Dave Chinner, Steven Whitehouse,
Mimi Zohar
Option 1: security_inode_init_security returning xattr array
Changelog v7:
- moved the initialization call to security_inode_init_security,
renaming evm_inode_post_init_security to evm_inode_init_security
- increase size of xattr array for EVM xattr
Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
---
fs/ext4/xattr_security.c | 2 +-
include/linux/security.h | 2 +-
security/security.c | 15 ++++++++++-----
3 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/fs/ext4/xattr_security.c b/fs/ext4/xattr_security.c
index ccf3347..6b6a330 100644
--- a/fs/ext4/xattr_security.c
+++ b/fs/ext4/xattr_security.c
@@ -52,7 +52,7 @@ int
ext4_init_security(handle_t *handle, struct inode *inode, struct inode *dir,
const struct qstr *qstr)
{
- struct xattr new_xattrs[MAX_LSM_XATTR + 1];
+ struct xattr new_xattrs[MAX_LSM_EVM_XATTR + 1];
struct xattr *xattr_array = &new_xattrs[0], *xattr;
int err;
diff --git a/include/linux/security.h b/include/linux/security.h
index bf593c1..577fcf8 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -41,7 +41,7 @@
/* Maximum number of letters for an LSM name string */
#define SECURITY_NAME_MAX 10
-#define MAX_LSM_XATTR 1
+#define MAX_LSM_EVM_XATTR 2
/* If capable should audit the security request */
#define SECURITY_CAP_NOAUDIT 0
diff --git a/security/security.c b/security/security.c
index 2cfb7c9..f8f21c0 100644
--- a/security/security.c
+++ b/security/security.c
@@ -344,7 +344,8 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
const struct qstr *qstr,
struct xattr **xattr_array)
{
- struct xattr *lsm_xattr;
+ struct xattr *lsm_xattr, *evm_xattr;
+ int ret;
if (unlikely(IS_PRIVATE(inode)))
return -EOPNOTSUPP;
@@ -353,10 +354,14 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
return security_ops->inode_init_security(inode, dir, qstr,
NULL, NULL, NULL);
lsm_xattr = *xattr_array;
- return security_ops->inode_init_security(inode, dir, qstr,
- &lsm_xattr->name,
- &lsm_xattr->value,
- &lsm_xattr->value_len);
+ ret = security_ops->inode_init_security(inode, dir, qstr,
+ &lsm_xattr->name,
+ &lsm_xattr->value,
+ &lsm_xattr->value_len);
+ if (ret)
+ return ret;
+ evm_xattr = lsm_xattr + 1;
+ return evm_inode_init_security(inode, lsm_xattr, evm_xattr);
}
EXPORT_SYMBOL(security_inode_init_security);
--
1.7.3.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [RFC PATCH 3/4] security: add security_inode_init_security function callback parameter
2011-06-17 14:46 [RFC PATCH 0/4] security_inode_init_security API change Mimi Zohar
2011-06-17 14:46 ` [RFC PATCH 1/4] security: modify security_inode_init_security to return an array of xattrs Mimi Zohar
2011-06-17 14:46 ` [RFC PATCH 2/4] evm: call evm_inode_init_security from security_inode_init_security Mimi Zohar
@ 2011-06-17 14:46 ` Mimi Zohar
2011-06-20 11:21 ` Dmitry Kasatkin
2011-06-17 14:47 ` [RFC PATCH 4/4] evm: call evm_inode_init_security from security_inode_init_security Mimi Zohar
3 siblings, 1 reply; 6+ messages in thread
From: Mimi Zohar @ 2011-06-17 14:46 UTC (permalink / raw)
To: linux-security-module
Cc: Mimi Zohar, linux-fsdevel, Dave Chinner, Steven Whitehouse,
Mimi Zohar
Option 2:
In preparation for supporting the initialization of multiple LSM xattrs
and the EVM xattr, this patch defines an xattr structure and changes
the security_inode_init_security API, adding an fs specific function
callback parameter to write the xattrs.
Initially the callback function walks the array of xattrs, calling the
xattr 'set' function for each xattr. To optimize performance an FS could
replace this, with one that writes the multiple xattrs in a single 'set'
call.
Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
---
fs/ext3/xattr_security.c | 36 ++++++++++++++++++++----------------
fs/ext4/xattr_security.c | 36 ++++++++++++++++++++----------------
include/linux/security.h | 20 +++++++++++++++-----
include/linux/xattr.h | 6 ++++++
mm/shmem.c | 4 ++--
security/security.c | 36 +++++++++++++++++++++++++++++++-----
6 files changed, 94 insertions(+), 44 deletions(-)
diff --git a/fs/ext3/xattr_security.c b/fs/ext3/xattr_security.c
index b8d9f83..1ceaad6d 100644
--- a/fs/ext3/xattr_security.c
+++ b/fs/ext3/xattr_security.c
@@ -48,26 +48,30 @@ ext3_xattr_security_set(struct dentry *dentry, const char *name,
name, value, size, flags);
}
+int ext3_initxattrs(struct inode *inode, struct xattr *xattr_array, int flag,
+ void *fs_info)
+{
+ handle_t *handle = fs_info;
+ struct xattr *xattr;
+ int err = 0;
+
+ for (xattr = xattr_array; xattr->name != NULL; xattr++) {
+ err = ext3_xattr_set_handle(handle, inode,
+ EXT3_XATTR_INDEX_SECURITY,
+ xattr->name, xattr->value,
+ xattr->value_len, 0);
+ if (err < 0)
+ break;
+ }
+ return err;
+}
+
int
ext3_init_security(handle_t *handle, struct inode *inode, struct inode *dir,
const struct qstr *qstr)
{
- int err;
- size_t len;
- void *value;
- char *name;
-
- err = security_inode_init_security(inode, dir, qstr, &name, &value, &len);
- if (err) {
- if (err == -EOPNOTSUPP)
- return 0;
- return err;
- }
- err = ext3_xattr_set_handle(handle, inode, EXT3_XATTR_INDEX_SECURITY,
- name, value, len, 0);
- kfree(name);
- kfree(value);
- return err;
+ return security_inode_init_security(inode, dir, qstr,
+ &ext3_initxattrs, handle);
}
const struct xattr_handler ext3_xattr_security_handler = {
diff --git a/fs/ext4/xattr_security.c b/fs/ext4/xattr_security.c
index 007c3bf..3a97aaa 100644
--- a/fs/ext4/xattr_security.c
+++ b/fs/ext4/xattr_security.c
@@ -48,26 +48,30 @@ ext4_xattr_security_set(struct dentry *dentry, const char *name,
name, value, size, flags);
}
+int ext4_initxattrs(struct inode *inode, struct xattr *xattr_array, int flag,
+ void *fs_info)
+{
+ handle_t *handle = fs_info;
+ struct xattr *xattr;
+ int err = 0;
+
+ for (xattr = xattr_array; xattr->name != NULL; xattr++) {
+ err = ext4_xattr_set_handle(handle, inode,
+ EXT4_XATTR_INDEX_SECURITY,
+ xattr->name, xattr->value,
+ xattr->value_len, 0);
+ if (err < 0)
+ break;
+ }
+ return err;
+}
+
int
ext4_init_security(handle_t *handle, struct inode *inode, struct inode *dir,
const struct qstr *qstr)
{
- int err;
- size_t len;
- void *value;
- char *name;
-
- err = security_inode_init_security(inode, dir, qstr, &name, &value, &len);
- if (err) {
- if (err == -EOPNOTSUPP)
- return 0;
- return err;
- }
- err = ext4_xattr_set_handle(handle, inode, EXT4_XATTR_INDEX_SECURITY,
- name, value, len, 0);
- kfree(name);
- kfree(value);
- return err;
+ return security_inode_init_security(inode, dir, qstr,
+ &ext4_initxattrs, handle);
}
const struct xattr_handler ext4_xattr_security_handler = {
diff --git a/include/linux/security.h b/include/linux/security.h
index 8ce59ef..92cbf8d 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -36,6 +36,7 @@
#include <linux/key.h>
#include <linux/xfrm.h>
#include <linux/slab.h>
+#include <linux/xattr.h>
#include <net/flow.h>
/* Maximum number of letters for an LSM name string */
@@ -1704,8 +1705,12 @@ int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts);
int security_inode_alloc(struct inode *inode);
void security_inode_free(struct inode *inode);
int security_inode_init_security(struct inode *inode, struct inode *dir,
- const struct qstr *qstr, char **name,
- void **value, size_t *len);
+ const struct qstr *qstr,
+ int (*initxattrs) (struct inode *inode,
+ struct xattr *xattr_array, int flag,
+ void *fs_data),
+ void *fs_data
+ );
int security_inode_create(struct inode *dir, struct dentry *dentry, int mode);
int security_inode_link(struct dentry *old_dentry, struct inode *dir,
struct dentry *new_dentry);
@@ -2035,9 +2040,14 @@ static inline void security_inode_free(struct inode *inode)
static inline int security_inode_init_security(struct inode *inode,
struct inode *dir,
const struct qstr *qstr,
- char **name,
- void **value,
- size_t *len)
+ struct xattr **xattr_array)
+ int (*initxattrs)
+ (struct inode *inode,
+ struct xattr *xattr_array,
+ int flag,
+ void *fs_data),
+ void *fs_data
+ );
{
return -EOPNOTSUPP;
}
diff --git a/include/linux/xattr.h b/include/linux/xattr.h
index aed54c5..7a37866 100644
--- a/include/linux/xattr.h
+++ b/include/linux/xattr.h
@@ -67,6 +67,12 @@ struct xattr_handler {
size_t size, int flags, int handler_flags);
};
+struct xattr {
+ char *name;
+ void *value;
+ size_t value_len;
+};
+
ssize_t xattr_getsecurity(struct inode *, const char *, void *, size_t);
ssize_t vfs_getxattr(struct dentry *, const char *, void *, size_t);
ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size);
diff --git a/mm/shmem.c b/mm/shmem.c
index d221a1c..518f27c 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1877,7 +1877,7 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
inode = shmem_get_inode(dir->i_sb, dir, mode, dev, VM_NORESERVE);
if (inode) {
error = security_inode_init_security(inode, dir,
- &dentry->d_name, NULL,
+ &dentry->d_name,
NULL, NULL);
if (error) {
if (error != -EOPNOTSUPP) {
@@ -2017,7 +2017,7 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s
if (!inode)
return -ENOSPC;
- error = security_inode_init_security(inode, dir, &dentry->d_name, NULL,
+ error = security_inode_init_security(inode, dir, &dentry->d_name,
NULL, NULL);
if (error) {
if (error != -EOPNOTSUPP) {
diff --git a/security/security.c b/security/security.c
index 4ba6d4c..c1ad1d2 100644
--- a/security/security.c
+++ b/security/security.c
@@ -18,6 +18,8 @@
#include <linux/security.h>
#include <linux/ima.h>
+#define MAX_LSM_XATTR 1
+
/* Boot-time LSM user choice */
static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] =
CONFIG_DEFAULT_SECURITY;
@@ -339,13 +341,37 @@ void security_inode_free(struct inode *inode)
}
int security_inode_init_security(struct inode *inode, struct inode *dir,
- const struct qstr *qstr, char **name,
- void **value, size_t *len)
-{
+ const struct qstr *qstr,
+ int (*initxattrs) (struct inode *inode,
+ struct xattr *xattr_array, int flag,
+ void *fs_data),
+ void *fs_data
+ )
+{
+ struct xattr new_xattrs[MAX_LSM_XATTR + 1];
+ struct xattr *lsm_xattr;
+ int ret;
+
if (unlikely(IS_PRIVATE(inode)))
return -EOPNOTSUPP;
- return security_ops->inode_init_security(inode, dir, qstr, name, value,
- len);
+
+ memset(new_xattrs, 0, sizeof new_xattrs);
+ if (!initxattrs)
+ return security_ops->inode_init_security(inode, dir, qstr,
+ NULL, NULL, NULL);
+ lsm_xattr = new_xattrs;
+ ret = security_ops->inode_init_security(inode, dir, qstr,
+ &lsm_xattr->name,
+ &lsm_xattr->value,
+ &lsm_xattr->value_len);
+ if (ret)
+ goto out;
+ ret = initxattrs(inode, new_xattrs, 0, fs_data);
+out:
+ kfree(lsm_xattr->name);
+ kfree(lsm_xattr->value);
+
+ return (ret == -EOPNOTSUPP) ? 0 : ret;
}
EXPORT_SYMBOL(security_inode_init_security);
--
1.7.3.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [RFC PATCH 3/4] security: add security_inode_init_security function callback parameter
2011-06-17 14:46 ` [RFC PATCH 3/4] security: add security_inode_init_security function callback parameter Mimi Zohar
@ 2011-06-20 11:21 ` Dmitry Kasatkin
0 siblings, 0 replies; 6+ messages in thread
From: Dmitry Kasatkin @ 2011-06-20 11:21 UTC (permalink / raw)
To: Mimi Zohar
Cc: linux-security-module, linux-fsdevel, Dave Chinner,
Steven Whitehouse, Mimi Zohar
On 17/06/11 17:46, Mimi Zohar wrote:
> Option 2:
>
> In preparation for supporting the initialization of multiple LSM xattrs
> and the EVM xattr, this patch defines an xattr structure and changes
> the security_inode_init_security API, adding an fs specific function
> callback parameter to write the xattrs.
>
> Initially the callback function walks the array of xattrs, calling the
> xattr 'set' function for each xattr. To optimize performance an FS could
> replace this, with one that writes the multiple xattrs in a single 'set'
> call.
>
> Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
> ---
> fs/ext3/xattr_security.c | 36 ++++++++++++++++++++----------------
> fs/ext4/xattr_security.c | 36 ++++++++++++++++++++----------------
> include/linux/security.h | 20 +++++++++++++++-----
> include/linux/xattr.h | 6 ++++++
> mm/shmem.c | 4 ++--
> security/security.c | 36 +++++++++++++++++++++++++++++++-----
> 6 files changed, 94 insertions(+), 44 deletions(-)
>
> diff --git a/fs/ext3/xattr_security.c b/fs/ext3/xattr_security.c
> index b8d9f83..1ceaad6d 100644
> --- a/fs/ext3/xattr_security.c
> +++ b/fs/ext3/xattr_security.c
> @@ -48,26 +48,30 @@ ext3_xattr_security_set(struct dentry *dentry, const char *name,
> name, value, size, flags);
> }
>
> +int ext3_initxattrs(struct inode *inode, struct xattr *xattr_array, int flag,
> + void *fs_info)
> +{
> + handle_t *handle = fs_info;
> + struct xattr *xattr;
> + int err = 0;
> +
> + for (xattr = xattr_array; xattr->name != NULL; xattr++) {
> + err = ext3_xattr_set_handle(handle, inode,
> + EXT3_XATTR_INDEX_SECURITY,
> + xattr->name, xattr->value,
> + xattr->value_len, 0);
> + if (err < 0)
> + break;
> + }
> + return err;
> +}
> +
> int
> ext3_init_security(handle_t *handle, struct inode *inode, struct inode *dir,
> const struct qstr *qstr)
> {
> - int err;
> - size_t len;
> - void *value;
> - char *name;
> -
> - err = security_inode_init_security(inode, dir, qstr, &name, &value, &len);
> - if (err) {
> - if (err == -EOPNOTSUPP)
> - return 0;
> - return err;
> - }
> - err = ext3_xattr_set_handle(handle, inode, EXT3_XATTR_INDEX_SECURITY,
> - name, value, len, 0);
> - kfree(name);
> - kfree(value);
> - return err;
> + return security_inode_init_security(inode, dir, qstr,
> + &ext3_initxattrs, handle);
> }
>
> const struct xattr_handler ext3_xattr_security_handler = {
> diff --git a/fs/ext4/xattr_security.c b/fs/ext4/xattr_security.c
> index 007c3bf..3a97aaa 100644
> --- a/fs/ext4/xattr_security.c
> +++ b/fs/ext4/xattr_security.c
> @@ -48,26 +48,30 @@ ext4_xattr_security_set(struct dentry *dentry, const char *name,
> name, value, size, flags);
> }
>
> +int ext4_initxattrs(struct inode *inode, struct xattr *xattr_array, int flag,
> + void *fs_info)
> +{
> + handle_t *handle = fs_info;
> + struct xattr *xattr;
> + int err = 0;
> +
> + for (xattr = xattr_array; xattr->name != NULL; xattr++) {
> + err = ext4_xattr_set_handle(handle, inode,
> + EXT4_XATTR_INDEX_SECURITY,
> + xattr->name, xattr->value,
> + xattr->value_len, 0);
> + if (err < 0)
> + break;
> + }
> + return err;
> +}
> +
> int
> ext4_init_security(handle_t *handle, struct inode *inode, struct inode *dir,
> const struct qstr *qstr)
> {
> - int err;
> - size_t len;
> - void *value;
> - char *name;
> -
> - err = security_inode_init_security(inode, dir, qstr, &name, &value, &len);
> - if (err) {
> - if (err == -EOPNOTSUPP)
> - return 0;
> - return err;
> - }
> - err = ext4_xattr_set_handle(handle, inode, EXT4_XATTR_INDEX_SECURITY,
> - name, value, len, 0);
> - kfree(name);
> - kfree(value);
> - return err;
> + return security_inode_init_security(inode, dir, qstr,
> + &ext4_initxattrs, handle);
> }
>
> const struct xattr_handler ext4_xattr_security_handler = {
> diff --git a/include/linux/security.h b/include/linux/security.h
> index 8ce59ef..92cbf8d 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -36,6 +36,7 @@
> #include <linux/key.h>
> #include <linux/xfrm.h>
> #include <linux/slab.h>
> +#include <linux/xattr.h>
> #include <net/flow.h>
>
> /* Maximum number of letters for an LSM name string */
> @@ -1704,8 +1705,12 @@ int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts);
> int security_inode_alloc(struct inode *inode);
> void security_inode_free(struct inode *inode);
> int security_inode_init_security(struct inode *inode, struct inode *dir,
> - const struct qstr *qstr, char **name,
> - void **value, size_t *len);
> + const struct qstr *qstr,
> + int (*initxattrs) (struct inode *inode,
> + struct xattr *xattr_array, int flag,
> + void *fs_data),
> + void *fs_data
> + );
> int security_inode_create(struct inode *dir, struct dentry *dentry, int mode);
> int security_inode_link(struct dentry *old_dentry, struct inode *dir,
> struct dentry *new_dentry);
> @@ -2035,9 +2040,14 @@ static inline void security_inode_free(struct inode *inode)
> static inline int security_inode_init_security(struct inode *inode,
> struct inode *dir,
> const struct qstr *qstr,
> - char **name,
> - void **value,
> - size_t *len)
> + struct xattr **xattr_array)
> + int (*initxattrs)
> + (struct inode *inode,
> + struct xattr *xattr_array,
> + int flag,
> + void *fs_data),
> + void *fs_data
> + );
> {
> return -EOPNOTSUPP;
> }
> diff --git a/include/linux/xattr.h b/include/linux/xattr.h
> index aed54c5..7a37866 100644
> --- a/include/linux/xattr.h
> +++ b/include/linux/xattr.h
> @@ -67,6 +67,12 @@ struct xattr_handler {
> size_t size, int flags, int handler_flags);
> };
>
> +struct xattr {
> + char *name;
> + void *value;
> + size_t value_len;
> +};
> +
> ssize_t xattr_getsecurity(struct inode *, const char *, void *, size_t);
> ssize_t vfs_getxattr(struct dentry *, const char *, void *, size_t);
> ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size);
> diff --git a/mm/shmem.c b/mm/shmem.c
> index d221a1c..518f27c 100644
> --- a/mm/shmem.c
> +++ b/mm/shmem.c
> @@ -1877,7 +1877,7 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
> inode = shmem_get_inode(dir->i_sb, dir, mode, dev, VM_NORESERVE);
> if (inode) {
> error = security_inode_init_security(inode, dir,
> - &dentry->d_name, NULL,
> + &dentry->d_name,
> NULL, NULL);
> if (error) {
> if (error != -EOPNOTSUPP) {
> @@ -2017,7 +2017,7 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s
> if (!inode)
> return -ENOSPC;
>
> - error = security_inode_init_security(inode, dir, &dentry->d_name, NULL,
> + error = security_inode_init_security(inode, dir, &dentry->d_name,
> NULL, NULL);
> if (error) {
> if (error != -EOPNOTSUPP) {
> diff --git a/security/security.c b/security/security.c
> index 4ba6d4c..c1ad1d2 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -18,6 +18,8 @@
> #include <linux/security.h>
> #include <linux/ima.h>
>
> +#define MAX_LSM_XATTR 1
> +
> /* Boot-time LSM user choice */
> static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] =
> CONFIG_DEFAULT_SECURITY;
> @@ -339,13 +341,37 @@ void security_inode_free(struct inode *inode)
> }
>
> int security_inode_init_security(struct inode *inode, struct inode *dir,
> - const struct qstr *qstr, char **name,
> - void **value, size_t *len)
> -{
> + const struct qstr *qstr,
> + int (*initxattrs) (struct inode *inode,
> + struct xattr *xattr_array, int flag,
> + void *fs_data),
> + void *fs_data
> + )
> +{
> + struct xattr new_xattrs[MAX_LSM_XATTR + 1];
> + struct xattr *lsm_xattr;
> + int ret;
> +
> if (unlikely(IS_PRIVATE(inode)))
> return -EOPNOTSUPP;
> - return security_ops->inode_init_security(inode, dir, qstr, name, value,
> - len);
> +
> + memset(new_xattrs, 0, sizeof new_xattrs);
> + if (!initxattrs)
> + return security_ops->inode_init_security(inode, dir, qstr,
> + NULL, NULL, NULL);
> + lsm_xattr = new_xattrs;
> + ret = security_ops->inode_init_security(inode, dir, qstr,
> + &lsm_xattr->name,
> + &lsm_xattr->value,
> + &lsm_xattr->value_len);
> + if (ret)
> + goto out;
> + ret = initxattrs(inode, new_xattrs, 0, fs_data);
> +out:
> + kfree(lsm_xattr->name);
> + kfree(lsm_xattr->value);
> +
> + return (ret == -EOPNOTSUPP) ? 0 : ret;
> }
> EXPORT_SYMBOL(security_inode_init_security);
>
Hi,
Option 1 and 2 are about the same - both use xattr array approach and
change API.
But callback option looks as cleaner approach to me, because it provides
a function which is used to set multiple xattrs...
- Dmitry
^ permalink raw reply [flat|nested] 6+ messages in thread
* [RFC PATCH 4/4] evm: call evm_inode_init_security from security_inode_init_security
2011-06-17 14:46 [RFC PATCH 0/4] security_inode_init_security API change Mimi Zohar
` (2 preceding siblings ...)
2011-06-17 14:46 ` [RFC PATCH 3/4] security: add security_inode_init_security function callback parameter Mimi Zohar
@ 2011-06-17 14:47 ` Mimi Zohar
3 siblings, 0 replies; 6+ messages in thread
From: Mimi Zohar @ 2011-06-17 14:47 UTC (permalink / raw)
To: linux-security-module
Cc: Mimi Zohar, linux-fsdevel, Dave Chinner, Steven Whitehouse,
Mimi Zohar
Option 2: security_inode_init_security function callback parameter
Changelog v7:
- moved the EVM xattr initialization call to security_inode_init_security,
renaming evm_inode_post_init_security to evm_inode_init_security
- increase size of xattr array for EVM xattr
Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
---
security/security.c | 17 +++++++++++------
1 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/security/security.c b/security/security.c
index b4b997d..0480fb2 100644
--- a/security/security.c
+++ b/security/security.c
@@ -20,7 +20,7 @@
#include <linux/ima.h>
#include <linux/evm.h>
-#define MAX_LSM_XATTR 1
+#define MAX_LSM_EVM_XATTR 2
/* Boot-time LSM user choice */
static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] =
@@ -350,8 +350,8 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
void *fs_data
)
{
- struct xattr new_xattrs[MAX_LSM_XATTR + 1];
- struct xattr *lsm_xattr;
+ struct xattr new_xattrs[MAX_LSM_EVM_XATTR + 1];
+ struct xattr *lsm_xattr, *evm_xattr, *xattr;
int ret;
if (unlikely(IS_PRIVATE(inode)))
@@ -368,11 +368,16 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
&lsm_xattr->value_len);
if (ret)
goto out;
+ evm_xattr = lsm_xattr + 1;
+ ret = evm_inode_init_security(inode, lsm_xattr, evm_xattr);
+ if (ret)
+ goto out;
ret = initxattrs(inode, new_xattrs, 0, fs_data);
out:
- kfree(lsm_xattr->name);
- kfree(lsm_xattr->value);
-
+ for (xattr = new_xattrs; xattr->name != NULL; xattr++) {
+ kfree(xattr->name);
+ kfree(xattr->value);
+ }
return (ret == -EOPNOTSUPP) ? 0 : ret;
}
EXPORT_SYMBOL(security_inode_init_security);
--
1.7.3.4
^ permalink raw reply related [flat|nested] 6+ messages in thread