diff options
Diffstat (limited to 'fs/autofs4/dev-ioctl.c')
-rw-r--r-- | fs/autofs4/dev-ioctl.c | 78 |
1 files changed, 42 insertions, 36 deletions
diff --git a/fs/autofs4/dev-ioctl.c b/fs/autofs4/dev-ioctl.c index 33bf8cbfd051..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 | ||
@@ -308,7 +309,8 @@ static int autofs_dev_ioctl_open_mountpoint(const char *path, dev_t devid) | |||
308 | goto out; | 309 | goto out; |
309 | } | 310 | } |
310 | 311 | ||
311 | filp = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY); | 312 | filp = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY, |
313 | current_cred()); | ||
312 | if (IS_ERR(filp)) { | 314 | if (IS_ERR(filp)) { |
313 | err = PTR_ERR(filp); | 315 | err = PTR_ERR(filp); |
314 | goto out; | 316 | goto out; |
@@ -334,13 +336,13 @@ static int autofs_dev_ioctl_openmount(struct file *fp, | |||
334 | int err, fd; | 336 | int err, fd; |
335 | 337 | ||
336 | /* param->path has already been checked */ | 338 | /* param->path has already been checked */ |
337 | if (!param->arg1) | 339 | if (!param->openmount.devid) |
338 | return -EINVAL; | 340 | return -EINVAL; |
339 | 341 | ||
340 | param->ioctlfd = -1; | 342 | param->ioctlfd = -1; |
341 | 343 | ||
342 | path = param->path; | 344 | path = param->path; |
343 | devid = param->arg1; | 345 | devid = param->openmount.devid; |
344 | 346 | ||
345 | err = 0; | 347 | err = 0; |
346 | fd = autofs_dev_ioctl_open_mountpoint(path, devid); | 348 | fd = autofs_dev_ioctl_open_mountpoint(path, devid); |
@@ -372,7 +374,7 @@ static int autofs_dev_ioctl_ready(struct file *fp, | |||
372 | { | 374 | { |
373 | autofs_wqt_t token; | 375 | autofs_wqt_t token; |
374 | 376 | ||
375 | token = (autofs_wqt_t) param->arg1; | 377 | token = (autofs_wqt_t) param->ready.token; |
376 | return autofs4_wait_release(sbi, token, 0); | 378 | return autofs4_wait_release(sbi, token, 0); |
377 | } | 379 | } |
378 | 380 | ||
@@ -387,8 +389,8 @@ static int autofs_dev_ioctl_fail(struct file *fp, | |||
387 | autofs_wqt_t token; | 389 | autofs_wqt_t token; |
388 | int status; | 390 | int status; |
389 | 391 | ||
390 | token = (autofs_wqt_t) param->arg1; | 392 | token = (autofs_wqt_t) param->fail.token; |
391 | status = param->arg2 ? param->arg2 : -ENOENT; | 393 | status = param->fail.status ? param->fail.status : -ENOENT; |
392 | return autofs4_wait_release(sbi, token, status); | 394 | return autofs4_wait_release(sbi, token, status); |
393 | } | 395 | } |
394 | 396 | ||
@@ -411,10 +413,10 @@ static int autofs_dev_ioctl_setpipefd(struct file *fp, | |||
411 | int pipefd; | 413 | int pipefd; |
412 | int err = 0; | 414 | int err = 0; |
413 | 415 | ||
414 | if (param->arg1 == -1) | 416 | if (param->setpipefd.pipefd == -1) |
415 | return -EINVAL; | 417 | return -EINVAL; |
416 | 418 | ||
417 | pipefd = param->arg1; | 419 | pipefd = param->setpipefd.pipefd; |
418 | 420 | ||
419 | mutex_lock(&sbi->wq_mutex); | 421 | mutex_lock(&sbi->wq_mutex); |
420 | if (!sbi->catatonic) { | 422 | if (!sbi->catatonic) { |
@@ -456,8 +458,8 @@ static int autofs_dev_ioctl_timeout(struct file *fp, | |||
456 | { | 458 | { |
457 | unsigned long timeout; | 459 | unsigned long timeout; |
458 | 460 | ||
459 | timeout = param->arg1; | 461 | timeout = param->timeout.timeout; |
460 | param->arg1 = sbi->exp_timeout / HZ; | 462 | param->timeout.timeout = sbi->exp_timeout / HZ; |
461 | sbi->exp_timeout = timeout * HZ; | 463 | sbi->exp_timeout = timeout * HZ; |
462 | return 0; | 464 | return 0; |
463 | } | 465 | } |
@@ -488,7 +490,7 @@ static int autofs_dev_ioctl_requester(struct file *fp, | |||
488 | path = param->path; | 490 | path = param->path; |
489 | devid = sbi->sb->s_dev; | 491 | devid = sbi->sb->s_dev; |
490 | 492 | ||
491 | param->arg1 = param->arg2 = -1; | 493 | param->requester.uid = param->requester.gid = -1; |
492 | 494 | ||
493 | /* Get nameidata of the parent directory */ | 495 | /* Get nameidata of the parent directory */ |
494 | err = path_lookup(path, LOOKUP_PARENT, &nd); | 496 | err = path_lookup(path, LOOKUP_PARENT, &nd); |
@@ -504,8 +506,8 @@ static int autofs_dev_ioctl_requester(struct file *fp, | |||
504 | err = 0; | 506 | err = 0; |
505 | autofs4_expire_wait(nd.path.dentry); | 507 | autofs4_expire_wait(nd.path.dentry); |
506 | spin_lock(&sbi->fs_lock); | 508 | spin_lock(&sbi->fs_lock); |
507 | param->arg1 = ino->uid; | 509 | param->requester.uid = ino->uid; |
508 | param->arg2 = ino->gid; | 510 | param->requester.gid = ino->gid; |
509 | spin_unlock(&sbi->fs_lock); | 511 | spin_unlock(&sbi->fs_lock); |
510 | } | 512 | } |
511 | 513 | ||
@@ -528,10 +530,10 @@ static int autofs_dev_ioctl_expire(struct file *fp, | |||
528 | int err = -EAGAIN; | 530 | int err = -EAGAIN; |
529 | int how; | 531 | int how; |
530 | 532 | ||
531 | how = param->arg1; | 533 | how = param->expire.how; |
532 | mnt = fp->f_path.mnt; | 534 | mnt = fp->f_path.mnt; |
533 | 535 | ||
534 | if (sbi->type & AUTOFS_TYPE_TRIGGER) | 536 | if (autofs_type_trigger(sbi->type)) |
535 | dentry = autofs4_expire_direct(sbi->sb, mnt, sbi, how); | 537 | dentry = autofs4_expire_direct(sbi->sb, mnt, sbi, how); |
536 | else | 538 | else |
537 | dentry = autofs4_expire_indirect(sbi->sb, mnt, sbi, how); | 539 | dentry = autofs4_expire_indirect(sbi->sb, mnt, sbi, how); |
@@ -564,9 +566,9 @@ static int autofs_dev_ioctl_askumount(struct file *fp, | |||
564 | struct autofs_sb_info *sbi, | 566 | struct autofs_sb_info *sbi, |
565 | struct autofs_dev_ioctl *param) | 567 | struct autofs_dev_ioctl *param) |
566 | { | 568 | { |
567 | param->arg1 = 0; | 569 | param->askumount.may_umount = 0; |
568 | if (may_umount(fp->f_path.mnt)) | 570 | if (may_umount(fp->f_path.mnt)) |
569 | param->arg1 = 1; | 571 | param->askumount.may_umount = 1; |
570 | return 0; | 572 | return 0; |
571 | } | 573 | } |
572 | 574 | ||
@@ -599,6 +601,7 @@ static int autofs_dev_ioctl_ismountpoint(struct file *fp, | |||
599 | struct nameidata nd; | 601 | struct nameidata nd; |
600 | const char *path; | 602 | const char *path; |
601 | unsigned int type; | 603 | unsigned int type; |
604 | unsigned int devid, magic; | ||
602 | int err = -ENOENT; | 605 | int err = -ENOENT; |
603 | 606 | ||
604 | if (param->size <= sizeof(*param)) { | 607 | if (param->size <= sizeof(*param)) { |
@@ -607,13 +610,13 @@ static int autofs_dev_ioctl_ismountpoint(struct file *fp, | |||
607 | } | 610 | } |
608 | 611 | ||
609 | path = param->path; | 612 | path = param->path; |
610 | type = param->arg1; | 613 | type = param->ismountpoint.in.type; |
611 | 614 | ||
612 | param->arg1 = 0; | 615 | param->ismountpoint.out.devid = devid = 0; |
613 | param->arg2 = 0; | 616 | param->ismountpoint.out.magic = magic = 0; |
614 | 617 | ||
615 | if (!fp || param->ioctlfd == -1) { | 618 | if (!fp || param->ioctlfd == -1) { |
616 | if (type == AUTOFS_TYPE_ANY) { | 619 | if (autofs_type_any(type)) { |
617 | struct super_block *sb; | 620 | struct super_block *sb; |
618 | 621 | ||
619 | err = path_lookup(path, LOOKUP_FOLLOW, &nd); | 622 | err = path_lookup(path, LOOKUP_FOLLOW, &nd); |
@@ -621,7 +624,7 @@ static int autofs_dev_ioctl_ismountpoint(struct file *fp, | |||
621 | goto out; | 624 | goto out; |
622 | 625 | ||
623 | sb = nd.path.dentry->d_sb; | 626 | sb = nd.path.dentry->d_sb; |
624 | param->arg1 = new_encode_dev(sb->s_dev); | 627 | devid = new_encode_dev(sb->s_dev); |
625 | } else { | 628 | } else { |
626 | struct autofs_info *ino; | 629 | struct autofs_info *ino; |
627 | 630 | ||
@@ -634,38 +637,41 @@ static int autofs_dev_ioctl_ismountpoint(struct file *fp, | |||
634 | goto out_release; | 637 | goto out_release; |
635 | 638 | ||
636 | ino = autofs4_dentry_ino(nd.path.dentry); | 639 | ino = autofs4_dentry_ino(nd.path.dentry); |
637 | param->arg1 = autofs4_get_dev(ino->sbi); | 640 | devid = autofs4_get_dev(ino->sbi); |
638 | } | 641 | } |
639 | 642 | ||
640 | err = 0; | 643 | err = 0; |
641 | if (nd.path.dentry->d_inode && | 644 | if (nd.path.dentry->d_inode && |
642 | nd.path.mnt->mnt_root == nd.path.dentry) { | 645 | nd.path.mnt->mnt_root == nd.path.dentry) { |
643 | err = 1; | 646 | err = 1; |
644 | param->arg2 = nd.path.dentry->d_inode->i_sb->s_magic; | 647 | magic = nd.path.dentry->d_inode->i_sb->s_magic; |
645 | } | 648 | } |
646 | } else { | 649 | } else { |
647 | dev_t devid = new_encode_dev(sbi->sb->s_dev); | 650 | dev_t dev = autofs4_get_dev(sbi); |
648 | 651 | ||
649 | err = path_lookup(path, LOOKUP_PARENT, &nd); | 652 | err = path_lookup(path, LOOKUP_PARENT, &nd); |
650 | if (err) | 653 | if (err) |
651 | goto out; | 654 | goto out; |
652 | 655 | ||
653 | err = autofs_dev_ioctl_find_super(&nd, devid); | 656 | err = autofs_dev_ioctl_find_super(&nd, dev); |
654 | if (err) | 657 | if (err) |
655 | goto out_release; | 658 | goto out_release; |
656 | 659 | ||
657 | param->arg1 = autofs4_get_dev(sbi); | 660 | devid = dev; |
658 | 661 | ||
659 | err = have_submounts(nd.path.dentry); | 662 | err = have_submounts(nd.path.dentry); |
660 | 663 | ||
661 | if (nd.path.mnt->mnt_mountpoint != nd.path.mnt->mnt_root) { | 664 | if (nd.path.mnt->mnt_mountpoint != nd.path.mnt->mnt_root) { |
662 | if (follow_down(&nd.path.mnt, &nd.path.dentry)) { | 665 | if (follow_down(&nd.path.mnt, &nd.path.dentry)) { |
663 | struct inode *inode = nd.path.dentry->d_inode; | 666 | struct inode *inode = nd.path.dentry->d_inode; |
664 | param->arg2 = inode->i_sb->s_magic; | 667 | magic = inode->i_sb->s_magic; |
665 | } | 668 | } |
666 | } | 669 | } |
667 | } | 670 | } |
668 | 671 | ||
672 | param->ismountpoint.out.devid = devid; | ||
673 | param->ismountpoint.out.magic = magic; | ||
674 | |||
669 | out_release: | 675 | out_release: |
670 | path_put(&nd.path); | 676 | path_put(&nd.path); |
671 | out: | 677 | out: |