aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c13
-rw-r--r--fs/xfs/xfs_attr.c41
-rw-r--r--fs/xfs/xfs_attr.h2
3 files changed, 1 insertions, 55 deletions
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index 5fc61c824bb9..13b6cfd366c2 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -739,15 +739,11 @@ xfs_vn_setxattr(
739 char *attr = (char *)name; 739 char *attr = (char *)name;
740 attrnames_t *namesp; 740 attrnames_t *namesp;
741 int xflags = 0; 741 int xflags = 0;
742 int error;
743 742
744 namesp = attr_lookup_namespace(attr, attr_namespaces, ATTR_NAMECOUNT); 743 namesp = attr_lookup_namespace(attr, attr_namespaces, ATTR_NAMECOUNT);
745 if (!namesp) 744 if (!namesp)
746 return -EOPNOTSUPP; 745 return -EOPNOTSUPP;
747 attr += namesp->attr_namelen; 746 attr += namesp->attr_namelen;
748 error = namesp->attr_capable(vp, NULL);
749 if (error)
750 return error;
751 747
752 /* Convert Linux syscall to XFS internal ATTR flags */ 748 /* Convert Linux syscall to XFS internal ATTR flags */
753 if (flags & XATTR_CREATE) 749 if (flags & XATTR_CREATE)
@@ -769,15 +765,11 @@ xfs_vn_getxattr(
769 char *attr = (char *)name; 765 char *attr = (char *)name;
770 attrnames_t *namesp; 766 attrnames_t *namesp;
771 int xflags = 0; 767 int xflags = 0;
772 ssize_t error;
773 768
774 namesp = attr_lookup_namespace(attr, attr_namespaces, ATTR_NAMECOUNT); 769 namesp = attr_lookup_namespace(attr, attr_namespaces, ATTR_NAMECOUNT);
775 if (!namesp) 770 if (!namesp)
776 return -EOPNOTSUPP; 771 return -EOPNOTSUPP;
777 attr += namesp->attr_namelen; 772 attr += namesp->attr_namelen;
778 error = namesp->attr_capable(vp, NULL);
779 if (error)
780 return error;
781 773
782 /* Convert Linux syscall to XFS internal ATTR flags */ 774 /* Convert Linux syscall to XFS internal ATTR flags */
783 if (!size) { 775 if (!size) {
@@ -817,15 +809,12 @@ xfs_vn_removexattr(
817 char *attr = (char *)name; 809 char *attr = (char *)name;
818 attrnames_t *namesp; 810 attrnames_t *namesp;
819 int xflags = 0; 811 int xflags = 0;
820 int error;
821 812
822 namesp = attr_lookup_namespace(attr, attr_namespaces, ATTR_NAMECOUNT); 813 namesp = attr_lookup_namespace(attr, attr_namespaces, ATTR_NAMECOUNT);
823 if (!namesp) 814 if (!namesp)
824 return -EOPNOTSUPP; 815 return -EOPNOTSUPP;
825 attr += namesp->attr_namelen; 816 attr += namesp->attr_namelen;
826 error = namesp->attr_capable(vp, NULL); 817
827 if (error)
828 return error;
829 xflags |= namesp->attr_flag; 818 xflags |= namesp->attr_flag;
830 return namesp->attr_remove(vp, attr, xflags); 819 return namesp->attr_remove(vp, attr, xflags);
831} 820}
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c
index df151a859186..86d8619f279c 100644
--- a/fs/xfs/xfs_attr.c
+++ b/fs/xfs/xfs_attr.c
@@ -2622,43 +2622,6 @@ attr_lookup_namespace(
2622 return NULL; 2622 return NULL;
2623} 2623}
2624 2624
2625/*
2626 * Some checks to prevent people abusing EAs to get over quota:
2627 * - Don't allow modifying user EAs on devices/symlinks;
2628 * - Don't allow modifying user EAs if sticky bit set;
2629 */
2630STATIC int
2631attr_user_capable(
2632 bhv_vnode_t *vp,
2633 cred_t *cred)
2634{
2635 struct inode *inode = vn_to_inode(vp);
2636
2637 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
2638 return -EPERM;
2639 if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode) &&
2640 !capable(CAP_SYS_ADMIN))
2641 return -EPERM;
2642 if (S_ISDIR(inode->i_mode) && (inode->i_mode & S_ISVTX) &&
2643 (current_fsuid(cred) != inode->i_uid) && !capable(CAP_FOWNER))
2644 return -EPERM;
2645 return 0;
2646}
2647
2648STATIC int
2649attr_trusted_capable(
2650 bhv_vnode_t *vp,
2651 cred_t *cred)
2652{
2653 struct inode *inode = vn_to_inode(vp);
2654
2655 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
2656 return -EPERM;
2657 if (!capable(CAP_SYS_ADMIN))
2658 return -EPERM;
2659 return 0;
2660}
2661
2662STATIC int 2625STATIC int
2663attr_system_set( 2626attr_system_set(
2664 bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags) 2627 bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
@@ -2709,7 +2672,6 @@ struct attrnames attr_system = {
2709 .attr_get = attr_system_get, 2672 .attr_get = attr_system_get,
2710 .attr_set = attr_system_set, 2673 .attr_set = attr_system_set,
2711 .attr_remove = attr_system_remove, 2674 .attr_remove = attr_system_remove,
2712 .attr_capable = (attrcapable_t)fs_noerr,
2713}; 2675};
2714 2676
2715struct attrnames attr_trusted = { 2677struct attrnames attr_trusted = {
@@ -2719,7 +2681,6 @@ struct attrnames attr_trusted = {
2719 .attr_get = attr_generic_get, 2681 .attr_get = attr_generic_get,
2720 .attr_set = attr_generic_set, 2682 .attr_set = attr_generic_set,
2721 .attr_remove = attr_generic_remove, 2683 .attr_remove = attr_generic_remove,
2722 .attr_capable = attr_trusted_capable,
2723}; 2684};
2724 2685
2725struct attrnames attr_secure = { 2686struct attrnames attr_secure = {
@@ -2729,7 +2690,6 @@ struct attrnames attr_secure = {
2729 .attr_get = attr_generic_get, 2690 .attr_get = attr_generic_get,
2730 .attr_set = attr_generic_set, 2691 .attr_set = attr_generic_set,
2731 .attr_remove = attr_generic_remove, 2692 .attr_remove = attr_generic_remove,
2732 .attr_capable = (attrcapable_t)fs_noerr,
2733}; 2693};
2734 2694
2735struct attrnames attr_user = { 2695struct attrnames attr_user = {
@@ -2738,7 +2698,6 @@ struct attrnames attr_user = {
2738 .attr_get = attr_generic_get, 2698 .attr_get = attr_generic_get,
2739 .attr_set = attr_generic_set, 2699 .attr_set = attr_generic_set,
2740 .attr_remove = attr_generic_remove, 2700 .attr_remove = attr_generic_remove,
2741 .attr_capable = attr_user_capable,
2742}; 2701};
2743 2702
2744struct attrnames *attr_namespaces[] = 2703struct attrnames *attr_namespaces[] =
diff --git a/fs/xfs/xfs_attr.h b/fs/xfs/xfs_attr.h
index 6cfc9384fe35..9b96d171b75c 100644
--- a/fs/xfs/xfs_attr.h
+++ b/fs/xfs/xfs_attr.h
@@ -42,7 +42,6 @@ typedef int (*attrset_t)(bhv_vnode_t *, char *, void *, size_t, int);
42typedef int (*attrget_t)(bhv_vnode_t *, char *, void *, size_t, int); 42typedef int (*attrget_t)(bhv_vnode_t *, char *, void *, size_t, int);
43typedef int (*attrremove_t)(bhv_vnode_t *, char *, int); 43typedef int (*attrremove_t)(bhv_vnode_t *, char *, int);
44typedef int (*attrexists_t)(bhv_vnode_t *); 44typedef int (*attrexists_t)(bhv_vnode_t *);
45typedef int (*attrcapable_t)(bhv_vnode_t *, struct cred *);
46 45
47typedef struct attrnames { 46typedef struct attrnames {
48 char * attr_name; 47 char * attr_name;
@@ -52,7 +51,6 @@ typedef struct attrnames {
52 attrset_t attr_set; 51 attrset_t attr_set;
53 attrremove_t attr_remove; 52 attrremove_t attr_remove;
54 attrexists_t attr_exists; 53 attrexists_t attr_exists;
55 attrcapable_t attr_capable;
56} attrnames_t; 54} attrnames_t;
57 55
58#define ATTR_NAMECOUNT 4 56#define ATTR_NAMECOUNT 4