diff options
Diffstat (limited to 'fs/quota')
-rw-r--r-- | fs/quota/dquot.c | 8 | ||||
-rw-r--r-- | fs/quota/quota.c | 28 |
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; |