diff options
Diffstat (limited to 'fs/autofs4/dev-ioctl.c')
| -rw-r--r-- | fs/autofs4/dev-ioctl.c | 75 |
1 files changed, 40 insertions, 35 deletions
diff --git a/fs/autofs4/dev-ioctl.c b/fs/autofs4/dev-ioctl.c index 63b7c7afe8df..025e105bffea 100644 --- a/fs/autofs4/dev-ioctl.c +++ b/fs/autofs4/dev-ioctl.c | |||
| @@ -124,7 +124,7 @@ static inline void free_dev_ioctl(struct autofs_dev_ioctl *param) | |||
| 124 | 124 | ||
| 125 | /* | 125 | /* |
| 126 | * Check sanity of parameter control fields and if a path is present | 126 | * Check sanity of parameter control fields and if a path is present |
| 127 | * check that it has a "/" and is terminated. | 127 | * check that it is terminated and contains at least one "/". |
| 128 | */ | 128 | */ |
| 129 | static int validate_dev_ioctl(int cmd, struct autofs_dev_ioctl *param) | 129 | static int validate_dev_ioctl(int cmd, struct autofs_dev_ioctl *param) |
| 130 | { | 130 | { |
| @@ -138,15 +138,16 @@ static int validate_dev_ioctl(int cmd, struct autofs_dev_ioctl *param) | |||
| 138 | } | 138 | } |
| 139 | 139 | ||
| 140 | if (param->size > sizeof(*param)) { | 140 | if (param->size > sizeof(*param)) { |
| 141 | err = check_name(param->path); | 141 | err = invalid_str(param->path, |
| 142 | (void *) ((size_t) param + param->size)); | ||
| 142 | if (err) { | 143 | if (err) { |
| 143 | AUTOFS_WARN("invalid path supplied for cmd(0x%08x)", | 144 | AUTOFS_WARN( |
| 144 | cmd); | 145 | "path string terminator missing for cmd(0x%08x)", |
| 146 | cmd); | ||
| 145 | goto out; | 147 | goto out; |
| 146 | } | 148 | } |
| 147 | 149 | ||
| 148 | err = invalid_str(param->path, | 150 | err = check_name(param->path); |
| 149 | (void *) ((size_t) param + param->size)); | ||
| 150 | if (err) { | 151 | if (err) { |
| 151 | AUTOFS_WARN("invalid path supplied for cmd(0x%08x)", | 152 | AUTOFS_WARN("invalid path supplied for cmd(0x%08x)", |
| 152 | cmd); | 153 | cmd); |
| @@ -180,7 +181,7 @@ static int autofs_dev_ioctl_protover(struct file *fp, | |||
| 180 | struct autofs_sb_info *sbi, | 181 | struct autofs_sb_info *sbi, |
| 181 | struct autofs_dev_ioctl *param) | 182 | struct autofs_dev_ioctl *param) |
| 182 | { | 183 | { |
| 183 | param->arg1 = sbi->version; | 184 | param->protover.version = sbi->version; |
| 184 | return 0; | 185 | return 0; |
| 185 | } | 186 | } |
| 186 | 187 | ||
| @@ -189,7 +190,7 @@ static int autofs_dev_ioctl_protosubver(struct file *fp, | |||
| 189 | struct autofs_sb_info *sbi, | 190 | struct autofs_sb_info *sbi, |
| 190 | struct autofs_dev_ioctl *param) | 191 | struct autofs_dev_ioctl *param) |
| 191 | { | 192 | { |
| 192 | param->arg1 = sbi->sub_version; | 193 | param->protosubver.sub_version = sbi->sub_version; |
| 193 | return 0; | 194 | return 0; |
| 194 | } | 195 | } |
| 195 | 196 | ||
| @@ -335,13 +336,13 @@ static int autofs_dev_ioctl_openmount(struct file *fp, | |||
| 335 | int err, fd; | 336 | int err, fd; |
| 336 | 337 | ||
| 337 | /* param->path has already been checked */ | 338 | /* param->path has already been checked */ |
| 338 | if (!param->arg1) | 339 | if (!param->openmount.devid) |
| 339 | return -EINVAL; | 340 | return -EINVAL; |
| 340 | 341 | ||
| 341 | param->ioctlfd = -1; | 342 | param->ioctlfd = -1; |
| 342 | 343 | ||
| 343 | path = param->path; | 344 | path = param->path; |
| 344 | devid = param->arg1; | 345 | devid = param->openmount.devid; |
| 345 | 346 | ||
| 346 | err = 0; | 347 | err = 0; |
| 347 | fd = autofs_dev_ioctl_open_mountpoint(path, devid); | 348 | fd = autofs_dev_ioctl_open_mountpoint(path, devid); |
| @@ -373,7 +374,7 @@ static int autofs_dev_ioctl_ready(struct file *fp, | |||
| 373 | { | 374 | { |
| 374 | autofs_wqt_t token; | 375 | autofs_wqt_t token; |
| 375 | 376 | ||
| 376 | token = (autofs_wqt_t) param->arg1; | 377 | token = (autofs_wqt_t) param->ready.token; |
| 377 | return autofs4_wait_release(sbi, token, 0); | 378 | return autofs4_wait_release(sbi, token, 0); |
| 378 | } | 379 | } |
| 379 | 380 | ||
| @@ -388,8 +389,8 @@ static int autofs_dev_ioctl_fail(struct file *fp, | |||
| 388 | autofs_wqt_t token; | 389 | autofs_wqt_t token; |
| 389 | int status; | 390 | int status; |
| 390 | 391 | ||
| 391 | token = (autofs_wqt_t) param->arg1; | 392 | token = (autofs_wqt_t) param->fail.token; |
| 392 | status = param->arg2 ? param->arg2 : -ENOENT; | 393 | status = param->fail.status ? param->fail.status : -ENOENT; |
| 393 | return autofs4_wait_release(sbi, token, status); | 394 | return autofs4_wait_release(sbi, token, status); |
| 394 | } | 395 | } |
| 395 | 396 | ||
| @@ -412,10 +413,10 @@ static int autofs_dev_ioctl_setpipefd(struct file *fp, | |||
| 412 | int pipefd; | 413 | int pipefd; |
| 413 | int err = 0; | 414 | int err = 0; |
| 414 | 415 | ||
| 415 | if (param->arg1 == -1) | 416 | if (param->setpipefd.pipefd == -1) |
| 416 | return -EINVAL; | 417 | return -EINVAL; |
| 417 | 418 | ||
| 418 | pipefd = param->arg1; | 419 | pipefd = param->setpipefd.pipefd; |
| 419 | 420 | ||
| 420 | mutex_lock(&sbi->wq_mutex); | 421 | mutex_lock(&sbi->wq_mutex); |
| 421 | if (!sbi->catatonic) { | 422 | if (!sbi->catatonic) { |
| @@ -457,8 +458,8 @@ static int autofs_dev_ioctl_timeout(struct file *fp, | |||
| 457 | { | 458 | { |
| 458 | unsigned long timeout; | 459 | unsigned long timeout; |
| 459 | 460 | ||
| 460 | timeout = param->arg1; | 461 | timeout = param->timeout.timeout; |
| 461 | param->arg1 = sbi->exp_timeout / HZ; | 462 | param->timeout.timeout = sbi->exp_timeout / HZ; |
| 462 | sbi->exp_timeout = timeout * HZ; | 463 | sbi->exp_timeout = timeout * HZ; |
| 463 | return 0; | 464 | return 0; |
| 464 | } | 465 | } |
| @@ -489,7 +490,7 @@ static int autofs_dev_ioctl_requester(struct file *fp, | |||
| 489 | path = param->path; | 490 | path = param->path; |
| 490 | devid = sbi->sb->s_dev; | 491 | devid = sbi->sb->s_dev; |
| 491 | 492 | ||
| 492 | param->arg1 = param->arg2 = -1; | 493 | param->requester.uid = param->requester.gid = -1; |
| 493 | 494 | ||
| 494 | /* Get nameidata of the parent directory */ | 495 | /* Get nameidata of the parent directory */ |
| 495 | err = path_lookup(path, LOOKUP_PARENT, &nd); | 496 | err = path_lookup(path, LOOKUP_PARENT, &nd); |
| @@ -505,8 +506,8 @@ static int autofs_dev_ioctl_requester(struct file *fp, | |||
| 505 | err = 0; | 506 | err = 0; |
| 506 | autofs4_expire_wait(nd.path.dentry); | 507 | autofs4_expire_wait(nd.path.dentry); |
| 507 | spin_lock(&sbi->fs_lock); | 508 | spin_lock(&sbi->fs_lock); |
| 508 | param->arg1 = ino->uid; | 509 | param->requester.uid = ino->uid; |
| 509 | param->arg2 = ino->gid; | 510 | param->requester.gid = ino->gid; |
| 510 | spin_unlock(&sbi->fs_lock); | 511 | spin_unlock(&sbi->fs_lock); |
| 511 | } | 512 | } |
| 512 | 513 | ||
| @@ -529,10 +530,10 @@ static int autofs_dev_ioctl_expire(struct file *fp, | |||
| 529 | int err = -EAGAIN; | 530 | int err = -EAGAIN; |
| 530 | int how; | 531 | int how; |
| 531 | 532 | ||
| 532 | how = param->arg1; | 533 | how = param->expire.how; |
| 533 | mnt = fp->f_path.mnt; | 534 | mnt = fp->f_path.mnt; |
| 534 | 535 | ||
| 535 | if (sbi->type & AUTOFS_TYPE_TRIGGER) | 536 | if (autofs_type_trigger(sbi->type)) |
| 536 | dentry = autofs4_expire_direct(sbi->sb, mnt, sbi, how); | 537 | dentry = autofs4_expire_direct(sbi->sb, mnt, sbi, how); |
| 537 | else | 538 | else |
| 538 | dentry = autofs4_expire_indirect(sbi->sb, mnt, sbi, how); | 539 | dentry = autofs4_expire_indirect(sbi->sb, mnt, sbi, how); |
| @@ -565,9 +566,9 @@ static int autofs_dev_ioctl_askumount(struct file *fp, | |||
| 565 | struct autofs_sb_info *sbi, | 566 | struct autofs_sb_info *sbi, |
| 566 | struct autofs_dev_ioctl *param) | 567 | struct autofs_dev_ioctl *param) |
| 567 | { | 568 | { |
| 568 | param->arg1 = 0; | 569 | param->askumount.may_umount = 0; |
| 569 | if (may_umount(fp->f_path.mnt)) | 570 | if (may_umount(fp->f_path.mnt)) |
| 570 | param->arg1 = 1; | 571 | param->askumount.may_umount = 1; |
| 571 | return 0; | 572 | return 0; |
| 572 | } | 573 | } |
| 573 | 574 | ||
| @@ -600,6 +601,7 @@ static int autofs_dev_ioctl_ismountpoint(struct file *fp, | |||
| 600 | struct nameidata nd; | 601 | struct nameidata nd; |
| 601 | const char *path; | 602 | const char *path; |
| 602 | unsigned int type; | 603 | unsigned int type; |
| 604 | unsigned int devid, magic; | ||
| 603 | int err = -ENOENT; | 605 | int err = -ENOENT; |
| 604 | 606 | ||
| 605 | if (param->size <= sizeof(*param)) { | 607 | if (param->size <= sizeof(*param)) { |
| @@ -608,13 +610,13 @@ static int autofs_dev_ioctl_ismountpoint(struct file *fp, | |||
| 608 | } | 610 | } |
| 609 | 611 | ||
| 610 | path = param->path; | 612 | path = param->path; |
| 611 | type = param->arg1; | 613 | type = param->ismountpoint.in.type; |
| 612 | 614 | ||
| 613 | param->arg1 = 0; | 615 | param->ismountpoint.out.devid = devid = 0; |
| 614 | param->arg2 = 0; | 616 | param->ismountpoint.out.magic = magic = 0; |
| 615 | 617 | ||
| 616 | if (!fp || param->ioctlfd == -1) { | 618 | if (!fp || param->ioctlfd == -1) { |
| 617 | if (type == AUTOFS_TYPE_ANY) { | 619 | if (autofs_type_any(type)) { |
| 618 | struct super_block *sb; | 620 | struct super_block *sb; |
| 619 | 621 | ||
| 620 | err = path_lookup(path, LOOKUP_FOLLOW, &nd); | 622 | err = path_lookup(path, LOOKUP_FOLLOW, &nd); |
| @@ -622,7 +624,7 @@ static int autofs_dev_ioctl_ismountpoint(struct file *fp, | |||
| 622 | goto out; | 624 | goto out; |
| 623 | 625 | ||
| 624 | sb = nd.path.dentry->d_sb; | 626 | sb = nd.path.dentry->d_sb; |
| 625 | param->arg1 = new_encode_dev(sb->s_dev); | 627 | devid = new_encode_dev(sb->s_dev); |
| 626 | } else { | 628 | } else { |
| 627 | struct autofs_info *ino; | 629 | struct autofs_info *ino; |
| 628 | 630 | ||
| @@ -635,38 +637,41 @@ static int autofs_dev_ioctl_ismountpoint(struct file *fp, | |||
| 635 | goto out_release; | 637 | goto out_release; |
| 636 | 638 | ||
| 637 | ino = autofs4_dentry_ino(nd.path.dentry); | 639 | ino = autofs4_dentry_ino(nd.path.dentry); |
| 638 | param->arg1 = autofs4_get_dev(ino->sbi); | 640 | devid = autofs4_get_dev(ino->sbi); |
| 639 | } | 641 | } |
| 640 | 642 | ||
| 641 | err = 0; | 643 | err = 0; |
| 642 | if (nd.path.dentry->d_inode && | 644 | if (nd.path.dentry->d_inode && |
| 643 | nd.path.mnt->mnt_root == nd.path.dentry) { | 645 | nd.path.mnt->mnt_root == nd.path.dentry) { |
| 644 | err = 1; | 646 | err = 1; |
| 645 | param->arg2 = nd.path.dentry->d_inode->i_sb->s_magic; | 647 | magic = nd.path.dentry->d_inode->i_sb->s_magic; |
| 646 | } | 648 | } |
| 647 | } else { | 649 | } else { |
| 648 | dev_t devid = new_encode_dev(sbi->sb->s_dev); | 650 | dev_t dev = autofs4_get_dev(sbi); |
| 649 | 651 | ||
| 650 | err = path_lookup(path, LOOKUP_PARENT, &nd); | 652 | err = path_lookup(path, LOOKUP_PARENT, &nd); |
| 651 | if (err) | 653 | if (err) |
| 652 | goto out; | 654 | goto out; |
| 653 | 655 | ||
| 654 | err = autofs_dev_ioctl_find_super(&nd, devid); | 656 | err = autofs_dev_ioctl_find_super(&nd, dev); |
| 655 | if (err) | 657 | if (err) |
| 656 | goto out_release; | 658 | goto out_release; |
| 657 | 659 | ||
| 658 | param->arg1 = autofs4_get_dev(sbi); | 660 | devid = dev; |
| 659 | 661 | ||
| 660 | err = have_submounts(nd.path.dentry); | 662 | err = have_submounts(nd.path.dentry); |
| 661 | 663 | ||
| 662 | if (nd.path.mnt->mnt_mountpoint != nd.path.mnt->mnt_root) { | 664 | if (nd.path.mnt->mnt_mountpoint != nd.path.mnt->mnt_root) { |
| 663 | if (follow_down(&nd.path.mnt, &nd.path.dentry)) { | 665 | if (follow_down(&nd.path.mnt, &nd.path.dentry)) { |
| 664 | struct inode *inode = nd.path.dentry->d_inode; | 666 | struct inode *inode = nd.path.dentry->d_inode; |
| 665 | param->arg2 = inode->i_sb->s_magic; | 667 | magic = inode->i_sb->s_magic; |
| 666 | } | 668 | } |
| 667 | } | 669 | } |
| 668 | } | 670 | } |
| 669 | 671 | ||
| 672 | param->ismountpoint.out.devid = devid; | ||
| 673 | param->ismountpoint.out.magic = magic; | ||
| 674 | |||
| 670 | out_release: | 675 | out_release: |
| 671 | path_put(&nd.path); | 676 | path_put(&nd.path); |
| 672 | out: | 677 | out: |
