Commit 5d6c3191 authored by Andreas Gruenbacher's avatar Andreas Gruenbacher Committed by Al Viro

xattr: Add __vfs_{get,set,remove}xattr helpers

Right now, various places in the kernel check for the existence of
getxattr, setxattr, and removexattr inode operations and directly call
those operations.  Switch to helper functions and test for the IOP_XATTR
flag instead.
Signed-off-by: default avatarAndreas Gruenbacher <agruenba@redhat.com>
Acked-by: default avatarJames Morris <james.l.morris@oracle.com>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent f5c24438
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/mount.h> #include <linux/mount.h>
#include <linux/statfs.h> #include <linux/statfs.h>
#include <linux/ctype.h> #include <linux/ctype.h>
#include <linux/xattr.h>
#include "internal.h" #include "internal.h"
static int cachefiles_daemon_add_cache(struct cachefiles_cache *caches); static int cachefiles_daemon_add_cache(struct cachefiles_cache *caches);
...@@ -126,8 +127,7 @@ static int cachefiles_daemon_add_cache(struct cachefiles_cache *cache) ...@@ -126,8 +127,7 @@ static int cachefiles_daemon_add_cache(struct cachefiles_cache *cache)
if (d_is_negative(root) || if (d_is_negative(root) ||
!d_backing_inode(root)->i_op->lookup || !d_backing_inode(root)->i_op->lookup ||
!d_backing_inode(root)->i_op->mkdir || !d_backing_inode(root)->i_op->mkdir ||
!d_backing_inode(root)->i_op->setxattr || !(d_backing_inode(root)->i_opflags & IOP_XATTR) ||
!d_backing_inode(root)->i_op->getxattr ||
!root->d_sb->s_op->statfs || !root->d_sb->s_op->statfs ||
!root->d_sb->s_op->sync_fs) !root->d_sb->s_op->sync_fs)
goto error_unsupported; goto error_unsupported;
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/namei.h> #include <linux/namei.h>
#include <linux/security.h> #include <linux/security.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/xattr.h>
#include "internal.h" #include "internal.h"
#define CACHEFILES_KEYBUF_SIZE 512 #define CACHEFILES_KEYBUF_SIZE 512
...@@ -799,8 +800,7 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache, ...@@ -799,8 +800,7 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
} }
ret = -EPERM; ret = -EPERM;
if (!d_backing_inode(subdir)->i_op->setxattr || if (!(d_backing_inode(subdir)->i_opflags & IOP_XATTR) ||
!d_backing_inode(subdir)->i_op->getxattr ||
!d_backing_inode(subdir)->i_op->lookup || !d_backing_inode(subdir)->i_op->lookup ||
!d_backing_inode(subdir)->i_op->mkdir || !d_backing_inode(subdir)->i_op->mkdir ||
!d_backing_inode(subdir)->i_op->create || !d_backing_inode(subdir)->i_op->create ||
......
...@@ -1005,15 +1005,14 @@ ecryptfs_setxattr(struct dentry *dentry, struct inode *inode, ...@@ -1005,15 +1005,14 @@ ecryptfs_setxattr(struct dentry *dentry, struct inode *inode,
const char *name, const void *value, const char *name, const void *value,
size_t size, int flags) size_t size, int flags)
{ {
int rc = 0; int rc;
struct dentry *lower_dentry; struct dentry *lower_dentry;
lower_dentry = ecryptfs_dentry_to_lower(dentry); lower_dentry = ecryptfs_dentry_to_lower(dentry);
if (!d_inode(lower_dentry)->i_op->setxattr) { if (!(d_inode(lower_dentry)->i_opflags & IOP_XATTR)) {
rc = -EOPNOTSUPP; rc = -EOPNOTSUPP;
goto out; goto out;
} }
rc = vfs_setxattr(lower_dentry, name, value, size, flags); rc = vfs_setxattr(lower_dentry, name, value, size, flags);
if (!rc && inode) if (!rc && inode)
fsstack_copy_attr_all(inode, d_inode(lower_dentry)); fsstack_copy_attr_all(inode, d_inode(lower_dentry));
...@@ -1025,15 +1024,14 @@ ssize_t ...@@ -1025,15 +1024,14 @@ ssize_t
ecryptfs_getxattr_lower(struct dentry *lower_dentry, struct inode *lower_inode, ecryptfs_getxattr_lower(struct dentry *lower_dentry, struct inode *lower_inode,
const char *name, void *value, size_t size) const char *name, void *value, size_t size)
{ {
int rc = 0; int rc;
if (!lower_inode->i_op->getxattr) { if (!(lower_inode->i_opflags & IOP_XATTR)) {
rc = -EOPNOTSUPP; rc = -EOPNOTSUPP;
goto out; goto out;
} }
inode_lock(lower_inode); inode_lock(lower_inode);
rc = lower_inode->i_op->getxattr(lower_dentry, lower_inode, rc = __vfs_getxattr(lower_dentry, lower_inode, name, value, size);
name, value, size);
inode_unlock(lower_inode); inode_unlock(lower_inode);
out: out:
return rc; return rc;
...@@ -1069,18 +1067,18 @@ ecryptfs_listxattr(struct dentry *dentry, char *list, size_t size) ...@@ -1069,18 +1067,18 @@ ecryptfs_listxattr(struct dentry *dentry, char *list, size_t size)
static int ecryptfs_removexattr(struct dentry *dentry, struct inode *inode, static int ecryptfs_removexattr(struct dentry *dentry, struct inode *inode,
const char *name) const char *name)
{ {
int rc = 0; int rc;
struct dentry *lower_dentry; struct dentry *lower_dentry;
struct inode *lower_inode; struct inode *lower_inode;
lower_dentry = ecryptfs_dentry_to_lower(dentry); lower_dentry = ecryptfs_dentry_to_lower(dentry);
lower_inode = ecryptfs_inode_to_lower(inode); lower_inode = ecryptfs_inode_to_lower(inode);
if (!lower_inode->i_op->removexattr) { if (!(lower_inode->i_opflags & IOP_XATTR)) {
rc = -EOPNOTSUPP; rc = -EOPNOTSUPP;
goto out; goto out;
} }
inode_lock(lower_inode); inode_lock(lower_inode);
rc = lower_inode->i_op->removexattr(lower_dentry, name); rc = __vfs_removexattr(lower_dentry, name);
inode_unlock(lower_inode); inode_unlock(lower_inode);
out: out:
return rc; return rc;
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <linux/file.h> #include <linux/file.h>
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/xattr.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include "ecryptfs_kernel.h" #include "ecryptfs_kernel.h"
...@@ -422,7 +423,7 @@ static int ecryptfs_write_inode_size_to_xattr(struct inode *ecryptfs_inode) ...@@ -422,7 +423,7 @@ static int ecryptfs_write_inode_size_to_xattr(struct inode *ecryptfs_inode)
struct inode *lower_inode = d_inode(lower_dentry); struct inode *lower_inode = d_inode(lower_dentry);
int rc; int rc;
if (!lower_inode->i_op->getxattr || !lower_inode->i_op->setxattr) { if (!(lower_inode->i_opflags & IOP_XATTR)) {
printk(KERN_WARNING printk(KERN_WARNING
"No support for setting xattr in lower filesystem\n"); "No support for setting xattr in lower filesystem\n");
rc = -ENOSYS; rc = -ENOSYS;
...@@ -436,15 +437,13 @@ static int ecryptfs_write_inode_size_to_xattr(struct inode *ecryptfs_inode) ...@@ -436,15 +437,13 @@ static int ecryptfs_write_inode_size_to_xattr(struct inode *ecryptfs_inode)
goto out; goto out;
} }
inode_lock(lower_inode); inode_lock(lower_inode);
size = lower_inode->i_op->getxattr(lower_dentry, lower_inode, size = __vfs_getxattr(lower_dentry, lower_inode, ECRYPTFS_XATTR_NAME,
ECRYPTFS_XATTR_NAME, xattr_virt, PAGE_SIZE);
xattr_virt, PAGE_SIZE);
if (size < 0) if (size < 0)
size = 8; size = 8;
put_unaligned_be64(i_size_read(ecryptfs_inode), xattr_virt); put_unaligned_be64(i_size_read(ecryptfs_inode), xattr_virt);
rc = lower_inode->i_op->setxattr(lower_dentry, lower_inode, rc = __vfs_setxattr(lower_dentry, lower_inode, ECRYPTFS_XATTR_NAME,
ECRYPTFS_XATTR_NAME, xattr_virt, size, 0);
xattr_virt, size, 0);
inode_unlock(lower_inode); inode_unlock(lower_inode);
if (rc) if (rc)
printk(KERN_ERR "Error whilst attempting to write inode size " printk(KERN_ERR "Error whilst attempting to write inode size "
......
...@@ -58,8 +58,8 @@ int ovl_copy_xattr(struct dentry *old, struct dentry *new) ...@@ -58,8 +58,8 @@ int ovl_copy_xattr(struct dentry *old, struct dentry *new)
char *buf, *name, *value = NULL; char *buf, *name, *value = NULL;
int uninitialized_var(error); int uninitialized_var(error);
if (!old->d_inode->i_op->getxattr || if (!(old->d_inode->i_opflags & IOP_XATTR) ||
!new->d_inode->i_op->getxattr) !(new->d_inode->i_opflags & IOP_XATTR))
return 0; return 0;
list_size = vfs_listxattr(old, NULL, 0); list_size = vfs_listxattr(old, NULL, 0);
......
...@@ -275,10 +275,10 @@ static bool ovl_is_opaquedir(struct dentry *dentry) ...@@ -275,10 +275,10 @@ static bool ovl_is_opaquedir(struct dentry *dentry)
char val; char val;
struct inode *inode = dentry->d_inode; struct inode *inode = dentry->d_inode;
if (!S_ISDIR(inode->i_mode) || !inode->i_op->getxattr) if (!S_ISDIR(inode->i_mode) || !(inode->i_opflags & IOP_XATTR))
return false; return false;
res = inode->i_op->getxattr(dentry, inode, OVL_XATTR_OPAQUE, &val, 1); res = __vfs_getxattr(dentry, inode, OVL_XATTR_OPAQUE, &val, 1);
if (res == 1 && val == 'y') if (res == 1 && val == 'y')
return true; return true;
......
...@@ -136,6 +136,16 @@ xattr_permission(struct inode *inode, const char *name, int mask) ...@@ -136,6 +136,16 @@ xattr_permission(struct inode *inode, const char *name, int mask)
return inode_permission(inode, mask); return inode_permission(inode, mask);
} }
int
__vfs_setxattr(struct dentry *dentry, struct inode *inode, const char *name,
const void *value, size_t size, int flags)
{
if (!inode->i_op->setxattr)
return -EOPNOTSUPP;
return inode->i_op->setxattr(dentry, inode, name, value, size, flags);
}
EXPORT_SYMBOL(__vfs_setxattr);
/** /**
* __vfs_setxattr_noperm - perform setxattr operation without performing * __vfs_setxattr_noperm - perform setxattr operation without performing
* permission checks. * permission checks.
...@@ -163,7 +173,7 @@ int __vfs_setxattr_noperm(struct dentry *dentry, const char *name, ...@@ -163,7 +173,7 @@ int __vfs_setxattr_noperm(struct dentry *dentry, const char *name,
if (issec) if (issec)
inode->i_flags &= ~S_NOSEC; inode->i_flags &= ~S_NOSEC;
if (inode->i_op->setxattr) { if (inode->i_op->setxattr) {
error = inode->i_op->setxattr(dentry, inode, name, value, size, flags); error = __vfs_setxattr(dentry, inode, name, value, size, flags);
if (!error) { if (!error) {
fsnotify_xattr(dentry); fsnotify_xattr(dentry);
security_inode_post_setxattr(dentry, name, value, security_inode_post_setxattr(dentry, name, value,
...@@ -274,6 +284,16 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value, ...@@ -274,6 +284,16 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value,
return error; return error;
} }
ssize_t
__vfs_getxattr(struct dentry *dentry, struct inode *inode, const char *name,
void *value, size_t size)
{
if (!inode->i_op->getxattr)
return -EOPNOTSUPP;
return inode->i_op->getxattr(dentry, inode, name, value, size);
}
EXPORT_SYMBOL(__vfs_getxattr);
ssize_t ssize_t
vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size) vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size)
{ {
...@@ -301,13 +321,7 @@ vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size) ...@@ -301,13 +321,7 @@ vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size)
return ret; return ret;
} }
nolsm: nolsm:
if (inode->i_op->getxattr) return __vfs_getxattr(dentry, inode, name, value, size);
error = inode->i_op->getxattr(dentry, inode, name, value, size);
else
error = -EOPNOTSUPP;
return error;
} }
EXPORT_SYMBOL_GPL(vfs_getxattr); EXPORT_SYMBOL_GPL(vfs_getxattr);
...@@ -332,13 +346,21 @@ vfs_listxattr(struct dentry *d, char *list, size_t size) ...@@ -332,13 +346,21 @@ vfs_listxattr(struct dentry *d, char *list, size_t size)
EXPORT_SYMBOL_GPL(vfs_listxattr); EXPORT_SYMBOL_GPL(vfs_listxattr);
int int
vfs_removexattr(struct dentry *dentry, const char *name) __vfs_removexattr(struct dentry *dentry, const char *name)
{ {
struct inode *inode = dentry->d_inode; struct inode *inode = dentry->d_inode;
int error;
if (!inode->i_op->removexattr) if (!inode->i_op->removexattr)
return -EOPNOTSUPP; return -EOPNOTSUPP;
return inode->i_op->removexattr(dentry, name);
}
EXPORT_SYMBOL(__vfs_removexattr);
int
vfs_removexattr(struct dentry *dentry, const char *name)
{
struct inode *inode = dentry->d_inode;
int error;
error = xattr_permission(inode, name, MAY_WRITE); error = xattr_permission(inode, name, MAY_WRITE);
if (error) if (error)
...@@ -349,7 +371,7 @@ vfs_removexattr(struct dentry *dentry, const char *name) ...@@ -349,7 +371,7 @@ vfs_removexattr(struct dentry *dentry, const char *name)
if (error) if (error)
goto out; goto out;
error = inode->i_op->removexattr(dentry, name); error = __vfs_removexattr(dentry, name);
if (!error) { if (!error) {
fsnotify_xattr(dentry); fsnotify_xattr(dentry);
......
...@@ -46,10 +46,13 @@ struct xattr { ...@@ -46,10 +46,13 @@ struct xattr {
}; };
ssize_t xattr_getsecurity(struct inode *, const char *, void *, size_t); ssize_t xattr_getsecurity(struct inode *, const char *, void *, size_t);
ssize_t __vfs_getxattr(struct dentry *, struct inode *, const char *, void *, size_t);
ssize_t vfs_getxattr(struct dentry *, 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); ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size);
int __vfs_setxattr(struct dentry *, struct inode *, const char *, const void *, size_t, int);
int __vfs_setxattr_noperm(struct dentry *, const char *, const void *, size_t, int); int __vfs_setxattr_noperm(struct dentry *, const char *, const void *, size_t, int);
int vfs_setxattr(struct dentry *, const char *, const void *, size_t, int); int vfs_setxattr(struct dentry *, const char *, const void *, size_t, int);
int __vfs_removexattr(struct dentry *, const char *);
int vfs_removexattr(struct dentry *, const char *); int vfs_removexattr(struct dentry *, const char *);
ssize_t generic_getxattr(struct dentry *dentry, struct inode *inode, const char *name, void *buffer, size_t size); ssize_t generic_getxattr(struct dentry *dentry, struct inode *inode, const char *name, void *buffer, size_t size);
......
...@@ -310,13 +310,8 @@ int cap_inode_need_killpriv(struct dentry *dentry) ...@@ -310,13 +310,8 @@ int cap_inode_need_killpriv(struct dentry *dentry)
struct inode *inode = d_backing_inode(dentry); struct inode *inode = d_backing_inode(dentry);
int error; int error;
if (!inode->i_op->getxattr) error = __vfs_getxattr(dentry, inode, XATTR_NAME_CAPS, NULL, 0);
return 0; return error > 0;
error = inode->i_op->getxattr(dentry, inode, XATTR_NAME_CAPS, NULL, 0);
if (error <= 0)
return 0;
return 1;
} }
/** /**
...@@ -329,12 +324,12 @@ int cap_inode_need_killpriv(struct dentry *dentry) ...@@ -329,12 +324,12 @@ int cap_inode_need_killpriv(struct dentry *dentry)
*/ */
int cap_inode_killpriv(struct dentry *dentry) int cap_inode_killpriv(struct dentry *dentry)
{ {
struct inode *inode = d_backing_inode(dentry); int error;
if (!inode->i_op->removexattr)
return 0;
return inode->i_op->removexattr(dentry, XATTR_NAME_CAPS); error = __vfs_removexattr(dentry, XATTR_NAME_CAPS);
if (error == -EOPNOTSUPP)
error = 0;
return error;
} }
/* /*
...@@ -394,11 +389,11 @@ int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data ...@@ -394,11 +389,11 @@ int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data
memset(cpu_caps, 0, sizeof(struct cpu_vfs_cap_data)); memset(cpu_caps, 0, sizeof(struct cpu_vfs_cap_data));
if (!inode || !inode->i_op->getxattr) if (!inode)
return -ENODATA; return -ENODATA;
size = inode->i_op->getxattr((struct dentry *)dentry, inode, size = __vfs_getxattr((struct dentry *)dentry, inode,
XATTR_NAME_CAPS, &caps, XATTR_CAPS_SZ); XATTR_NAME_CAPS, &caps, XATTR_CAPS_SZ);
if (size == -ENODATA || size == -EOPNOTSUPP) if (size == -ENODATA || size == -EOPNOTSUPP)
/* no data, that's ok */ /* no data, that's ok */
return -ENODATA; return -ENODATA;
......
...@@ -182,8 +182,9 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry, ...@@ -182,8 +182,9 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry,
int error; int error;
int size; int size;
if (!inode->i_op->getxattr) if (!(inode->i_opflags & IOP_XATTR))
return -EOPNOTSUPP; return -EOPNOTSUPP;
desc = init_desc(type); desc = init_desc(type);
if (IS_ERR(desc)) if (IS_ERR(desc))
return PTR_ERR(desc); return PTR_ERR(desc);
...@@ -253,8 +254,8 @@ int evm_update_evmxattr(struct dentry *dentry, const char *xattr_name, ...@@ -253,8 +254,8 @@ int evm_update_evmxattr(struct dentry *dentry, const char *xattr_name,
rc = __vfs_setxattr_noperm(dentry, XATTR_NAME_EVM, rc = __vfs_setxattr_noperm(dentry, XATTR_NAME_EVM,
&xattr_data, &xattr_data,
sizeof(xattr_data), 0); sizeof(xattr_data), 0);
} else if (rc == -ENODATA && inode->i_op->removexattr) { } else if (rc == -ENODATA && (inode->i_opflags & IOP_XATTR)) {
rc = inode->i_op->removexattr(dentry, XATTR_NAME_EVM); rc = __vfs_removexattr(dentry, XATTR_NAME_EVM);
} }
return rc; return rc;
} }
......
...@@ -78,11 +78,11 @@ static int evm_find_protected_xattrs(struct dentry *dentry) ...@@ -78,11 +78,11 @@ static int evm_find_protected_xattrs(struct dentry *dentry)
int error; int error;
int count = 0; int count = 0;
if (!inode->i_op->getxattr) if (!(inode->i_opflags & IOP_XATTR))
return -EOPNOTSUPP; return -EOPNOTSUPP;
for (xattr = evm_config_xattrnames; *xattr != NULL; xattr++) { for (xattr = evm_config_xattrnames; *xattr != NULL; xattr++) {
error = inode->i_op->getxattr(dentry, inode, *xattr, NULL, 0); error = __vfs_getxattr(dentry, inode, *xattr, NULL, 0);
if (error < 0) { if (error < 0) {
if (error == -ENODATA) if (error == -ENODATA)
continue; continue;
......
...@@ -165,13 +165,13 @@ enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, ...@@ -165,13 +165,13 @@ enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value,
int ima_read_xattr(struct dentry *dentry, int ima_read_xattr(struct dentry *dentry,
struct evm_ima_xattr_data **xattr_value) struct evm_ima_xattr_data **xattr_value)
{ {
struct inode *inode = d_backing_inode(dentry); ssize_t ret;
if (!inode->i_op->getxattr)
return 0;
return vfs_getxattr_alloc(dentry, XATTR_NAME_IMA, (char **)xattr_value, ret = vfs_getxattr_alloc(dentry, XATTR_NAME_IMA, (char **)xattr_value,
0, GFP_NOFS); 0, GFP_NOFS);
if (ret == -EOPNOTSUPP)
ret = 0;
return ret;
} }
/* /*
...@@ -195,7 +195,7 @@ int ima_appraise_measurement(enum ima_hooks func, ...@@ -195,7 +195,7 @@ int ima_appraise_measurement(enum ima_hooks func,
enum integrity_status status = INTEGRITY_UNKNOWN; enum integrity_status status = INTEGRITY_UNKNOWN;
int rc = xattr_len, hash_start = 0; int rc = xattr_len, hash_start = 0;
if (!inode->i_op->getxattr) if (!(inode->i_opflags & IOP_XATTR))
return INTEGRITY_UNKNOWN; return INTEGRITY_UNKNOWN;
if (rc <= 0) { if (rc <= 0) {
...@@ -322,10 +322,10 @@ void ima_inode_post_setattr(struct dentry *dentry) ...@@ -322,10 +322,10 @@ void ima_inode_post_setattr(struct dentry *dentry)
{ {
struct inode *inode = d_backing_inode(dentry); struct inode *inode = d_backing_inode(dentry);
struct integrity_iint_cache *iint; struct integrity_iint_cache *iint;
int must_appraise, rc; int must_appraise;
if (!(ima_policy_flag & IMA_APPRAISE) || !S_ISREG(inode->i_mode) if (!(ima_policy_flag & IMA_APPRAISE) || !S_ISREG(inode->i_mode)
|| !inode->i_op->removexattr) || !(inode->i_opflags & IOP_XATTR))
return; return;
must_appraise = ima_must_appraise(inode, MAY_ACCESS, POST_SETATTR); must_appraise = ima_must_appraise(inode, MAY_ACCESS, POST_SETATTR);
...@@ -338,8 +338,7 @@ void ima_inode_post_setattr(struct dentry *dentry) ...@@ -338,8 +338,7 @@ void ima_inode_post_setattr(struct dentry *dentry)
iint->flags |= IMA_APPRAISE; iint->flags |= IMA_APPRAISE;
} }
if (!must_appraise) if (!must_appraise)
rc = inode->i_op->removexattr(dentry, XATTR_NAME_IMA); __vfs_removexattr(dentry, XATTR_NAME_IMA);
return;
} }
/* /*
......
...@@ -507,14 +507,14 @@ static int sb_finish_set_opts(struct super_block *sb) ...@@ -507,14 +507,14 @@ static int sb_finish_set_opts(struct super_block *sb)
the root directory. -ENODATA is ok, as this may be the root directory. -ENODATA is ok, as this may be
the first boot of the SELinux kernel before we have the first boot of the SELinux kernel before we have
assigned xattr values to the filesystem. */ assigned xattr values to the filesystem. */
if (!root_inode->i_op->getxattr) { if (!(root_inode->i_opflags & IOP_XATTR)) {
printk(KERN_WARNING "SELinux: (dev %s, type %s) has no " printk(KERN_WARNING "SELinux: (dev %s, type %s) has no "
"xattr support\n", sb->s_id, sb->s_type->name); "xattr support\n", sb->s_id, sb->s_type->name);
rc = -EOPNOTSUPP; rc = -EOPNOTSUPP;
goto out; goto out;
} }
rc = root_inode->i_op->getxattr(root, root_inode,
XATTR_NAME_SELINUX, NULL, 0); rc = __vfs_getxattr(root, root_inode, XATTR_NAME_SELINUX, NULL, 0);
if (rc < 0 && rc != -ENODATA) { if (rc < 0 && rc != -ENODATA) {
if (rc == -EOPNOTSUPP) if (rc == -EOPNOTSUPP)
printk(KERN_WARNING "SELinux: (dev %s, type " printk(KERN_WARNING "SELinux: (dev %s, type "
...@@ -1410,11 +1410,10 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent ...@@ -1410,11 +1410,10 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
case SECURITY_FS_USE_NATIVE: case SECURITY_FS_USE_NATIVE:
break; break;
case SECURITY_FS_USE_XATTR: case SECURITY_FS_USE_XATTR:
if (!inode->i_op->getxattr) { if (!(inode->i_opflags & IOP_XATTR)) {
isec->sid = sbsec->def_sid; isec->sid = sbsec->def_sid;
break; break;
} }
/* Need a dentry, since the xattr API requires one. /* Need a dentry, since the xattr API requires one.
Life would be simpler if we could just pass the inode. */ Life would be simpler if we could just pass the inode. */
if (opt_dentry) { if (opt_dentry) {
...@@ -1445,14 +1444,12 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent ...@@ -1445,14 +1444,12 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
goto out_unlock; goto out_unlock;
} }
context[len] = '\0'; context[len] = '\0';
rc = inode->i_op->getxattr(dentry, inode, XATTR_NAME_SELINUX, rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, context, len);
context, len);
if (rc == -ERANGE) { if (rc == -ERANGE) {
kfree(context); kfree(context);
/* Need a larger buffer. Query for the right size. */ /* Need a larger buffer. Query for the right size. */
rc = inode->i_op->getxattr(dentry, inode, XATTR_NAME_SELINUX, rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, NULL, 0);
NULL, 0);
if (rc < 0) { if (rc < 0) {
dput(dentry); dput(dentry);
goto out_unlock; goto out_unlock;
...@@ -1465,9 +1462,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent ...@@ -1465,9 +1462,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
goto out_unlock; goto out_unlock;
} }
context[len] = '\0'; context[len] = '\0';
rc = inode->i_op->getxattr(dentry, inode, rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, context, len);
XATTR_NAME_SELINUX,
context, len);
} }
dput(dentry); dput(dentry);
if (rc < 0) { if (rc < 0) {
......
...@@ -265,14 +265,14 @@ static struct smack_known *smk_fetch(const char *name, struct inode *ip, ...@@ -265,14 +265,14 @@ static struct smack_known *smk_fetch(const char *name, struct inode *ip,
char *buffer; char *buffer;
struct smack_known *skp = NULL; struct smack_known *skp = NULL;
if (ip->i_op->getxattr == NULL) if (!(ip->i_opflags & IOP_XATTR))
return ERR_PTR(-EOPNOTSUPP); return ERR_PTR(-EOPNOTSUPP);
buffer = kzalloc(SMK_LONGLABEL, GFP_KERNEL); buffer = kzalloc(SMK_LONGLABEL, GFP_KERNEL);
if (buffer == NULL) if (buffer == NULL)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
rc = ip->i_op->getxattr(dp, ip, name, buffer, SMK_LONGLABEL); rc = __vfs_getxattr(dp, ip, name, buffer, SMK_LONGLABEL);
if (rc < 0) if (rc < 0)
skp = ERR_PTR(rc); skp = ERR_PTR(rc);
else if (rc == 0) else if (rc == 0)
...@@ -3520,8 +3520,8 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) ...@@ -3520,8 +3520,8 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
* It would be curious if the label of the task * It would be curious if the label of the task
* does not match that assigned. * does not match that assigned.
*/ */
if (inode->i_op->getxattr == NULL) if (!(inode->i_opflags & IOP_XATTR))
break; break;
/* /*
* Get the dentry for xattr. * Get the dentry for xattr.
*/ */
...@@ -3545,12 +3545,12 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) ...@@ -3545,12 +3545,12 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
*/ */
if (isp->smk_flags & SMK_INODE_CHANGED) { if (isp->smk_flags & SMK_INODE_CHANGED) {
isp->smk_flags &= ~SMK_INODE_CHANGED; isp->smk_flags &= ~SMK_INODE_CHANGED;
rc = inode->i_op->setxattr(dp, inode, rc = __vfs_setxattr(dp, inode,
XATTR_NAME_SMACKTRANSMUTE, XATTR_NAME_SMACKTRANSMUTE,
TRANS_TRUE, TRANS_TRUE_SIZE, TRANS_TRUE, TRANS_TRUE_SIZE,
0); 0);
} else { } else {
rc = inode->i_op->getxattr(dp, inode, rc = __vfs_getxattr(dp, inode,
XATTR_NAME_SMACKTRANSMUTE, trattr, XATTR_NAME_SMACKTRANSMUTE, trattr,
TRANS_TRUE_SIZE); TRANS_TRUE_SIZE);
if (rc >= 0 && strncmp(trattr, TRANS_TRUE, if (rc >= 0 && strncmp(trattr, TRANS_TRUE,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment