summaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2018-12-16 01:37:06 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2018-12-21 11:51:02 -0500
commitd2497e12e230c3f1be8ca6a0609a98c8c609fb80 (patch)
tree91156d8db61b4929b980bc4d4856803a4acb1685 /security
parentc3300aaf95fb4e5be41e731fa6427d0d996d32ac (diff)
smack: rewrite smack_sb_eat_lsm_opts()
make it use smack_add_opt() and avoid separate copies - gather non-LSM options by memmove() in place Reviewed-by: David Howells <dhowells@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'security')
-rw-r--r--security/smack/smack_lsm.c108
1 files changed, 23 insertions, 85 deletions
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index d479def4d6a0..24a00d93d8c3 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -599,53 +599,6 @@ static void smack_free_mnt_opts(void *mnt_opts)
599 kfree(opts); 599 kfree(opts);
600} 600}
601 601
602/**
603 * smack_sb_copy_data - copy mount options data for processing
604 * @orig: where to start
605 * @smackopts: mount options string
606 *
607 * Returns 0 on success or -ENOMEM on error.
608 *
609 * Copy the Smack specific mount options out of the mount
610 * options list.
611 */
612static int smack_sb_copy_data(char *orig, char *smackopts)
613{
614 char *cp, *commap, *otheropts, *dp;
615
616 otheropts = (char *)get_zeroed_page(GFP_KERNEL);
617 if (otheropts == NULL)
618 return -ENOMEM;
619
620 for (cp = orig, commap = orig; commap != NULL; cp = commap + 1) {
621 if (strstr(cp, SMK_FSDEFAULT) == cp)
622 dp = smackopts;
623 else if (strstr(cp, SMK_FSFLOOR) == cp)
624 dp = smackopts;
625 else if (strstr(cp, SMK_FSHAT) == cp)
626 dp = smackopts;
627 else if (strstr(cp, SMK_FSROOT) == cp)
628 dp = smackopts;
629 else if (strstr(cp, SMK_FSTRANS) == cp)
630 dp = smackopts;
631 else
632 dp = otheropts;
633
634 commap = strchr(cp, ',');
635 if (commap != NULL)
636 *commap = '\0';
637
638 if (*dp != '\0')
639 strcat(dp, ",");
640 strcat(dp, cp);
641 }
642
643 strcpy(orig, otheropts);
644 free_page((unsigned long)otheropts);
645
646 return 0;
647}
648
649static int smack_add_opt(int token, const char *s, void **mnt_opts) 602static int smack_add_opt(int token, const char *s, void **mnt_opts)
650{ 603{
651 struct smack_mnt_opts *opts = *mnt_opts; 604 struct smack_mnt_opts *opts = *mnt_opts;
@@ -656,7 +609,6 @@ static int smack_add_opt(int token, const char *s, void **mnt_opts)
656 return -ENOMEM; 609 return -ENOMEM;
657 *mnt_opts = opts; 610 *mnt_opts = opts;
658 } 611 }
659
660 if (!s) 612 if (!s)
661 return -ENOMEM; 613 return -ENOMEM;
662 614
@@ -694,22 +646,10 @@ out_opt_err:
694 return -EINVAL; 646 return -EINVAL;
695} 647}
696 648
697/** 649static int smack_sb_eat_lsm_opts(char *options, void **mnt_opts)
698 * smack_parse_opts_str - parse Smack specific mount options
699 * @options: mount options string
700 * @opts: where to store converted mount opts
701 *
702 * Returns 0 on success or -ENOMEM on error.
703 *
704 * converts Smack specific mount options to generic security option format
705 */
706static int smack_parse_opts_str(char *options,
707 void **mnt_opts)
708{ 650{
709 char *from = options; 651 char *from = options, *to = options;
710 652 bool first = true;
711 if (!options)
712 return 0;
713 653
714 while (1) { 654 while (1) {
715 char *next = strchr(from, ','); 655 char *next = strchr(from, ',');
@@ -722,36 +662,34 @@ static int smack_parse_opts_str(char *options,
722 len = strlen(from); 662 len = strlen(from);
723 663
724 token = match_opt_prefix(from, len, &arg); 664 token = match_opt_prefix(from, len, &arg);
725 arg = kmemdup_nul(arg, from + len - arg, GFP_KERNEL); 665 if (token != Opt_error) {
726 rc = smack_add_opt(token, arg, mnt_opts); 666 arg = kmemdup_nul(arg, from + len - arg, GFP_KERNEL);
727 if (unlikely(rc)) { 667 rc = smack_add_opt(token, arg, mnt_opts);
728 kfree(arg); 668 if (unlikely(rc)) {
729 if (*mnt_opts) 669 kfree(arg);
730 smack_free_mnt_opts(*mnt_opts); 670 if (*mnt_opts)
731 *mnt_opts = NULL; 671 smack_free_mnt_opts(*mnt_opts);
732 return rc; 672 *mnt_opts = NULL;
673 return rc;
674 }
675 } else {
676 if (!first) { // copy with preceding comma
677 from--;
678 len++;
679 }
680 if (to != from)
681 memmove(to, from, len);
682 to += len;
683 first = false;
733 } 684 }
734 if (!from[len]) 685 if (!from[len])
735 break; 686 break;
736 from += len + 1; 687 from += len + 1;
737 } 688 }
689 *to = '\0';
738 return 0; 690 return 0;
739} 691}
740 692
741static int smack_sb_eat_lsm_opts(char *options, void **mnt_opts)
742{
743 char *s = (char *)get_zeroed_page(GFP_KERNEL);
744 int err;
745
746 if (!s)
747 return -ENOMEM;
748 err = smack_sb_copy_data(options, s);
749 if (!err)
750 err = smack_parse_opts_str(s, mnt_opts);
751 free_page((unsigned long)s);
752 return err;
753}
754
755/** 693/**
756 * smack_set_mnt_opts - set Smack specific mount options 694 * smack_set_mnt_opts - set Smack specific mount options
757 * @sb: the file system superblock 695 * @sb: the file system superblock