summaryrefslogtreecommitdiff
path: root/fs/quota
diff options
context:
space:
mode:
Diffstat (limited to 'fs/quota')
-rw-r--r--fs/quota/dquot.c8
-rw-r--r--fs/quota/quota.c28
2 files changed, 26 insertions, 10 deletions
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 36a29b753c79..7714b169d646 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -2376,12 +2376,12 @@ static void do_get_dqblk(struct dquot *dquot, struct fs_disk_quota *di)
spin_unlock(&dq_data_lock);
}
-int dquot_get_dqblk(struct super_block *sb, int type, qid_t id,
+int dquot_get_dqblk(struct super_block *sb, struct kqid qid,
struct fs_disk_quota *di)
{
struct dquot *dquot;
- dquot = dqget(sb, id, type);
+ dquot = dqget(sb, qid.type, from_kqid(&init_user_ns, qid));
if (!dquot)
return -ESRCH;
do_get_dqblk(dquot, di);
@@ -2488,13 +2488,13 @@ static int do_set_dqblk(struct dquot *dquot, struct fs_disk_quota *di)
return 0;
}
-int dquot_set_dqblk(struct super_block *sb, int type, qid_t id,
+int dquot_set_dqblk(struct super_block *sb, struct kqid qid,
struct fs_disk_quota *di)
{
struct dquot *dquot;
int rc;
- dquot = dqget(sb, id, type);
+ dquot = dqget(sb, qid.type, from_kqid(&init_user_ns, qid));
if (!dquot) {
rc = -ESRCH;
goto out;
diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index 6f155788cbc6..ff0135d6bc51 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -32,8 +32,8 @@ static int check_quotactl_permission(struct super_block *sb, int type, int cmd,
/* allow to query information for dquots we "own" */
case Q_GETQUOTA:
case Q_XGETQUOTA:
- if ((type == USRQUOTA && current_euid() == id) ||
- (type == GRPQUOTA && in_egroup_p(id)))
+ if ((type == USRQUOTA && uid_eq(current_euid(), make_kuid(current_user_ns(), id))) ||
+ (type == GRPQUOTA && in_egroup_p(make_kgid(current_user_ns(), id))))
break;
/*FALLTHROUGH*/
default:
@@ -130,13 +130,17 @@ static void copy_to_if_dqblk(struct if_dqblk *dst, struct fs_disk_quota *src)
static int quota_getquota(struct super_block *sb, int type, qid_t id,
void __user *addr)
{
+ struct kqid qid;
struct fs_disk_quota fdq;
struct if_dqblk idq;
int ret;
if (!sb->s_qcop->get_dqblk)
return -ENOSYS;
- ret = sb->s_qcop->get_dqblk(sb, type, id, &fdq);
+ qid = make_kqid(current_user_ns(), type, id);
+ if (!qid_valid(qid))
+ return -EINVAL;
+ ret = sb->s_qcop->get_dqblk(sb, qid, &fdq);
if (ret)
return ret;
copy_to_if_dqblk(&idq, &fdq);
@@ -176,13 +180,17 @@ static int quota_setquota(struct super_block *sb, int type, qid_t id,
{
struct fs_disk_quota fdq;
struct if_dqblk idq;
+ struct kqid qid;
if (copy_from_user(&idq, addr, sizeof(idq)))
return -EFAULT;
if (!sb->s_qcop->set_dqblk)
return -ENOSYS;
+ qid = make_kqid(current_user_ns(), type, id);
+ if (!qid_valid(qid))
+ return -EINVAL;
copy_from_if_dqblk(&fdq, &idq);
- return sb->s_qcop->set_dqblk(sb, type, id, &fdq);
+ return sb->s_qcop->set_dqblk(sb, qid, &fdq);
}
static int quota_setxstate(struct super_block *sb, int cmd, void __user *addr)
@@ -213,23 +221,31 @@ static int quota_setxquota(struct super_block *sb, int type, qid_t id,
void __user *addr)
{
struct fs_disk_quota fdq;
+ struct kqid qid;
if (copy_from_user(&fdq, addr, sizeof(fdq)))
return -EFAULT;
if (!sb->s_qcop->set_dqblk)
return -ENOSYS;
- return sb->s_qcop->set_dqblk(sb, type, id, &fdq);
+ qid = make_kqid(current_user_ns(), type, id);
+ if (!qid_valid(qid))
+ return -EINVAL;
+ return sb->s_qcop->set_dqblk(sb, qid, &fdq);
}
static int quota_getxquota(struct super_block *sb, int type, qid_t id,
void __user *addr)
{
struct fs_disk_quota fdq;
+ struct kqid qid;
int ret;
if (!sb->s_qcop->get_dqblk)
return -ENOSYS;
- ret = sb->s_qcop->get_dqblk(sb, type, id, &fdq);
+ qid = make_kqid(current_user_ns(), type, id);
+ if (!qid_valid(qid))
+ return -EINVAL;
+ ret = sb->s_qcop->get_dqblk(sb, qid, &fdq);
if (!ret && copy_to_user(addr, &fdq, sizeof(fdq)))
return -EFAULT;
return ret;