xfs
[Top] [All Lists]

[PATCH 2/4] userns: ioctl: convert project id between user and kernel sp

To: xfs@xxxxxxxxxxx
Subject: [PATCH 2/4] userns: ioctl: convert project id between user and kernel space
From: Gao feng <gaofeng@xxxxxxxxxxxxxx>
Date: Wed, 4 Sep 2013 14:38:35 +0800
Cc: dwight.engen@xxxxxxxxxx, david@xxxxxxxxxxxxx, bfoster@xxxxxxxxxx, ebiederm@xxxxxxxxxxxx, Gao feng <gaofeng@xxxxxxxxxxxxxx>
Delivered-to: xfs@xxxxxxxxxxx
In-reply-to: <1378276717-9663-1-git-send-email-gaofeng@xxxxxxxxxxxxxx>
References: <1378276717-9663-1-git-send-email-gaofeng@xxxxxxxxxxxxxx>
User namespace use /proc/<pid>/projid_map to map the project ids
in user namespace to the global project ids.

This patch adds the conversion of xfs proj_t to the global project
id struct kprojid_t, and adds the validating check.

User in un-init user namespace can only change file's project id
to the specified ids which are configured in projid_map of userns.

Signed-off-by: Gao feng <gaofeng@xxxxxxxxxxxxxx>
---
 fs/xfs/xfs_ioctl.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index bdebc21..8db622f 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -855,7 +855,7 @@ xfs_ioc_fsgetxattr(
        xfs_ilock(ip, XFS_ILOCK_SHARED);
        fa.fsx_xflags = xfs_ip2xflags(ip);
        fa.fsx_extsize = ip->i_d.di_extsize << ip->i_mount->m_sb.sb_blocklog;
-       fa.fsx_projid = xfs_get_projid(ip);
+       fa.fsx_projid = xfs_convert_to_user_projid(xfs_get_projid(ip));
 
        if (attr) {
                if (ip->i_afp) {
@@ -965,6 +965,7 @@ xfs_ioctl_setattr(
        struct xfs_dquot        *pdqp = NULL;
        struct xfs_dquot        *olddquot = NULL;
        int                     code;
+       prid_t                  projid = 0;
 
        trace_xfs_ioctl_setattr(ip);
 
@@ -976,9 +977,12 @@ xfs_ioctl_setattr(
        /*
         * Disallow 32bit project ids when projid32bit feature is not enabled.
         */
-       if ((mask & FSX_PROJID) && (fa->fsx_projid > (__uint16_t)-1) &&
-                       !xfs_sb_version_hasprojid32bit(&ip->i_mount->m_sb))
-               return XFS_ERROR(EINVAL);
+       if ((mask & FSX_PROJID)) {
+               if ((xfs_convert_to_kernel_projid(fa->fsx_projid, &projid) < 0) 
||
+                   ((projid > (__uint16_t)-1) &&
+                    !xfs_sb_version_hasprojid32bit(&ip->i_mount->m_sb)))
+                       return XFS_ERROR(EINVAL);
+       }
 
        /*
         * If disk quotas is on, we make sure that the dquots do exist on disk,
@@ -990,7 +994,7 @@ xfs_ioctl_setattr(
         */
        if (XFS_IS_QUOTA_ON(mp) && (mask & FSX_PROJID)) {
                code = xfs_qm_vop_dqalloc(ip, ip->i_d.di_uid,
-                                        ip->i_d.di_gid, fa->fsx_projid,
+                                        ip->i_d.di_gid, projid,
                                         XFS_QMOPT_PQUOTA, &udqp, NULL, &pdqp);
                if (code)
                        return code;
@@ -1033,7 +1037,7 @@ xfs_ioctl_setattr(
 
                if (XFS_IS_QUOTA_RUNNING(mp) &&
                    XFS_IS_PQUOTA_ON(mp) &&
-                   xfs_get_projid(ip) != fa->fsx_projid) {
+                   xfs_get_projid(ip) != projid) {
                        ASSERT(tp);
                        code = xfs_qm_vop_chown_reserve(tp, ip, udqp, NULL,
                                                pdqp, capable(CAP_FOWNER) ?
@@ -1151,12 +1155,12 @@ xfs_ioctl_setattr(
                 * Change the ownerships and register quota modifications
                 * in the transaction.
                 */
-               if (xfs_get_projid(ip) != fa->fsx_projid) {
+               if (xfs_get_projid(ip) != projid) {
                        if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_PQUOTA_ON(mp)) {
                                olddquot = xfs_qm_vop_chown(tp, ip,
                                                        &ip->i_pdquot, pdqp);
                        }
-                       xfs_set_projid(ip, fa->fsx_projid);
+                       xfs_set_projid(ip, projid);
 
                        /*
                         * We may have to rev the inode as well as
-- 
1.8.3.1

<Prev in Thread] Current Thread [Next in Thread>