aboutsummaryrefslogtreecommitdiffstats
path: root/fs/quota/quota.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-10-15 11:20:54 -0400
committerJohannes Berg <johannes.berg@intel.com>2012-10-15 11:20:54 -0400
commitdf9b42963f2d010ae3163a894ce22cf6b27cd344 (patch)
treef42f826d9bb975766c1a79986c39e64c9a900908 /fs/quota/quota.c
parent33766368f6532313571534f9112b1796d6651bbe (diff)
parentc3e7724b6bc2f25e46c38dbe68f09d71fafeafb8 (diff)
Merge remote-tracking branch 'wireless/master' into mac80211
Diffstat (limited to 'fs/quota/quota.c')
-rw-r--r--fs/quota/quota.c30
1 files changed, 23 insertions, 7 deletions
diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index c659f92298d3..ff0135d6bc51 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -9,7 +9,7 @@
9#include <linux/namei.h> 9#include <linux/namei.h>
10#include <linux/slab.h> 10#include <linux/slab.h>
11#include <asm/current.h> 11#include <asm/current.h>
12#include <asm/uaccess.h> 12#include <linux/uaccess.h>
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/security.h> 14#include <linux/security.h>
15#include <linux/syscalls.h> 15#include <linux/syscalls.h>
@@ -32,8 +32,8 @@ static int check_quotactl_permission(struct super_block *sb, int type, int cmd,
32 /* allow to query information for dquots we "own" */ 32 /* allow to query information for dquots we "own" */
33 case Q_GETQUOTA: 33 case Q_GETQUOTA:
34 case Q_XGETQUOTA: 34 case Q_XGETQUOTA:
35 if ((type == USRQUOTA && current_euid() == id) || 35 if ((type == USRQUOTA && uid_eq(current_euid(), make_kuid(current_user_ns(), id))) ||
36 (type == GRPQUOTA && in_egroup_p(id))) 36 (type == GRPQUOTA && in_egroup_p(make_kgid(current_user_ns(), id))))
37 break; 37 break;
38 /*FALLTHROUGH*/ 38 /*FALLTHROUGH*/
39 default: 39 default:
@@ -130,13 +130,17 @@ static void copy_to_if_dqblk(struct if_dqblk *dst, struct fs_disk_quota *src)
130static int quota_getquota(struct super_block *sb, int type, qid_t id, 130static int quota_getquota(struct super_block *sb, int type, qid_t id,
131 void __user *addr) 131 void __user *addr)
132{ 132{
133 struct kqid qid;
133 struct fs_disk_quota fdq; 134 struct fs_disk_quota fdq;
134 struct if_dqblk idq; 135 struct if_dqblk idq;
135 int ret; 136 int ret;
136 137
137 if (!sb->s_qcop->get_dqblk) 138 if (!sb->s_qcop->get_dqblk)
138 return -ENOSYS; 139 return -ENOSYS;
139 ret = sb->s_qcop->get_dqblk(sb, type, id, &fdq); 140 qid = make_kqid(current_user_ns(), type, id);
141 if (!qid_valid(qid))
142 return -EINVAL;
143 ret = sb->s_qcop->get_dqblk(sb, qid, &fdq);
140 if (ret) 144 if (ret)
141 return ret; 145 return ret;
142 copy_to_if_dqblk(&idq, &fdq); 146 copy_to_if_dqblk(&idq, &fdq);
@@ -176,13 +180,17 @@ static int quota_setquota(struct super_block *sb, int type, qid_t id,
176{ 180{
177 struct fs_disk_quota fdq; 181 struct fs_disk_quota fdq;
178 struct if_dqblk idq; 182 struct if_dqblk idq;
183 struct kqid qid;
179 184
180 if (copy_from_user(&idq, addr, sizeof(idq))) 185 if (copy_from_user(&idq, addr, sizeof(idq)))
181 return -EFAULT; 186 return -EFAULT;
182 if (!sb->s_qcop->set_dqblk) 187 if (!sb->s_qcop->set_dqblk)
183 return -ENOSYS; 188 return -ENOSYS;
189 qid = make_kqid(current_user_ns(), type, id);
190 if (!qid_valid(qid))
191 return -EINVAL;
184 copy_from_if_dqblk(&fdq, &idq); 192 copy_from_if_dqblk(&fdq, &idq);
185 return sb->s_qcop->set_dqblk(sb, type, id, &fdq); 193 return sb->s_qcop->set_dqblk(sb, qid, &fdq);
186} 194}
187 195
188static int quota_setxstate(struct super_block *sb, int cmd, void __user *addr) 196static 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,
213 void __user *addr) 221 void __user *addr)
214{ 222{
215 struct fs_disk_quota fdq; 223 struct fs_disk_quota fdq;
224 struct kqid qid;
216 225
217 if (copy_from_user(&fdq, addr, sizeof(fdq))) 226 if (copy_from_user(&fdq, addr, sizeof(fdq)))
218 return -EFAULT; 227 return -EFAULT;
219 if (!sb->s_qcop->set_dqblk) 228 if (!sb->s_qcop->set_dqblk)
220 return -ENOSYS; 229 return -ENOSYS;
221 return sb->s_qcop->set_dqblk(sb, type, id, &fdq); 230 qid = make_kqid(current_user_ns(), type, id);
231 if (!qid_valid(qid))
232 return -EINVAL;
233 return sb->s_qcop->set_dqblk(sb, qid, &fdq);
222} 234}
223 235
224static int quota_getxquota(struct super_block *sb, int type, qid_t id, 236static int quota_getxquota(struct super_block *sb, int type, qid_t id,
225 void __user *addr) 237 void __user *addr)
226{ 238{
227 struct fs_disk_quota fdq; 239 struct fs_disk_quota fdq;
240 struct kqid qid;
228 int ret; 241 int ret;
229 242
230 if (!sb->s_qcop->get_dqblk) 243 if (!sb->s_qcop->get_dqblk)
231 return -ENOSYS; 244 return -ENOSYS;
232 ret = sb->s_qcop->get_dqblk(sb, type, id, &fdq); 245 qid = make_kqid(current_user_ns(), type, id);
246 if (!qid_valid(qid))
247 return -EINVAL;
248 ret = sb->s_qcop->get_dqblk(sb, qid, &fdq);
233 if (!ret && copy_to_user(addr, &fdq, sizeof(fdq))) 249 if (!ret && copy_to_user(addr, &fdq, sizeof(fdq)))
234 return -EFAULT; 250 return -EFAULT;
235 return ret; 251 return ret;