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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

_______________________________________________
xfs mailing list
xfs@xxxxxxxxxxx
http://oss.sgi.com/mailman/listinfo/xfs




[Index of Archives]     [Linux XFS Devel]     [Linux Filesystem Development]     [Filesystem Testing]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux