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 <asm/uaccess.h> 13 #include <linux/compat.h> 14 #include <linux/kernel.h> 15 #include <linux/security.h> 16 #include <linux/syscalls.h> 17 #include <linux/buffer_head.h> 18 #include <linux/capability.h> 19 #include <linux/quotaops.h> 20 #include <linux/types.h> 21 22 /* Check validity of generic quotactl commands */ 23 static int generic_quotactl_valid(struct super_block *sb, int type, int cmd, 24 qid_t id) 25 { 26 if (type >= MAXQUOTAS) 27 return -EINVAL; 28 if (!sb && cmd != Q_SYNC) 29 return -ENODEV; 30 /* Is operation supported? */ 31 if (sb && !sb->s_qcop) 32 return -ENOSYS; 33 34 switch (cmd) { 35 case Q_GETFMT: 36 break; 37 case Q_QUOTAON: 38 if (!sb->s_qcop->quota_on) 39 return -ENOSYS; 40 break; 41 case Q_QUOTAOFF: 42 if (!sb->s_qcop->quota_off) 43 return -ENOSYS; 44 break; 45 case Q_SETINFO: 46 if (!sb->s_qcop->set_info) 47 return -ENOSYS; 48 break; 49 case Q_GETINFO: 50 if (!sb->s_qcop->get_info) 51 return -ENOSYS; 52 break; 53 case Q_SETQUOTA: 54 if (!sb->s_qcop->set_dqblk) 55 return -ENOSYS; 56 break; 57 case Q_GETQUOTA: 58 if (!sb->s_qcop->get_dqblk) 59 return -ENOSYS; 60 break; 61 case Q_SYNC: 62 if (sb && !sb->s_qcop->quota_sync) 63 return -ENOSYS; 64 break; 65 default: 66 return -EINVAL; 67 } 68 69 /* Is quota turned on for commands which need it? */ 70 switch (cmd) { 71 case Q_GETFMT: 72 case Q_GETINFO: 73 case Q_SETINFO: 74 case Q_SETQUOTA: 75 case Q_GETQUOTA: 76 /* This is just an informative test so we are satisfied 77 * without the lock */ 78 if (!sb_has_quota_active(sb, type)) 79 return -ESRCH; 80 } 81 82 /* Check privileges */ 83 if (cmd == Q_GETQUOTA) { 84 if (((type == USRQUOTA && current_euid() != id) || 85 (type == GRPQUOTA && !in_egroup_p(id))) && 86 !capable(CAP_SYS_ADMIN)) 87 return -EPERM; 88 } 89 else if (cmd != Q_GETFMT && cmd != Q_SYNC && cmd != Q_GETINFO) 90 if (!capable(CAP_SYS_ADMIN)) 91 return -EPERM; 92 93 return 0; 94 } 95 96 /* Check validity of XFS Quota Manager commands */ 97 static int xqm_quotactl_valid(struct super_block *sb, int type, int cmd, 98 qid_t id) 99 { 100 if (type >= XQM_MAXQUOTAS) 101 return -EINVAL; 102 if (!sb) 103 return -ENODEV; 104 if (!sb->s_qcop) 105 return -ENOSYS; 106 107 switch (cmd) { 108 case Q_XQUOTAON: 109 case Q_XQUOTAOFF: 110 case Q_XQUOTARM: 111 if (!sb->s_qcop->set_xstate) 112 return -ENOSYS; 113 break; 114 case Q_XGETQSTAT: 115 if (!sb->s_qcop->get_xstate) 116 return -ENOSYS; 117 break; 118 case Q_XSETQLIM: 119 if (!sb->s_qcop->set_xquota) 120 return -ENOSYS; 121 break; 122 case Q_XGETQUOTA: 123 if (!sb->s_qcop->get_xquota) 124 return -ENOSYS; 125 break; 126 case Q_XQUOTASYNC: 127 if (!sb->s_qcop->quota_sync) 128 return -ENOSYS; 129 break; 130 default: 131 return -EINVAL; 132 } 133 134 /* Check privileges */ 135 if (cmd == Q_XGETQUOTA) { 136 if (((type == XQM_USRQUOTA && current_euid() != id) || 137 (type == XQM_GRPQUOTA && !in_egroup_p(id))) && 138 !capable(CAP_SYS_ADMIN)) 139 return -EPERM; 140 } else if (cmd != Q_XGETQSTAT && cmd != Q_XQUOTASYNC) { 141 if (!capable(CAP_SYS_ADMIN)) 142 return -EPERM; 143 } 144 145 return 0; 146 } 147 148 static int check_quotactl_valid(struct super_block *sb, int type, int cmd, 149 qid_t id) 150 { 151 int error; 152 153 if (XQM_COMMAND(cmd)) 154 error = xqm_quotactl_valid(sb, type, cmd, id); 155 else 156 error = generic_quotactl_valid(sb, type, cmd, id); 157 if (!error) 158 error = security_quotactl(cmd, type, id, sb); 159 return error; 160 } 161 162 static void quota_sync_sb(struct super_block *sb, int type) 163 { 164 int cnt; 165 166 sb->s_qcop->quota_sync(sb, type); 167 168 if (sb_dqopt(sb)->flags & DQUOT_QUOTA_SYS_FILE) 169 return; 170 /* This is not very clever (and fast) but currently I don't know about 171 * any other simple way of getting quota data to disk and we must get 172 * them there for userspace to be visible... */ 173 if (sb->s_op->sync_fs) 174 sb->s_op->sync_fs(sb, 1); 175 sync_blockdev(sb->s_bdev); 176 177 /* 178 * Now when everything is written we can discard the pagecache so 179 * that userspace sees the changes. 180 */ 181 mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); 182 for (cnt = 0; cnt < MAXQUOTAS; cnt++) { 183 if (type != -1 && cnt != type) 184 continue; 185 if (!sb_has_quota_active(sb, cnt)) 186 continue; 187 mutex_lock_nested(&sb_dqopt(sb)->files[cnt]->i_mutex, 188 I_MUTEX_QUOTA); 189 truncate_inode_pages(&sb_dqopt(sb)->files[cnt]->i_data, 0); 190 mutex_unlock(&sb_dqopt(sb)->files[cnt]->i_mutex); 191 } 192 mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); 193 } 194 195 void sync_dquots(struct super_block *sb, int type) 196 { 197 int cnt; 198 199 if (sb) { 200 if (sb->s_qcop->quota_sync) 201 quota_sync_sb(sb, type); 202 return; 203 } 204 205 spin_lock(&sb_lock); 206 restart: 207 list_for_each_entry(sb, &super_blocks, s_list) { 208 /* This test just improves performance so it needn't be 209 * reliable... */ 210 for (cnt = 0; cnt < MAXQUOTAS; cnt++) { 211 if (type != -1 && type != cnt) 212 continue; 213 if (!sb_has_quota_active(sb, cnt)) 214 continue; 215 if (!info_dirty(&sb_dqopt(sb)->info[cnt]) && 216 list_empty(&sb_dqopt(sb)->info[cnt].dqi_dirty_list)) 217 continue; 218 break; 219 } 220 if (cnt == MAXQUOTAS) 221 continue; 222 sb->s_count++; 223 spin_unlock(&sb_lock); 224 down_read(&sb->s_umount); 225 if (sb->s_root && sb->s_qcop->quota_sync) 226 quota_sync_sb(sb, type); 227 up_read(&sb->s_umount); 228 spin_lock(&sb_lock); 229 if (__put_super_and_need_restart(sb)) 230 goto restart; 231 } 232 spin_unlock(&sb_lock); 233 } 234 235 /* Copy parameters and call proper function */ 236 static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, 237 void __user *addr) 238 { 239 int ret; 240 241 switch (cmd) { 242 case Q_QUOTAON: { 243 char *pathname; 244 245 pathname = getname(addr); 246 if (IS_ERR(pathname)) 247 return PTR_ERR(pathname); 248 ret = sb->s_qcop->quota_on(sb, type, id, pathname, 0); 249 putname(pathname); 250 return ret; 251 } 252 case Q_QUOTAOFF: 253 return sb->s_qcop->quota_off(sb, type, 0); 254 255 case Q_GETFMT: { 256 __u32 fmt; 257 258 down_read(&sb_dqopt(sb)->dqptr_sem); 259 if (!sb_has_quota_active(sb, type)) { 260 up_read(&sb_dqopt(sb)->dqptr_sem); 261 return -ESRCH; 262 } 263 fmt = sb_dqopt(sb)->info[type].dqi_format->qf_fmt_id; 264 up_read(&sb_dqopt(sb)->dqptr_sem); 265 if (copy_to_user(addr, &fmt, sizeof(fmt))) 266 return -EFAULT; 267 return 0; 268 } 269 case Q_GETINFO: { 270 struct if_dqinfo info; 271 272 ret = sb->s_qcop->get_info(sb, type, &info); 273 if (ret) 274 return ret; 275 if (copy_to_user(addr, &info, sizeof(info))) 276 return -EFAULT; 277 return 0; 278 } 279 case Q_SETINFO: { 280 struct if_dqinfo info; 281 282 if (copy_from_user(&info, addr, sizeof(info))) 283 return -EFAULT; 284 return sb->s_qcop->set_info(sb, type, &info); 285 } 286 case Q_GETQUOTA: { 287 struct if_dqblk idq; 288 289 ret = sb->s_qcop->get_dqblk(sb, type, id, &idq); 290 if (ret) 291 return ret; 292 if (copy_to_user(addr, &idq, sizeof(idq))) 293 return -EFAULT; 294 return 0; 295 } 296 case Q_SETQUOTA: { 297 struct if_dqblk idq; 298 299 if (copy_from_user(&idq, addr, sizeof(idq))) 300 return -EFAULT; 301 return sb->s_qcop->set_dqblk(sb, type, id, &idq); 302 } 303 case Q_SYNC: 304 sync_dquots(sb, type); 305 return 0; 306 307 case Q_XQUOTAON: 308 case Q_XQUOTAOFF: 309 case Q_XQUOTARM: { 310 __u32 flags; 311 312 if (copy_from_user(&flags, addr, sizeof(flags))) 313 return -EFAULT; 314 return sb->s_qcop->set_xstate(sb, flags, cmd); 315 } 316 case Q_XGETQSTAT: { 317 struct fs_quota_stat fqs; 318 319 if ((ret = sb->s_qcop->get_xstate(sb, &fqs))) 320 return ret; 321 if (copy_to_user(addr, &fqs, sizeof(fqs))) 322 return -EFAULT; 323 return 0; 324 } 325 case Q_XSETQLIM: { 326 struct fs_disk_quota fdq; 327 328 if (copy_from_user(&fdq, addr, sizeof(fdq))) 329 return -EFAULT; 330 return sb->s_qcop->set_xquota(sb, type, id, &fdq); 331 } 332 case Q_XGETQUOTA: { 333 struct fs_disk_quota fdq; 334 335 ret = sb->s_qcop->get_xquota(sb, type, id, &fdq); 336 if (ret) 337 return ret; 338 if (copy_to_user(addr, &fdq, sizeof(fdq))) 339 return -EFAULT; 340 return 0; 341 } 342 case Q_XQUOTASYNC: 343 return sb->s_qcop->quota_sync(sb, type); 344 /* We never reach here unless validity check is broken */ 345 default: 346 BUG(); 347 } 348 return 0; 349 } 350 351 /* 352 * look up a superblock on which quota ops will be performed 353 * - use the name of a block device to find the superblock thereon 354 */ 355 static struct super_block *quotactl_block(const char __user *special) 356 { 357 #ifdef CONFIG_BLOCK 358 struct block_device *bdev; 359 struct super_block *sb; 360 char *tmp = getname(special); 361 362 if (IS_ERR(tmp)) 363 return ERR_CAST(tmp); 364 bdev = lookup_bdev(tmp); 365 putname(tmp); 366 if (IS_ERR(bdev)) 367 return ERR_CAST(bdev); 368 sb = get_super(bdev); 369 bdput(bdev); 370 if (!sb) 371 return ERR_PTR(-ENODEV); 372 373 return sb; 374 #else 375 return ERR_PTR(-ENODEV); 376 #endif 377 } 378 379 /* 380 * This is the system call interface. This communicates with 381 * the user-level programs. Currently this only supports diskquota 382 * calls. Maybe we need to add the process quotas etc. in the future, 383 * but we probably should use rlimits for that. 384 */ 385 SYSCALL_DEFINE4(quotactl, unsigned int, cmd, const char __user *, special, 386 qid_t, id, void __user *, addr) 387 { 388 uint cmds, type; 389 struct super_block *sb = NULL; 390 int ret; 391 392 cmds = cmd >> SUBCMDSHIFT; 393 type = cmd & SUBCMDMASK; 394 395 if (cmds != Q_SYNC || special) { 396 sb = quotactl_block(special); 397 if (IS_ERR(sb)) 398 return PTR_ERR(sb); 399 } 400 401 ret = check_quotactl_valid(sb, type, cmds, id); 402 if (ret >= 0) 403 ret = do_quotactl(sb, type, cmds, id, addr); 404 if (sb) 405 drop_super(sb); 406 407 return ret; 408 } 409 410 #if defined(CONFIG_COMPAT_FOR_U64_ALIGNMENT) 411 /* 412 * This code works only for 32 bit quota tools over 64 bit OS (x86_64, ia64) 413 * and is necessary due to alignment problems. 414 */ 415 struct compat_if_dqblk { 416 compat_u64 dqb_bhardlimit; 417 compat_u64 dqb_bsoftlimit; 418 compat_u64 dqb_curspace; 419 compat_u64 dqb_ihardlimit; 420 compat_u64 dqb_isoftlimit; 421 compat_u64 dqb_curinodes; 422 compat_u64 dqb_btime; 423 compat_u64 dqb_itime; 424 compat_uint_t dqb_valid; 425 }; 426 427 /* XFS structures */ 428 struct compat_fs_qfilestat { 429 compat_u64 dqb_bhardlimit; 430 compat_u64 qfs_nblks; 431 compat_uint_t qfs_nextents; 432 }; 433 434 struct compat_fs_quota_stat { 435 __s8 qs_version; 436 __u16 qs_flags; 437 __s8 qs_pad; 438 struct compat_fs_qfilestat qs_uquota; 439 struct compat_fs_qfilestat qs_gquota; 440 compat_uint_t qs_incoredqs; 441 compat_int_t qs_btimelimit; 442 compat_int_t qs_itimelimit; 443 compat_int_t qs_rtbtimelimit; 444 __u16 qs_bwarnlimit; 445 __u16 qs_iwarnlimit; 446 }; 447 448 asmlinkage long sys32_quotactl(unsigned int cmd, const char __user *special, 449 qid_t id, void __user *addr) 450 { 451 unsigned int cmds; 452 struct if_dqblk __user *dqblk; 453 struct compat_if_dqblk __user *compat_dqblk; 454 struct fs_quota_stat __user *fsqstat; 455 struct compat_fs_quota_stat __user *compat_fsqstat; 456 compat_uint_t data; 457 u16 xdata; 458 long ret; 459 460 cmds = cmd >> SUBCMDSHIFT; 461 462 switch (cmds) { 463 case Q_GETQUOTA: 464 dqblk = compat_alloc_user_space(sizeof(struct if_dqblk)); 465 compat_dqblk = addr; 466 ret = sys_quotactl(cmd, special, id, dqblk); 467 if (ret) 468 break; 469 if (copy_in_user(compat_dqblk, dqblk, sizeof(*compat_dqblk)) || 470 get_user(data, &dqblk->dqb_valid) || 471 put_user(data, &compat_dqblk->dqb_valid)) 472 ret = -EFAULT; 473 break; 474 case Q_SETQUOTA: 475 dqblk = compat_alloc_user_space(sizeof(struct if_dqblk)); 476 compat_dqblk = addr; 477 ret = -EFAULT; 478 if (copy_in_user(dqblk, compat_dqblk, sizeof(*compat_dqblk)) || 479 get_user(data, &compat_dqblk->dqb_valid) || 480 put_user(data, &dqblk->dqb_valid)) 481 break; 482 ret = sys_quotactl(cmd, special, id, dqblk); 483 break; 484 case Q_XGETQSTAT: 485 fsqstat = compat_alloc_user_space(sizeof(struct fs_quota_stat)); 486 compat_fsqstat = addr; 487 ret = sys_quotactl(cmd, special, id, fsqstat); 488 if (ret) 489 break; 490 ret = -EFAULT; 491 /* Copying qs_version, qs_flags, qs_pad */ 492 if (copy_in_user(compat_fsqstat, fsqstat, 493 offsetof(struct compat_fs_quota_stat, qs_uquota))) 494 break; 495 /* Copying qs_uquota */ 496 if (copy_in_user(&compat_fsqstat->qs_uquota, 497 &fsqstat->qs_uquota, 498 sizeof(compat_fsqstat->qs_uquota)) || 499 get_user(data, &fsqstat->qs_uquota.qfs_nextents) || 500 put_user(data, &compat_fsqstat->qs_uquota.qfs_nextents)) 501 break; 502 /* Copying qs_gquota */ 503 if (copy_in_user(&compat_fsqstat->qs_gquota, 504 &fsqstat->qs_gquota, 505 sizeof(compat_fsqstat->qs_gquota)) || 506 get_user(data, &fsqstat->qs_gquota.qfs_nextents) || 507 put_user(data, &compat_fsqstat->qs_gquota.qfs_nextents)) 508 break; 509 /* Copying the rest */ 510 if (copy_in_user(&compat_fsqstat->qs_incoredqs, 511 &fsqstat->qs_incoredqs, 512 sizeof(struct compat_fs_quota_stat) - 513 offsetof(struct compat_fs_quota_stat, qs_incoredqs)) || 514 get_user(xdata, &fsqstat->qs_iwarnlimit) || 515 put_user(xdata, &compat_fsqstat->qs_iwarnlimit)) 516 break; 517 ret = 0; 518 break; 519 default: 520 ret = sys_quotactl(cmd, special, id, addr); 521 } 522 return ret; 523 } 524 #endif 525