1 /* 2 * Quota code necessary even when VFS quota support is not compiled 3 * into the kernel. The interesting stuff is over in dquot.c, here 4 * we have symbols for initial quotactl(2) handling, the sysctl(2) 5 * variables, etc - things needed even when quota support disabled. 6 */ 7 8 #include <linux/fs.h> 9 #include <linux/namei.h> 10 #include <linux/slab.h> 11 #include <asm/current.h> 12 #include <linux/uaccess.h> 13 #include <linux/kernel.h> 14 #include <linux/security.h> 15 #include <linux/syscalls.h> 16 #include <linux/capability.h> 17 #include <linux/quotaops.h> 18 #include <linux/types.h> 19 #include <linux/writeback.h> 20 21 static int check_quotactl_permission(struct super_block *sb, int type, int cmd, 22 qid_t id) 23 { 24 switch (cmd) { 25 /* these commands do not require any special privilegues */ 26 case Q_GETFMT: 27 case Q_SYNC: 28 case Q_GETINFO: 29 case Q_XGETQSTAT: 30 case Q_XQUOTASYNC: 31 break; 32 /* allow to query information for dquots we "own" */ 33 case Q_GETQUOTA: 34 case Q_XGETQUOTA: 35 if ((type == USRQUOTA && uid_eq(current_euid(), make_kuid(current_user_ns(), id))) || 36 (type == GRPQUOTA && in_egroup_p(make_kgid(current_user_ns(), id)))) 37 break; 38 /*FALLTHROUGH*/ 39 default: 40 if (!capable(CAP_SYS_ADMIN)) 41 return -EPERM; 42 } 43 44 return security_quotactl(cmd, type, id, sb); 45 } 46 47 static void quota_sync_one(struct super_block *sb, void *arg) 48 { 49 if (sb->s_qcop && sb->s_qcop->quota_sync) 50 sb->s_qcop->quota_sync(sb, *(int *)arg); 51 } 52 53 static int quota_sync_all(int type) 54 { 55 int ret; 56 57 if (type >= MAXQUOTAS) 58 return -EINVAL; 59 ret = security_quotactl(Q_SYNC, type, 0, NULL); 60 if (!ret) 61 iterate_supers(quota_sync_one, &type); 62 return ret; 63 } 64 65 static int quota_quotaon(struct super_block *sb, int type, int cmd, qid_t id, 66 struct path *path) 67 { 68 if (!sb->s_qcop->quota_on && !sb->s_qcop->quota_on_meta) 69 return -ENOSYS; 70 if (sb->s_qcop->quota_on_meta) 71 return sb->s_qcop->quota_on_meta(sb, type, id); 72 if (IS_ERR(path)) 73 return PTR_ERR(path); 74 return sb->s_qcop->quota_on(sb, type, id, path); 75 } 76 77 static int quota_getfmt(struct super_block *sb, int type, void __user *addr) 78 { 79 __u32 fmt; 80 81 down_read(&sb_dqopt(sb)->dqptr_sem); 82 if (!sb_has_quota_active(sb, type)) { 83 up_read(&sb_dqopt(sb)->dqptr_sem); 84 return -ESRCH; 85 } 86 fmt = sb_dqopt(sb)->info[type].dqi_format->qf_fmt_id; 87 up_read(&sb_dqopt(sb)->dqptr_sem); 88 if (copy_to_user(addr, &fmt, sizeof(fmt))) 89 return -EFAULT; 90 return 0; 91 } 92 93 static int quota_getinfo(struct super_block *sb, int type, void __user *addr) 94 { 95 struct if_dqinfo info; 96 int ret; 97 98 if (!sb->s_qcop->get_info) 99 return -ENOSYS; 100 ret = sb->s_qcop->get_info(sb, type, &info); 101 if (!ret && copy_to_user(addr, &info, sizeof(info))) 102 return -EFAULT; 103 return ret; 104 } 105 106 static int quota_setinfo(struct super_block *sb, int type, void __user *addr) 107 { 108 struct if_dqinfo info; 109 110 if (copy_from_user(&info, addr, sizeof(info))) 111 return -EFAULT; 112 if (!sb->s_qcop->set_info) 113 return -ENOSYS; 114 return sb->s_qcop->set_info(sb, type, &info); 115 } 116 117 static void copy_to_if_dqblk(struct if_dqblk *dst, struct fs_disk_quota *src) 118 { 119 dst->dqb_bhardlimit = src->d_blk_hardlimit; 120 dst->dqb_bsoftlimit = src->d_blk_softlimit; 121 dst->dqb_curspace = src->d_bcount; 122 dst->dqb_ihardlimit = src->d_ino_hardlimit; 123 dst->dqb_isoftlimit = src->d_ino_softlimit; 124 dst->dqb_curinodes = src->d_icount; 125 dst->dqb_btime = src->d_btimer; 126 dst->dqb_itime = src->d_itimer; 127 dst->dqb_valid = QIF_ALL; 128 } 129 130 static int quota_getquota(struct super_block *sb, int type, qid_t id, 131 void __user *addr) 132 { 133 struct kqid qid; 134 struct fs_disk_quota fdq; 135 struct if_dqblk idq; 136 int ret; 137 138 if (!sb->s_qcop->get_dqblk) 139 return -ENOSYS; 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); 144 if (ret) 145 return ret; 146 copy_to_if_dqblk(&idq, &fdq); 147 if (copy_to_user(addr, &idq, sizeof(idq))) 148 return -EFAULT; 149 return 0; 150 } 151 152 static void copy_from_if_dqblk(struct fs_disk_quota *dst, struct if_dqblk *src) 153 { 154 dst->d_blk_hardlimit = src->dqb_bhardlimit; 155 dst->d_blk_softlimit = src->dqb_bsoftlimit; 156 dst->d_bcount = src->dqb_curspace; 157 dst->d_ino_hardlimit = src->dqb_ihardlimit; 158 dst->d_ino_softlimit = src->dqb_isoftlimit; 159 dst->d_icount = src->dqb_curinodes; 160 dst->d_btimer = src->dqb_btime; 161 dst->d_itimer = src->dqb_itime; 162 163 dst->d_fieldmask = 0; 164 if (src->dqb_valid & QIF_BLIMITS) 165 dst->d_fieldmask |= FS_DQ_BSOFT | FS_DQ_BHARD; 166 if (src->dqb_valid & QIF_SPACE) 167 dst->d_fieldmask |= FS_DQ_BCOUNT; 168 if (src->dqb_valid & QIF_ILIMITS) 169 dst->d_fieldmask |= FS_DQ_ISOFT | FS_DQ_IHARD; 170 if (src->dqb_valid & QIF_INODES) 171 dst->d_fieldmask |= FS_DQ_ICOUNT; 172 if (src->dqb_valid & QIF_BTIME) 173 dst->d_fieldmask |= FS_DQ_BTIMER; 174 if (src->dqb_valid & QIF_ITIME) 175 dst->d_fieldmask |= FS_DQ_ITIMER; 176 } 177 178 static int quota_setquota(struct super_block *sb, int type, qid_t id, 179 void __user *addr) 180 { 181 struct fs_disk_quota fdq; 182 struct if_dqblk idq; 183 struct kqid qid; 184 185 if (copy_from_user(&idq, addr, sizeof(idq))) 186 return -EFAULT; 187 if (!sb->s_qcop->set_dqblk) 188 return -ENOSYS; 189 qid = make_kqid(current_user_ns(), type, id); 190 if (!qid_valid(qid)) 191 return -EINVAL; 192 copy_from_if_dqblk(&fdq, &idq); 193 return sb->s_qcop->set_dqblk(sb, qid, &fdq); 194 } 195 196 static int quota_setxstate(struct super_block *sb, int cmd, void __user *addr) 197 { 198 __u32 flags; 199 200 if (copy_from_user(&flags, addr, sizeof(flags))) 201 return -EFAULT; 202 if (!sb->s_qcop->set_xstate) 203 return -ENOSYS; 204 return sb->s_qcop->set_xstate(sb, flags, cmd); 205 } 206 207 static int quota_getxstate(struct super_block *sb, void __user *addr) 208 { 209 struct fs_quota_stat fqs; 210 int ret; 211 212 if (!sb->s_qcop->get_xstate) 213 return -ENOSYS; 214 ret = sb->s_qcop->get_xstate(sb, &fqs); 215 if (!ret && copy_to_user(addr, &fqs, sizeof(fqs))) 216 return -EFAULT; 217 return ret; 218 } 219 220 static int quota_setxquota(struct super_block *sb, int type, qid_t id, 221 void __user *addr) 222 { 223 struct fs_disk_quota fdq; 224 struct kqid qid; 225 226 if (copy_from_user(&fdq, addr, sizeof(fdq))) 227 return -EFAULT; 228 if (!sb->s_qcop->set_dqblk) 229 return -ENOSYS; 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); 234 } 235 236 static int quota_getxquota(struct super_block *sb, int type, qid_t id, 237 void __user *addr) 238 { 239 struct fs_disk_quota fdq; 240 struct kqid qid; 241 int ret; 242 243 if (!sb->s_qcop->get_dqblk) 244 return -ENOSYS; 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); 249 if (!ret && copy_to_user(addr, &fdq, sizeof(fdq))) 250 return -EFAULT; 251 return ret; 252 } 253 254 /* Copy parameters and call proper function */ 255 static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, 256 void __user *addr, struct path *path) 257 { 258 int ret; 259 260 if (type >= (XQM_COMMAND(cmd) ? XQM_MAXQUOTAS : MAXQUOTAS)) 261 return -EINVAL; 262 if (!sb->s_qcop) 263 return -ENOSYS; 264 265 ret = check_quotactl_permission(sb, type, cmd, id); 266 if (ret < 0) 267 return ret; 268 269 switch (cmd) { 270 case Q_QUOTAON: 271 return quota_quotaon(sb, type, cmd, id, path); 272 case Q_QUOTAOFF: 273 if (!sb->s_qcop->quota_off) 274 return -ENOSYS; 275 return sb->s_qcop->quota_off(sb, type); 276 case Q_GETFMT: 277 return quota_getfmt(sb, type, addr); 278 case Q_GETINFO: 279 return quota_getinfo(sb, type, addr); 280 case Q_SETINFO: 281 return quota_setinfo(sb, type, addr); 282 case Q_GETQUOTA: 283 return quota_getquota(sb, type, id, addr); 284 case Q_SETQUOTA: 285 return quota_setquota(sb, type, id, addr); 286 case Q_SYNC: 287 if (!sb->s_qcop->quota_sync) 288 return -ENOSYS; 289 return sb->s_qcop->quota_sync(sb, type); 290 case Q_XQUOTAON: 291 case Q_XQUOTAOFF: 292 case Q_XQUOTARM: 293 return quota_setxstate(sb, cmd, addr); 294 case Q_XGETQSTAT: 295 return quota_getxstate(sb, addr); 296 case Q_XSETQLIM: 297 return quota_setxquota(sb, type, id, addr); 298 case Q_XGETQUOTA: 299 return quota_getxquota(sb, type, id, addr); 300 case Q_XQUOTASYNC: 301 if (sb->s_flags & MS_RDONLY) 302 return -EROFS; 303 /* XFS quotas are fully coherent now, making this call a noop */ 304 return 0; 305 default: 306 return -EINVAL; 307 } 308 } 309 310 #ifdef CONFIG_BLOCK 311 312 /* Return 1 if 'cmd' will block on frozen filesystem */ 313 static int quotactl_cmd_write(int cmd) 314 { 315 switch (cmd) { 316 case Q_GETFMT: 317 case Q_GETINFO: 318 case Q_SYNC: 319 case Q_XGETQSTAT: 320 case Q_XGETQUOTA: 321 case Q_XQUOTASYNC: 322 return 0; 323 } 324 return 1; 325 } 326 327 #endif /* CONFIG_BLOCK */ 328 329 /* 330 * look up a superblock on which quota ops will be performed 331 * - use the name of a block device to find the superblock thereon 332 */ 333 static struct super_block *quotactl_block(const char __user *special, int cmd) 334 { 335 #ifdef CONFIG_BLOCK 336 struct block_device *bdev; 337 struct super_block *sb; 338 struct filename *tmp = getname(special); 339 340 if (IS_ERR(tmp)) 341 return ERR_CAST(tmp); 342 bdev = lookup_bdev(tmp->name); 343 putname(tmp); 344 if (IS_ERR(bdev)) 345 return ERR_CAST(bdev); 346 if (quotactl_cmd_write(cmd)) 347 sb = get_super_thawed(bdev); 348 else 349 sb = get_super(bdev); 350 bdput(bdev); 351 if (!sb) 352 return ERR_PTR(-ENODEV); 353 354 return sb; 355 #else 356 return ERR_PTR(-ENODEV); 357 #endif 358 } 359 360 /* 361 * This is the system call interface. This communicates with 362 * the user-level programs. Currently this only supports diskquota 363 * calls. Maybe we need to add the process quotas etc. in the future, 364 * but we probably should use rlimits for that. 365 */ 366 SYSCALL_DEFINE4(quotactl, unsigned int, cmd, const char __user *, special, 367 qid_t, id, void __user *, addr) 368 { 369 uint cmds, type; 370 struct super_block *sb = NULL; 371 struct path path, *pathp = NULL; 372 int ret; 373 374 cmds = cmd >> SUBCMDSHIFT; 375 type = cmd & SUBCMDMASK; 376 377 /* 378 * As a special case Q_SYNC can be called without a specific device. 379 * It will iterate all superblocks that have quota enabled and call 380 * the sync action on each of them. 381 */ 382 if (!special) { 383 if (cmds == Q_SYNC) 384 return quota_sync_all(type); 385 return -ENODEV; 386 } 387 388 /* 389 * Path for quotaon has to be resolved before grabbing superblock 390 * because that gets s_umount sem which is also possibly needed by path 391 * resolution (think about autofs) and thus deadlocks could arise. 392 */ 393 if (cmds == Q_QUOTAON) { 394 ret = user_path_at(AT_FDCWD, addr, LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT, &path); 395 if (ret) 396 pathp = ERR_PTR(ret); 397 else 398 pathp = &path; 399 } 400 401 sb = quotactl_block(special, cmds); 402 if (IS_ERR(sb)) { 403 ret = PTR_ERR(sb); 404 goto out; 405 } 406 407 ret = do_quotactl(sb, type, cmds, id, addr, pathp); 408 409 drop_super(sb); 410 out: 411 if (pathp && !IS_ERR(pathp)) 412 path_put(pathp); 413 return ret; 414 } 415