Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

wext: Create IW_REQUEST_FLAG_COMPAT and set it as needed.

Now low-level WEXT ioctl handlers can do compat handling
when necessary.

Signed-off-by: David S. Miller <davem@davemloft.net>

+34 -41
+1 -1
include/net/iw_handler.h
··· 256 256 #define EIWCOMMIT EINPROGRESS 257 257 258 258 /* Flags available in struct iw_request_info */ 259 - #define IW_REQUEST_FLAG_NONE 0x0000 /* No flag so far */ 259 + #define IW_REQUEST_FLAG_COMPAT 0x0001 /* Compat ioctl call */ 260 260 261 261 /* Type of headers we know about (basically union iwreq_data) */ 262 262 #define IW_HEADER_TYPE_NULL 0 /* Not available */
+33 -40
net/wireless/wext.c
··· 834 834 static int ioctl_standard_call(struct net_device * dev, 835 835 struct iwreq *iwr, 836 836 unsigned int cmd, 837 + struct iw_request_info *info, 837 838 iw_handler handler) 838 839 { 839 840 const struct iw_ioctl_description * descr; 840 - struct iw_request_info info; 841 841 int ret = -EINVAL; 842 842 843 843 /* Get the description of the IOCTL */ ··· 845 845 return -EOPNOTSUPP; 846 846 descr = &(standard_ioctl[cmd - SIOCIWFIRST]); 847 847 848 - /* Prepare the call */ 849 - info.cmd = cmd; 850 - info.flags = 0; 851 - 852 848 /* Check if we have a pointer to user space data or not */ 853 849 if (descr->header_type != IW_HEADER_TYPE_POINT) { 854 850 855 851 /* No extra arguments. Trivial to handle */ 856 - ret = handler(dev, &info, &(iwr->u), NULL); 852 + ret = handler(dev, info, &(iwr->u), NULL); 857 853 858 854 /* Generate an event to notify listeners of the change */ 859 855 if ((descr->flags & IW_DESCR_FLAG_EVENT) && ··· 857 861 wireless_send_event(dev, cmd, &(iwr->u), NULL); 858 862 } else { 859 863 ret = ioctl_standard_iw_point(&iwr->u.data, cmd, descr, 860 - handler, dev, &info); 864 + handler, dev, info); 861 865 } 862 866 863 867 /* Call commit handler if needed and defined */ ··· 980 984 } 981 985 982 986 static int ioctl_private_call(struct net_device *dev, struct iwreq *iwr, 983 - unsigned int cmd, iw_handler handler) 987 + unsigned int cmd, struct iw_request_info *info, 988 + iw_handler handler) 984 989 { 985 990 int extra_size = 0, ret = -EINVAL; 986 991 const struct iw_priv_args *descr; 987 - struct iw_request_info info; 988 992 989 993 extra_size = get_priv_descr_and_size(dev, cmd, &descr); 990 - 991 - /* Prepare the call */ 992 - info.cmd = cmd; 993 - info.flags = 0; 994 994 995 995 /* Check if we have a pointer to user space data or not. */ 996 996 if (extra_size == 0) { 997 997 /* No extra arguments. Trivial to handle */ 998 - ret = handler(dev, &info, &(iwr->u), (char *) &(iwr->u)); 998 + ret = handler(dev, info, &(iwr->u), (char *) &(iwr->u)); 999 999 } else { 1000 1000 ret = ioctl_private_iw_point(&iwr->u.data, cmd, descr, 1001 - handler, dev, &info, extra_size); 1001 + handler, dev, info, extra_size); 1002 1002 } 1003 1003 1004 1004 /* Call commit handler if needed and defined */ ··· 1006 1014 1007 1015 /* ---------------------------------------------------------------- */ 1008 1016 typedef int (*wext_ioctl_func)(struct net_device *, struct iwreq *, 1009 - unsigned int, iw_handler); 1017 + unsigned int, struct iw_request_info *, 1018 + iw_handler); 1010 1019 1011 1020 /* 1012 1021 * Main IOCTl dispatcher. ··· 1015 1022 */ 1016 1023 static int wireless_process_ioctl(struct net *net, struct ifreq *ifr, 1017 1024 unsigned int cmd, 1025 + struct iw_request_info *info, 1018 1026 wext_ioctl_func standard, 1019 1027 wext_ioctl_func private) 1020 1028 { ··· 1034 1040 * Note that 'cmd' is already filtered in dev_ioctl() with 1035 1041 * (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) */ 1036 1042 if (cmd == SIOCGIWSTATS) 1037 - return standard(dev, iwr, cmd, 1043 + return standard(dev, iwr, cmd, info, 1038 1044 &iw_handler_get_iwstats); 1039 1045 1040 1046 if (cmd == SIOCGIWPRIV && dev->wireless_handlers) 1041 - return standard(dev, iwr, cmd, 1047 + return standard(dev, iwr, cmd, info, 1042 1048 &iw_handler_get_private); 1043 1049 1044 1050 /* Basic check */ ··· 1050 1056 if (handler) { 1051 1057 /* Standard and private are not the same */ 1052 1058 if (cmd < SIOCIWFIRSTPRIV) 1053 - return standard(dev, iwr, cmd, handler); 1059 + return standard(dev, iwr, cmd, info, handler); 1054 1060 else 1055 - return private(dev, iwr, cmd, handler); 1061 + return private(dev, iwr, cmd, info, handler); 1056 1062 } 1057 1063 /* Old driver API : call driver ioctl handler */ 1058 1064 if (dev->do_ioctl) ··· 1074 1080 1075 1081 /* entry point from dev ioctl */ 1076 1082 static int wext_ioctl_dispatch(struct net *net, struct ifreq *ifr, 1077 - unsigned int cmd, 1083 + unsigned int cmd, struct iw_request_info *info, 1078 1084 wext_ioctl_func standard, 1079 1085 wext_ioctl_func private) 1080 1086 { ··· 1085 1091 1086 1092 dev_load(net, ifr->ifr_name); 1087 1093 rtnl_lock(); 1088 - ret = wireless_process_ioctl(net, ifr, cmd, standard, private); 1094 + ret = wireless_process_ioctl(net, ifr, cmd, info, standard, private); 1089 1095 rtnl_unlock(); 1090 1096 1091 1097 return ret; ··· 1094 1100 int wext_handle_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd, 1095 1101 void __user *arg) 1096 1102 { 1097 - int ret = wext_ioctl_dispatch(net, ifr, cmd, 1098 - ioctl_standard_call, 1099 - ioctl_private_call); 1103 + struct iw_request_info info = { .cmd = cmd, .flags = 0 }; 1104 + int ret; 1100 1105 1106 + ret = wext_ioctl_dispatch(net, ifr, cmd, &info, 1107 + ioctl_standard_call, 1108 + ioctl_private_call); 1101 1109 if (ret >= 0 && 1102 1110 IW_IS_GET(cmd) && 1103 1111 copy_to_user(arg, ifr, sizeof(struct iwreq))) ··· 1112 1116 static int compat_standard_call(struct net_device *dev, 1113 1117 struct iwreq *iwr, 1114 1118 unsigned int cmd, 1119 + struct iw_request_info *info, 1115 1120 iw_handler handler) 1116 1121 { 1117 1122 const struct iw_ioctl_description *descr; 1118 1123 struct compat_iw_point *iwp_compat; 1119 - struct iw_request_info info; 1120 1124 struct iw_point iwp; 1121 1125 int err; 1122 1126 1123 1127 descr = standard_ioctl + (cmd - SIOCIWFIRST); 1124 1128 1125 1129 if (descr->header_type != IW_HEADER_TYPE_POINT) 1126 - return ioctl_standard_call(dev, iwr, cmd, handler); 1130 + return ioctl_standard_call(dev, iwr, cmd, info, handler); 1127 1131 1128 1132 iwp_compat = (struct compat_iw_point *) &iwr->u.data; 1129 1133 iwp.pointer = compat_ptr(iwp_compat->pointer); 1130 1134 iwp.length = iwp_compat->length; 1131 1135 iwp.flags = iwp_compat->flags; 1132 1136 1133 - info.cmd = cmd; 1134 - info.flags = 0; 1135 - 1136 - err = ioctl_standard_iw_point(&iwp, cmd, descr, handler, dev, &info); 1137 + err = ioctl_standard_iw_point(&iwp, cmd, descr, handler, dev, info); 1137 1138 1138 1139 iwp_compat->pointer = ptr_to_compat(iwp.pointer); 1139 1140 iwp_compat->length = iwp.length; ··· 1140 1147 } 1141 1148 1142 1149 static int compat_private_call(struct net_device *dev, struct iwreq *iwr, 1143 - unsigned int cmd, iw_handler handler) 1150 + unsigned int cmd, struct iw_request_info *info, 1151 + iw_handler handler) 1144 1152 { 1145 1153 const struct iw_priv_args *descr; 1146 - struct iw_request_info info; 1147 1154 int ret, extra_size; 1148 1155 1149 1156 extra_size = get_priv_descr_and_size(dev, cmd, &descr); 1150 1157 1151 - /* Prepare the call */ 1152 - info.cmd = cmd; 1153 - info.flags = 0; 1154 - 1155 1158 /* Check if we have a pointer to user space data or not. */ 1156 1159 if (extra_size == 0) { 1157 1160 /* No extra arguments. Trivial to handle */ 1158 - ret = handler(dev, &info, &(iwr->u), (char *) &(iwr->u)); 1161 + ret = handler(dev, info, &(iwr->u), (char *) &(iwr->u)); 1159 1162 } else { 1160 1163 struct compat_iw_point *iwp_compat; 1161 1164 struct iw_point iwp; ··· 1162 1173 iwp.flags = iwp_compat->flags; 1163 1174 1164 1175 ret = ioctl_private_iw_point(&iwp, cmd, descr, 1165 - handler, dev, &info, extra_size); 1176 + handler, dev, info, extra_size); 1166 1177 1167 1178 iwp_compat->pointer = ptr_to_compat(iwp.pointer); 1168 1179 iwp_compat->length = iwp.length; ··· 1180 1191 unsigned long arg) 1181 1192 { 1182 1193 void __user *argp = (void __user *)arg; 1194 + struct iw_request_info info; 1183 1195 struct iwreq iwr; 1184 1196 char *colon; 1185 1197 int ret; ··· 1193 1203 if (colon) 1194 1204 *colon = 0; 1195 1205 1196 - ret = wext_ioctl_dispatch(net, (struct ifreq *) &iwr, cmd, 1206 + info.cmd = cmd; 1207 + info.flags = IW_REQUEST_FLAG_COMPAT; 1208 + 1209 + ret = wext_ioctl_dispatch(net, (struct ifreq *) &iwr, cmd, &info, 1197 1210 compat_standard_call, 1198 1211 compat_private_call); 1199 1212