aboutsummaryrefslogtreecommitdiffstats
path: root/fs/autofs4/dev-ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/autofs4/dev-ioctl.c')
-rw-r--r--fs/autofs4/dev-ioctl.c78
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 */
129static int validate_dev_ioctl(int cmd, struct autofs_dev_ioctl *param) 129static 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
669out_release: 675out_release:
670 path_put(&nd.path); 676 path_put(&nd.path);
671out: 677out: