aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/super.c34
1 files changed, 23 insertions, 11 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 20dc4ccdff56..d496e4016224 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -717,17 +717,21 @@ static void nfs_parse_ipv4_address(char *string, size_t str_len,
717} 717}
718 718
719#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 719#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
720static void nfs_parse_ipv6_scope_id(const char *string, const size_t str_len, 720static int nfs_parse_ipv6_scope_id(const char *string, const size_t str_len,
721 const char *delim, 721 const char *delim,
722 struct sockaddr_in6 *sin6) 722 struct sockaddr_in6 *sin6)
723{ 723{
724 char *p; 724 char *p;
725 size_t len; 725 size_t len;
726 726
727 if (!(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL)) 727 if ((string + str_len) == delim)
728 return ; 728 return 1;
729
729 if (*delim != IPV6_SCOPE_DELIMITER) 730 if (*delim != IPV6_SCOPE_DELIMITER)
730 return; 731 return 0;
732
733 if (!(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL))
734 return 0;
731 735
732 len = (string + str_len) - delim - 1; 736 len = (string + str_len) - delim - 1;
733 p = kstrndup(delim + 1, len, GFP_KERNEL); 737 p = kstrndup(delim + 1, len, GFP_KERNEL);
@@ -740,14 +744,20 @@ static void nfs_parse_ipv6_scope_id(const char *string, const size_t str_len,
740 scope_id = dev->ifindex; 744 scope_id = dev->ifindex;
741 dev_put(dev); 745 dev_put(dev);
742 } else { 746 } else {
743 /* scope_id is set to zero on error */ 747 if (strict_strtoul(p, 10, &scope_id) == 0) {
744 strict_strtoul(p, 10, &scope_id); 748 kfree(p);
749 return 0;
750 }
745 } 751 }
746 752
747 kfree(p); 753 kfree(p);
754
748 sin6->sin6_scope_id = scope_id; 755 sin6->sin6_scope_id = scope_id;
749 dfprintk(MOUNT, "NFS: IPv6 scope ID = %lu\n", scope_id); 756 dfprintk(MOUNT, "NFS: IPv6 scope ID = %lu\n", scope_id);
757 return 1;
750 } 758 }
759
760 return 0;
751} 761}
752 762
753static void nfs_parse_ipv6_address(char *string, size_t str_len, 763static void nfs_parse_ipv6_address(char *string, size_t str_len,
@@ -763,9 +773,11 @@ static void nfs_parse_ipv6_address(char *string, size_t str_len,
763 773
764 sin6->sin6_family = AF_INET6; 774 sin6->sin6_family = AF_INET6;
765 *addr_len = sizeof(*sin6); 775 *addr_len = sizeof(*sin6);
766 if (in6_pton(string, str_len, addr, IPV6_SCOPE_DELIMITER, &delim)) { 776 if (in6_pton(string, str_len, addr,
767 nfs_parse_ipv6_scope_id(string, str_len, delim, sin6); 777 IPV6_SCOPE_DELIMITER, &delim) != 0) {
768 return; 778 if (nfs_parse_ipv6_scope_id(string, str_len,
779 delim, sin6) != 0)
780 return;
769 } 781 }
770 } 782 }
771 783