summaryrefslogtreecommitdiffstats
path: root/net/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/socket.c')
-rw-r--r--net/socket.c301
1 files changed, 71 insertions, 230 deletions
diff --git a/net/socket.c b/net/socket.c
index 2f378449bc1b..a93c99b518ca 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -163,12 +163,6 @@ static DEFINE_SPINLOCK(net_family_lock);
163static const struct net_proto_family __rcu *net_families[NPROTO] __read_mostly; 163static const struct net_proto_family __rcu *net_families[NPROTO] __read_mostly;
164 164
165/* 165/*
166 * Statistics counters of the socket lists
167 */
168
169static DEFINE_PER_CPU(int, sockets_in_use);
170
171/*
172 * Support routines. 166 * Support routines.
173 * Move socket addresses back and forth across the kernel/user 167 * Move socket addresses back and forth across the kernel/user
174 * divide and look after the messy bits. 168 * divide and look after the messy bits.
@@ -580,7 +574,6 @@ struct socket *sock_alloc(void)
580 inode->i_gid = current_fsgid(); 574 inode->i_gid = current_fsgid();
581 inode->i_op = &sockfs_inode_ops; 575 inode->i_op = &sockfs_inode_ops;
582 576
583 this_cpu_add(sockets_in_use, 1);
584 return sock; 577 return sock;
585} 578}
586EXPORT_SYMBOL(sock_alloc); 579EXPORT_SYMBOL(sock_alloc);
@@ -607,7 +600,6 @@ void sock_release(struct socket *sock)
607 if (rcu_dereference_protected(sock->wq, 1)->fasync_list) 600 if (rcu_dereference_protected(sock->wq, 1)->fasync_list)
608 pr_err("%s: fasync list not empty!\n", __func__); 601 pr_err("%s: fasync list not empty!\n", __func__);
609 602
610 this_cpu_sub(sockets_in_use, 1);
611 if (!sock->file) { 603 if (!sock->file) {
612 iput(SOCK_INODE(sock)); 604 iput(SOCK_INODE(sock));
613 return; 605 return;
@@ -969,9 +961,28 @@ static long sock_do_ioctl(struct net *net, struct socket *sock,
969 * If this ioctl is unknown try to hand it down 961 * If this ioctl is unknown try to hand it down
970 * to the NIC driver. 962 * to the NIC driver.
971 */ 963 */
972 if (err == -ENOIOCTLCMD) 964 if (err != -ENOIOCTLCMD)
973 err = dev_ioctl(net, cmd, argp); 965 return err;
974 966
967 if (cmd == SIOCGIFCONF) {
968 struct ifconf ifc;
969 if (copy_from_user(&ifc, argp, sizeof(struct ifconf)))
970 return -EFAULT;
971 rtnl_lock();
972 err = dev_ifconf(net, &ifc, sizeof(struct ifreq));
973 rtnl_unlock();
974 if (!err && copy_to_user(argp, &ifc, sizeof(struct ifconf)))
975 err = -EFAULT;
976 } else {
977 struct ifreq ifr;
978 bool need_copyout;
979 if (copy_from_user(&ifr, argp, sizeof(struct ifreq)))
980 return -EFAULT;
981 err = dev_ioctl(net, cmd, &ifr, &need_copyout);
982 if (!err && need_copyout)
983 if (copy_to_user(argp, &ifr, sizeof(struct ifreq)))
984 return -EFAULT;
985 }
975 return err; 986 return err;
976} 987}
977 988
@@ -996,12 +1007,19 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
996 sock = file->private_data; 1007 sock = file->private_data;
997 sk = sock->sk; 1008 sk = sock->sk;
998 net = sock_net(sk); 1009 net = sock_net(sk);
999 if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) { 1010 if (unlikely(cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15))) {
1000 err = dev_ioctl(net, cmd, argp); 1011 struct ifreq ifr;
1012 bool need_copyout;
1013 if (copy_from_user(&ifr, argp, sizeof(struct ifreq)))
1014 return -EFAULT;
1015 err = dev_ioctl(net, cmd, &ifr, &need_copyout);
1016 if (!err && need_copyout)
1017 if (copy_to_user(argp, &ifr, sizeof(struct ifreq)))
1018 return -EFAULT;
1001 } else 1019 } else
1002#ifdef CONFIG_WEXT_CORE 1020#ifdef CONFIG_WEXT_CORE
1003 if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) { 1021 if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
1004 err = dev_ioctl(net, cmd, argp); 1022 err = wext_handle_ioctl(net, cmd, argp);
1005 } else 1023 } else
1006#endif 1024#endif
1007 switch (cmd) { 1025 switch (cmd) {
@@ -2621,29 +2639,11 @@ out_fs:
2621 2639
2622core_initcall(sock_init); /* early initcall */ 2640core_initcall(sock_init); /* early initcall */
2623 2641
2624static int __init jit_init(void)
2625{
2626#ifdef CONFIG_BPF_JIT_ALWAYS_ON
2627 bpf_jit_enable = 1;
2628#endif
2629 return 0;
2630}
2631pure_initcall(jit_init);
2632
2633#ifdef CONFIG_PROC_FS 2642#ifdef CONFIG_PROC_FS
2634void socket_seq_show(struct seq_file *seq) 2643void socket_seq_show(struct seq_file *seq)
2635{ 2644{
2636 int cpu; 2645 seq_printf(seq, "sockets: used %d\n",
2637 int counter = 0; 2646 sock_inuse_get(seq->private));
2638
2639 for_each_possible_cpu(cpu)
2640 counter += per_cpu(sockets_in_use, cpu);
2641
2642 /* It can be negative, by the way. 8) */
2643 if (counter < 0)
2644 counter = 0;
2645
2646 seq_printf(seq, "sockets: used %d\n", counter);
2647} 2647}
2648#endif /* CONFIG_PROC_FS */ 2648#endif /* CONFIG_PROC_FS */
2649 2649
@@ -2680,89 +2680,25 @@ static int do_siocgstampns(struct net *net, struct socket *sock,
2680 return err; 2680 return err;
2681} 2681}
2682 2682
2683static int dev_ifname32(struct net *net, struct compat_ifreq __user *uifr32) 2683static int compat_dev_ifconf(struct net *net, struct compat_ifconf __user *uifc32)
2684{
2685 struct ifreq __user *uifr;
2686 int err;
2687
2688 uifr = compat_alloc_user_space(sizeof(struct ifreq));
2689 if (copy_in_user(uifr, uifr32, sizeof(struct compat_ifreq)))
2690 return -EFAULT;
2691
2692 err = dev_ioctl(net, SIOCGIFNAME, uifr);
2693 if (err)
2694 return err;
2695
2696 if (copy_in_user(uifr32, uifr, sizeof(struct compat_ifreq)))
2697 return -EFAULT;
2698
2699 return 0;
2700}
2701
2702static int dev_ifconf(struct net *net, struct compat_ifconf __user *uifc32)
2703{ 2684{
2704 struct compat_ifconf ifc32; 2685 struct compat_ifconf ifc32;
2705 struct ifconf ifc; 2686 struct ifconf ifc;
2706 struct ifconf __user *uifc;
2707 struct compat_ifreq __user *ifr32;
2708 struct ifreq __user *ifr;
2709 unsigned int i, j;
2710 int err; 2687 int err;
2711 2688
2712 if (copy_from_user(&ifc32, uifc32, sizeof(struct compat_ifconf))) 2689 if (copy_from_user(&ifc32, uifc32, sizeof(struct compat_ifconf)))
2713 return -EFAULT; 2690 return -EFAULT;
2714 2691
2715 memset(&ifc, 0, sizeof(ifc)); 2692 ifc.ifc_len = ifc32.ifc_len;
2716 if (ifc32.ifcbuf == 0) { 2693 ifc.ifc_req = compat_ptr(ifc32.ifcbuf);
2717 ifc32.ifc_len = 0;
2718 ifc.ifc_len = 0;
2719 ifc.ifc_req = NULL;
2720 uifc = compat_alloc_user_space(sizeof(struct ifconf));
2721 } else {
2722 size_t len = ((ifc32.ifc_len / sizeof(struct compat_ifreq)) + 1) *
2723 sizeof(struct ifreq);
2724 uifc = compat_alloc_user_space(sizeof(struct ifconf) + len);
2725 ifc.ifc_len = len;
2726 ifr = ifc.ifc_req = (void __user *)(uifc + 1);
2727 ifr32 = compat_ptr(ifc32.ifcbuf);
2728 for (i = 0; i < ifc32.ifc_len; i += sizeof(struct compat_ifreq)) {
2729 if (copy_in_user(ifr, ifr32, sizeof(struct compat_ifreq)))
2730 return -EFAULT;
2731 ifr++;
2732 ifr32++;
2733 }
2734 }
2735 if (copy_to_user(uifc, &ifc, sizeof(struct ifconf)))
2736 return -EFAULT;
2737 2694
2738 err = dev_ioctl(net, SIOCGIFCONF, uifc); 2695 rtnl_lock();
2696 err = dev_ifconf(net, &ifc, sizeof(struct compat_ifreq));
2697 rtnl_unlock();
2739 if (err) 2698 if (err)
2740 return err; 2699 return err;
2741 2700
2742 if (copy_from_user(&ifc, uifc, sizeof(struct ifconf))) 2701 ifc32.ifc_len = ifc.ifc_len;
2743 return -EFAULT;
2744
2745 ifr = ifc.ifc_req;
2746 ifr32 = compat_ptr(ifc32.ifcbuf);
2747 for (i = 0, j = 0;
2748 i + sizeof(struct compat_ifreq) <= ifc32.ifc_len && j < ifc.ifc_len;
2749 i += sizeof(struct compat_ifreq), j += sizeof(struct ifreq)) {
2750 if (copy_in_user(ifr32, ifr, sizeof(struct compat_ifreq)))
2751 return -EFAULT;
2752 ifr32++;
2753 ifr++;
2754 }
2755
2756 if (ifc32.ifcbuf == 0) {
2757 /* Translate from 64-bit structure multiple to
2758 * a 32-bit one.
2759 */
2760 i = ifc.ifc_len;
2761 i = ((i / sizeof(struct ifreq)) * sizeof(struct compat_ifreq));
2762 ifc32.ifc_len = i;
2763 } else {
2764 ifc32.ifc_len = i;
2765 }
2766 if (copy_to_user(uifc32, &ifc32, sizeof(struct compat_ifconf))) 2702 if (copy_to_user(uifc32, &ifc32, sizeof(struct compat_ifconf)))
2767 return -EFAULT; 2703 return -EFAULT;
2768 2704
@@ -2773,9 +2709,9 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
2773{ 2709{
2774 struct compat_ethtool_rxnfc __user *compat_rxnfc; 2710 struct compat_ethtool_rxnfc __user *compat_rxnfc;
2775 bool convert_in = false, convert_out = false; 2711 bool convert_in = false, convert_out = false;
2776 size_t buf_size = ALIGN(sizeof(struct ifreq), 8); 2712 size_t buf_size = 0;
2777 struct ethtool_rxnfc __user *rxnfc; 2713 struct ethtool_rxnfc __user *rxnfc = NULL;
2778 struct ifreq __user *ifr; 2714 struct ifreq ifr;
2779 u32 rule_cnt = 0, actual_rule_cnt; 2715 u32 rule_cnt = 0, actual_rule_cnt;
2780 u32 ethcmd; 2716 u32 ethcmd;
2781 u32 data; 2717 u32 data;
@@ -2812,18 +2748,14 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
2812 case ETHTOOL_SRXCLSRLDEL: 2748 case ETHTOOL_SRXCLSRLDEL:
2813 buf_size += sizeof(struct ethtool_rxnfc); 2749 buf_size += sizeof(struct ethtool_rxnfc);
2814 convert_in = true; 2750 convert_in = true;
2751 rxnfc = compat_alloc_user_space(buf_size);
2815 break; 2752 break;
2816 } 2753 }
2817 2754
2818 ifr = compat_alloc_user_space(buf_size); 2755 if (copy_from_user(&ifr.ifr_name, &ifr32->ifr_name, IFNAMSIZ))
2819 rxnfc = (void __user *)ifr + ALIGN(sizeof(struct ifreq), 8);
2820
2821 if (copy_in_user(&ifr->ifr_name, &ifr32->ifr_name, IFNAMSIZ))
2822 return -EFAULT; 2756 return -EFAULT;
2823 2757
2824 if (put_user(convert_in ? rxnfc : compat_ptr(data), 2758 ifr.ifr_data = convert_in ? rxnfc : (void __user *)compat_rxnfc;
2825 &ifr->ifr_ifru.ifru_data))
2826 return -EFAULT;
2827 2759
2828 if (convert_in) { 2760 if (convert_in) {
2829 /* We expect there to be holes between fs.m_ext and 2761 /* We expect there to be holes between fs.m_ext and
@@ -2851,7 +2783,7 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
2851 return -EFAULT; 2783 return -EFAULT;
2852 } 2784 }
2853 2785
2854 ret = dev_ioctl(net, SIOCETHTOOL, ifr); 2786 ret = dev_ioctl(net, SIOCETHTOOL, &ifr, NULL);
2855 if (ret) 2787 if (ret)
2856 return ret; 2788 return ret;
2857 2789
@@ -2892,113 +2824,43 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
2892 2824
2893static int compat_siocwandev(struct net *net, struct compat_ifreq __user *uifr32) 2825static int compat_siocwandev(struct net *net, struct compat_ifreq __user *uifr32)
2894{ 2826{
2895 void __user *uptr;
2896 compat_uptr_t uptr32; 2827 compat_uptr_t uptr32;
2897 struct ifreq __user *uifr; 2828 struct ifreq ifr;
2829 void __user *saved;
2830 int err;
2898 2831
2899 uifr = compat_alloc_user_space(sizeof(*uifr)); 2832 if (copy_from_user(&ifr, uifr32, sizeof(struct compat_ifreq)))
2900 if (copy_in_user(uifr, uifr32, sizeof(struct compat_ifreq)))
2901 return -EFAULT; 2833 return -EFAULT;
2902 2834
2903 if (get_user(uptr32, &uifr32->ifr_settings.ifs_ifsu)) 2835 if (get_user(uptr32, &uifr32->ifr_settings.ifs_ifsu))
2904 return -EFAULT; 2836 return -EFAULT;
2905 2837
2906 uptr = compat_ptr(uptr32); 2838 saved = ifr.ifr_settings.ifs_ifsu.raw_hdlc;
2907 2839 ifr.ifr_settings.ifs_ifsu.raw_hdlc = compat_ptr(uptr32);
2908 if (put_user(uptr, &uifr->ifr_settings.ifs_ifsu.raw_hdlc))
2909 return -EFAULT;
2910
2911 return dev_ioctl(net, SIOCWANDEV, uifr);
2912}
2913
2914static int bond_ioctl(struct net *net, unsigned int cmd,
2915 struct compat_ifreq __user *ifr32)
2916{
2917 struct ifreq kifr;
2918 mm_segment_t old_fs;
2919 int err;
2920 2840
2921 switch (cmd) { 2841 err = dev_ioctl(net, SIOCWANDEV, &ifr, NULL);
2922 case SIOCBONDENSLAVE: 2842 if (!err) {
2923 case SIOCBONDRELEASE: 2843 ifr.ifr_settings.ifs_ifsu.raw_hdlc = saved;
2924 case SIOCBONDSETHWADDR: 2844 if (copy_to_user(uifr32, &ifr, sizeof(struct compat_ifreq)))
2925 case SIOCBONDCHANGEACTIVE: 2845 err = -EFAULT;
2926 if (copy_from_user(&kifr, ifr32, sizeof(struct compat_ifreq)))
2927 return -EFAULT;
2928
2929 old_fs = get_fs();
2930 set_fs(KERNEL_DS);
2931 err = dev_ioctl(net, cmd,
2932 (struct ifreq __user __force *) &kifr);
2933 set_fs(old_fs);
2934
2935 return err;
2936 default:
2937 return -ENOIOCTLCMD;
2938 } 2846 }
2847 return err;
2939} 2848}
2940 2849
2941/* Handle ioctls that use ifreq::ifr_data and just need struct ifreq converted */ 2850/* Handle ioctls that use ifreq::ifr_data and just need struct ifreq converted */
2942static int compat_ifr_data_ioctl(struct net *net, unsigned int cmd, 2851static int compat_ifr_data_ioctl(struct net *net, unsigned int cmd,
2943 struct compat_ifreq __user *u_ifreq32) 2852 struct compat_ifreq __user *u_ifreq32)
2944{ 2853{
2945 struct ifreq __user *u_ifreq64; 2854 struct ifreq ifreq;
2946 char tmp_buf[IFNAMSIZ];
2947 void __user *data64;
2948 u32 data32; 2855 u32 data32;
2949 2856
2950 if (copy_from_user(&tmp_buf[0], &(u_ifreq32->ifr_ifrn.ifrn_name[0]), 2857 if (copy_from_user(ifreq.ifr_name, u_ifreq32->ifr_name, IFNAMSIZ))
2951 IFNAMSIZ))
2952 return -EFAULT; 2858 return -EFAULT;
2953 if (get_user(data32, &u_ifreq32->ifr_ifru.ifru_data)) 2859 if (get_user(data32, &u_ifreq32->ifr_data))
2954 return -EFAULT; 2860 return -EFAULT;
2955 data64 = compat_ptr(data32); 2861 ifreq.ifr_data = compat_ptr(data32);
2956 2862
2957 u_ifreq64 = compat_alloc_user_space(sizeof(*u_ifreq64)); 2863 return dev_ioctl(net, cmd, &ifreq, NULL);
2958
2959 if (copy_to_user(&u_ifreq64->ifr_ifrn.ifrn_name[0], &tmp_buf[0],
2960 IFNAMSIZ))
2961 return -EFAULT;
2962 if (put_user(data64, &u_ifreq64->ifr_ifru.ifru_data))
2963 return -EFAULT;
2964
2965 return dev_ioctl(net, cmd, u_ifreq64);
2966}
2967
2968static int dev_ifsioc(struct net *net, struct socket *sock,
2969 unsigned int cmd, struct compat_ifreq __user *uifr32)
2970{
2971 struct ifreq __user *uifr;
2972 int err;
2973
2974 uifr = compat_alloc_user_space(sizeof(*uifr));
2975 if (copy_in_user(uifr, uifr32, sizeof(*uifr32)))
2976 return -EFAULT;
2977
2978 err = sock_do_ioctl(net, sock, cmd, (unsigned long)uifr);
2979
2980 if (!err) {
2981 switch (cmd) {
2982 case SIOCGIFFLAGS:
2983 case SIOCGIFMETRIC:
2984 case SIOCGIFMTU:
2985 case SIOCGIFMEM:
2986 case SIOCGIFHWADDR:
2987 case SIOCGIFINDEX:
2988 case SIOCGIFADDR:
2989 case SIOCGIFBRDADDR:
2990 case SIOCGIFDSTADDR:
2991 case SIOCGIFNETMASK:
2992 case SIOCGIFPFLAGS:
2993 case SIOCGIFTXQLEN:
2994 case SIOCGMIIPHY:
2995 case SIOCGMIIREG:
2996 if (copy_in_user(uifr32, uifr, sizeof(*uifr32)))
2997 err = -EFAULT;
2998 break;
2999 }
3000 }
3001 return err;
3002} 2864}
3003 2865
3004static int compat_sioc_ifmap(struct net *net, unsigned int cmd, 2866static int compat_sioc_ifmap(struct net *net, unsigned int cmd,
@@ -3006,7 +2868,6 @@ static int compat_sioc_ifmap(struct net *net, unsigned int cmd,
3006{ 2868{
3007 struct ifreq ifr; 2869 struct ifreq ifr;
3008 struct compat_ifmap __user *uifmap32; 2870 struct compat_ifmap __user *uifmap32;
3009 mm_segment_t old_fs;
3010 int err; 2871 int err;
3011 2872
3012 uifmap32 = &uifr32->ifr_ifru.ifru_map; 2873 uifmap32 = &uifr32->ifr_ifru.ifru_map;
@@ -3020,10 +2881,7 @@ static int compat_sioc_ifmap(struct net *net, unsigned int cmd,
3020 if (err) 2881 if (err)
3021 return -EFAULT; 2882 return -EFAULT;
3022 2883
3023 old_fs = get_fs(); 2884 err = dev_ioctl(net, cmd, &ifr, NULL);
3024 set_fs(KERNEL_DS);
3025 err = dev_ioctl(net, cmd, (void __user __force *)&ifr);
3026 set_fs(old_fs);
3027 2885
3028 if (cmd == SIOCGIFMAP && !err) { 2886 if (cmd == SIOCGIFMAP && !err) {
3029 err = copy_to_user(uifr32, &ifr, sizeof(ifr.ifr_name)); 2887 err = copy_to_user(uifr32, &ifr, sizeof(ifr.ifr_name));
@@ -3156,10 +3014,8 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
3156 case SIOCSIFBR: 3014 case SIOCSIFBR:
3157 case SIOCGIFBR: 3015 case SIOCGIFBR:
3158 return old_bridge_ioctl(argp); 3016 return old_bridge_ioctl(argp);
3159 case SIOCGIFNAME:
3160 return dev_ifname32(net, argp);
3161 case SIOCGIFCONF: 3017 case SIOCGIFCONF:
3162 return dev_ifconf(net, argp); 3018 return compat_dev_ifconf(net, argp);
3163 case SIOCETHTOOL: 3019 case SIOCETHTOOL:
3164 return ethtool_ioctl(net, argp); 3020 return ethtool_ioctl(net, argp);
3165 case SIOCWANDEV: 3021 case SIOCWANDEV:
@@ -3167,11 +3023,6 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
3167 case SIOCGIFMAP: 3023 case SIOCGIFMAP:
3168 case SIOCSIFMAP: 3024 case SIOCSIFMAP:
3169 return compat_sioc_ifmap(net, cmd, argp); 3025 return compat_sioc_ifmap(net, cmd, argp);
3170 case SIOCBONDENSLAVE:
3171 case SIOCBONDRELEASE:
3172 case SIOCBONDSETHWADDR:
3173 case SIOCBONDCHANGEACTIVE:
3174 return bond_ioctl(net, cmd, argp);
3175 case SIOCADDRT: 3026 case SIOCADDRT:
3176 case SIOCDELRT: 3027 case SIOCDELRT:
3177 return routing_ioctl(net, sock, cmd, argp); 3028 return routing_ioctl(net, sock, cmd, argp);
@@ -3231,12 +3082,15 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
3231 case SIOCGMIIPHY: 3082 case SIOCGMIIPHY:
3232 case SIOCGMIIREG: 3083 case SIOCGMIIREG:
3233 case SIOCSMIIREG: 3084 case SIOCSMIIREG:
3234 return dev_ifsioc(net, sock, cmd, argp);
3235
3236 case SIOCSARP: 3085 case SIOCSARP:
3237 case SIOCGARP: 3086 case SIOCGARP:
3238 case SIOCDARP: 3087 case SIOCDARP:
3239 case SIOCATMARK: 3088 case SIOCATMARK:
3089 case SIOCBONDENSLAVE:
3090 case SIOCBONDRELEASE:
3091 case SIOCBONDSETHWADDR:
3092 case SIOCBONDCHANGEACTIVE:
3093 case SIOCGIFNAME:
3240 return sock_do_ioctl(net, sock, cmd, arg); 3094 return sock_do_ioctl(net, sock, cmd, arg);
3241 } 3095 }
3242 3096
@@ -3391,19 +3245,6 @@ int kernel_sendpage_locked(struct sock *sk, struct page *page, int offset,
3391} 3245}
3392EXPORT_SYMBOL(kernel_sendpage_locked); 3246EXPORT_SYMBOL(kernel_sendpage_locked);
3393 3247
3394int kernel_sock_ioctl(struct socket *sock, int cmd, unsigned long arg)
3395{
3396 mm_segment_t oldfs = get_fs();
3397 int err;
3398
3399 set_fs(KERNEL_DS);
3400 err = sock->ops->ioctl(sock, cmd, arg);
3401 set_fs(oldfs);
3402
3403 return err;
3404}
3405EXPORT_SYMBOL(kernel_sock_ioctl);
3406
3407int kernel_sock_shutdown(struct socket *sock, enum sock_shutdown_cmd how) 3248int kernel_sock_shutdown(struct socket *sock, enum sock_shutdown_cmd how)
3408{ 3249{
3409 return sock->ops->shutdown(sock, how); 3250 return sock->ops->shutdown(sock, how);