diff options
Diffstat (limited to 'net/core/wireless.c')
-rw-r--r-- | net/core/wireless.c | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/net/core/wireless.c b/net/core/wireless.c index ffff0da46c6e..cb1b8728d7ee 100644 --- a/net/core/wireless.c +++ b/net/core/wireless.c | |||
@@ -748,11 +748,39 @@ static int ioctl_standard_call(struct net_device * dev, | |||
748 | int extra_size; | 748 | int extra_size; |
749 | int user_length = 0; | 749 | int user_length = 0; |
750 | int err; | 750 | int err; |
751 | int essid_compat = 0; | ||
751 | 752 | ||
752 | /* Calculate space needed by arguments. Always allocate | 753 | /* Calculate space needed by arguments. Always allocate |
753 | * for max space. Easier, and won't last long... */ | 754 | * for max space. Easier, and won't last long... */ |
754 | extra_size = descr->max_tokens * descr->token_size; | 755 | extra_size = descr->max_tokens * descr->token_size; |
755 | 756 | ||
757 | /* Check need for ESSID compatibility for WE < 21 */ | ||
758 | switch (cmd) { | ||
759 | case SIOCSIWESSID: | ||
760 | case SIOCGIWESSID: | ||
761 | case SIOCSIWNICKN: | ||
762 | case SIOCGIWNICKN: | ||
763 | if (iwr->u.data.length == descr->max_tokens + 1) | ||
764 | essid_compat = 1; | ||
765 | else if (IW_IS_SET(cmd) && (iwr->u.data.length != 0)) { | ||
766 | char essid[IW_ESSID_MAX_SIZE + 1]; | ||
767 | |||
768 | err = copy_from_user(essid, iwr->u.data.pointer, | ||
769 | iwr->u.data.length * | ||
770 | descr->token_size); | ||
771 | if (err) | ||
772 | return -EFAULT; | ||
773 | |||
774 | if (essid[iwr->u.data.length - 1] == '\0') | ||
775 | essid_compat = 1; | ||
776 | } | ||
777 | break; | ||
778 | default: | ||
779 | break; | ||
780 | } | ||
781 | |||
782 | iwr->u.data.length -= essid_compat; | ||
783 | |||
756 | /* Check what user space is giving us */ | 784 | /* Check what user space is giving us */ |
757 | if(IW_IS_SET(cmd)) { | 785 | if(IW_IS_SET(cmd)) { |
758 | /* Check NULL pointer */ | 786 | /* Check NULL pointer */ |
@@ -795,7 +823,8 @@ static int ioctl_standard_call(struct net_device * dev, | |||
795 | #endif /* WE_IOCTL_DEBUG */ | 823 | #endif /* WE_IOCTL_DEBUG */ |
796 | 824 | ||
797 | /* Create the kernel buffer */ | 825 | /* Create the kernel buffer */ |
798 | extra = kmalloc(extra_size, GFP_KERNEL); | 826 | /* kzalloc ensures NULL-termination for essid_compat */ |
827 | extra = kzalloc(extra_size, GFP_KERNEL); | ||
799 | if (extra == NULL) { | 828 | if (extra == NULL) { |
800 | return -ENOMEM; | 829 | return -ENOMEM; |
801 | } | 830 | } |
@@ -819,6 +848,8 @@ static int ioctl_standard_call(struct net_device * dev, | |||
819 | /* Call the handler */ | 848 | /* Call the handler */ |
820 | ret = handler(dev, &info, &(iwr->u), extra); | 849 | ret = handler(dev, &info, &(iwr->u), extra); |
821 | 850 | ||
851 | iwr->u.data.length += essid_compat; | ||
852 | |||
822 | /* If we have something to return to the user */ | 853 | /* If we have something to return to the user */ |
823 | if (!ret && IW_IS_GET(cmd)) { | 854 | if (!ret && IW_IS_GET(cmd)) { |
824 | /* Check if there is enough buffer up there */ | 855 | /* Check if there is enough buffer up there */ |