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 #ifdef CONFIG_QUOTA 163 void sync_quota_sb(struct super_block *sb, int type) 164 { 165 int cnt; 166 167 if (!sb->s_qcop->quota_sync) 168 return; 169 170 sb->s_qcop->quota_sync(sb, type); 171 172 if (sb_dqopt(sb)->flags & DQUOT_QUOTA_SYS_FILE) 173 return; 174 /* This is not very clever (and fast) but currently I don't know about 175 * any other simple way of getting quota data to disk and we must get 176 * them there for userspace to be visible... */ 177 if (sb->s_op->sync_fs) 178 sb->s_op->sync_fs(sb, 1); 179 sync_blockdev(sb->s_bdev); 180 181 /* 182 * Now when everything is written we can discard the pagecache so 183 * that userspace sees the changes. 184 */ 185 mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); 186 for (cnt = 0; cnt < MAXQUOTAS; cnt++) { 187 if (type != -1 && cnt != type) 188 continue; 189 if (!sb_has_quota_active(sb, cnt)) 190 continue; 191 mutex_lock_nested(&sb_dqopt(sb)->files[cnt]->i_mutex, 192 I_MUTEX_QUOTA); 193 truncate_inode_pages(&sb_dqopt(sb)->files[cnt]->i_data, 0); 194 mutex_unlock(&sb_dqopt(sb)->files[cnt]->i_mutex); 195 } 196 mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); 197 } 198 #endif 199 200 static void sync_dquots(int type) 201 { 202 struct super_block *sb; 203 int cnt; 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) 226 sync_quota_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 if (sb) 305 sync_quota_sb(sb, type); 306 else 307 sync_dquots(type); 308 return 0; 309 310 case Q_XQUOTAON: 311 case Q_XQUOTAOFF: 312 case Q_XQUOTARM: { 313 __u32 flags; 314 315 if (copy_from_user(&flags, addr, sizeof(flags))) 316 return -EFAULT; 317 return sb->s_qcop->set_xstate(sb, flags, cmd); 318 } 319 case Q_XGETQSTAT: { 320 struct fs_quota_stat fqs; 321 322 if ((ret = sb->s_qcop->get_xstate(sb, &fqs))) 323 return ret; 324 if (copy_to_user(addr, &fqs, sizeof(fqs))) 325 return -EFAULT; 326 return 0; 327 } 328 case Q_XSETQLIM: { 329 struct fs_disk_quota fdq; 330 331 if (copy_from_user(&fdq, addr, sizeof(fdq))) 332 return -EFAULT; 333 return sb->s_qcop->set_xquota(sb, type, id, &fdq); 334 } 335 case Q_XGETQUOTA: { 336 struct fs_disk_quota fdq; 337 338 ret = sb->s_qcop->get_xquota(sb, type, id, &fdq); 339 if (ret) 340 return ret; 341 if (copy_to_user(addr, &fdq, sizeof(fdq))) 342 return -EFAULT; 343 return 0; 344 } 345 case Q_XQUOTASYNC: 346 return sb->s_qcop->quota_sync(sb, type); 347 /* We never reach here unless validity check is broken */ 348 default: 349 BUG(); 350 } 351 return 0; 352 } 353 354 /* 355 * look up a superblock on which quota ops will be performed 356 * - use the name of a block device to find the superblock thereon 357 */ 358 static struct super_block *quotactl_block(const char __user *special) 359 { 360 #ifdef CONFIG_BLOCK 361 struct block_device *bdev; 362 struct super_block *sb; 363 char *tmp = getname(special); 364 365 if (IS_ERR(tmp)) 366 return ERR_CAST(tmp); 367 bdev = lookup_bdev(tmp); 368 putname(tmp); 369 if (IS_ERR(bdev)) 370 return ERR_CAST(bdev); 371 sb = get_super(bdev); 372 bdput(bdev); 373 if (!sb) 374 return ERR_PTR(-ENODEV); 375 376 return sb; 377 #else 378 return ERR_PTR(-ENODEV); 379 #endif 380 } 381 382 /* 383 * This is the system call interface. This communicates with 384 * the user-level programs. Currently this only supports diskquota 385 * calls. Maybe we need to add the process quotas etc. in the future, 386 * but we probably should use rlimits for that. 387 */ 388 SYSCALL_DEFINE4(quotactl, unsigned int, cmd, const char __user *, special, 389 qid_t, id, void __user *, addr) 390 { 391 uint cmds, type; 392 struct super_block *sb = NULL; 393 int ret; 394 395 cmds = cmd >> SUBCMDSHIFT; 396 type = cmd & SUBCMDMASK; 397 398 if (cmds != Q_SYNC || special) { 399 sb = quotactl_block(special); 400 if (IS_ERR(sb)) 401 return PTR_ERR(sb); 402 } 403 404 ret = check_quotactl_valid(sb, type, cmds, id); 405 if (ret >= 0) 406 ret = do_quotactl(sb, type, cmds, id, addr); 407 if (sb) 408 drop_super(sb); 409 410 return ret; 411 } 412 413 #if defined(CONFIG_COMPAT_FOR_U64_ALIGNMENT) 414 /* 415 * This code works only for 32 bit quota tools over 64 bit OS (x86_64, ia64) 416 * and is necessary due to alignment problems. 417 */ 418 struct compat_if_dqblk { 419 compat_u64 dqb_bhardlimit; 420 compat_u64 dqb_bsoftlimit; 421 compat_u64 dqb_curspace; 422 compat_u64 dqb_ihardlimit; 423 compat_u64 dqb_isoftlimit; 424 compat_u64 dqb_curinodes; 425 compat_u64 dqb_btime; 426 compat_u64 dqb_itime; 427 compat_uint_t dqb_valid; 428 }; 429 430 /* XFS structures */ 431 struct compat_fs_qfilestat { 432 compat_u64 dqb_bhardlimit; 433 compat_u64 qfs_nblks; 434 compat_uint_t qfs_nextents; 435 }; 436 437 struct compat_fs_quota_stat { 438 __s8 qs_version; 439 __u16 qs_flags; 440 __s8 qs_pad; 441 struct compat_fs_qfilestat qs_uquota; 442 struct compat_fs_qfilestat qs_gquota; 443 compat_uint_t qs_incoredqs; 444 compat_int_t qs_btimelimit; 445 compat_int_t qs_itimelimit; 446 compat_int_t qs_rtbtimelimit; 447 __u16 qs_bwarnlimit; 448 __u16 qs_iwarnlimit; 449 }; 450 451 asmlinkage long sys32_quotactl(unsigned int cmd, const char __user *special, 452 qid_t id, void __user *addr) 453 { 454 unsigned int cmds; 455 struct if_dqblk __user *dqblk; 456 struct compat_if_dqblk __user *compat_dqblk; 457 struct fs_quota_stat __user *fsqstat; 458 struct compat_fs_quota_stat __user *compat_fsqstat; 459 compat_uint_t data; 460 u16 xdata; 461 long ret; 462 463 cmds = cmd >> SUBCMDSHIFT; 464 465 switch (cmds) { 466 case Q_GETQUOTA: 467 dqblk = compat_alloc_user_space(sizeof(struct if_dqblk)); 468 compat_dqblk = addr; 469 ret = sys_quotactl(cmd, special, id, dqblk); 470 if (ret) 471 break; 472 if (copy_in_user(compat_dqblk, dqblk, sizeof(*compat_dqblk)) || 473 get_user(data, &dqblk->dqb_valid) || 474 put_user(data, &compat_dqblk->dqb_valid)) 475 ret = -EFAULT; 476 break; 477 case Q_SETQUOTA: 478 dqblk = compat_alloc_user_space(sizeof(struct if_dqblk)); 479 compat_dqblk = addr; 480 ret = -EFAULT; 481 if (copy_in_user(dqblk, compat_dqblk, sizeof(*compat_dqblk)) || 482 get_user(data, &compat_dqblk->dqb_valid) || 483 put_user(data, &dqblk->dqb_valid)) 484 break; 485 ret = sys_quotactl(cmd, special, id, dqblk); 486 break; 487 case Q_XGETQSTAT: 488 fsqstat = compat_alloc_user_space(sizeof(struct fs_quota_stat)); 489 compat_fsqstat = addr; 490 ret = sys_quotactl(cmd, special, id, fsqstat); 491 if (ret) 492 break; 493 ret = -EFAULT; 494 /* Copying qs_version, qs_flags, qs_pad */ 495 if (copy_in_user(compat_fsqstat, fsqstat, 496 offsetof(struct compat_fs_quota_stat, qs_uquota))) 497 break; 498 /* Copying qs_uquota */ 499 if (copy_in_user(&compat_fsqstat->qs_uquota, 500 &fsqstat->qs_uquota, 501 sizeof(compat_fsqstat->qs_uquota)) || 502 get_user(data, &fsqstat->qs_uquota.qfs_nextents) || 503 put_user(data, &compat_fsqstat->qs_uquota.qfs_nextents)) 504 break; 505 /* Copying qs_gquota */ 506 if (copy_in_user(&compat_fsqstat->qs_gquota, 507 &fsqstat->qs_gquota, 508 sizeof(compat_fsqstat->qs_gquota)) || 509 get_user(data, &fsqstat->qs_gquota.qfs_nextents) || 510 put_user(data, &compat_fsqstat->qs_gquota.qfs_nextents)) 511 break; 512 /* Copying the rest */ 513 if (copy_in_user(&compat_fsqstat->qs_incoredqs, 514 &fsqstat->qs_incoredqs, 515 sizeof(struct compat_fs_quota_stat) - 516 offsetof(struct compat_fs_quota_stat, qs_incoredqs)) || 517 get_user(xdata, &fsqstat->qs_iwarnlimit) || 518 put_user(xdata, &compat_fsqstat->qs_iwarnlimit)) 519 break; 520 ret = 0; 521 break; 522 default: 523 ret = sys_quotactl(cmd, special, id, addr); 524 } 525 return ret; 526 } 527 #endif 528