first
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
# Patch for aircrack-ng/8812au v5.6.4.2_35491.20191025 to route SIOCDEVPRIVATE
|
||||
# via .ndo_siocdevprivate on kernel 5.15+.
|
||||
#
|
||||
# Background
|
||||
# ----------
|
||||
# Linux 5.6 added struct net_device_ops::ndo_siocdevprivate, and 5.13 switched
|
||||
# SIOCDEVPRIVATE (0x89F0..0x89FF) dispatch over to it. Drivers that still only
|
||||
# register .ndo_do_ioctl no longer receive SIOCDEVPRIVATE ioctls on modern
|
||||
# kernels.
|
||||
#
|
||||
# aircrack-ng/88XXau (vintage 2019) wires the entire MP / EFUSE / debug
|
||||
# command surface through SIOCDEVPRIVATE → .ndo_do_ioctl → rtw_ioctl_wext_private
|
||||
# (the name-dispatch table at os_dep/linux/ioctl_linux.c:_rtw_ioctl_wext_private).
|
||||
# On kernel 5.15 these all return -EOPNOTSUPP from rtwpriv v5.9.1 (the
|
||||
# canonical Realtek MP-mode tool), even though MP/EFUSE handlers are compiled
|
||||
# in (CONFIG_MP_INCLUDED=y).
|
||||
#
|
||||
# iwpriv keeps working because it uses SIOCIWFIRSTPRIV+N (different ioctl
|
||||
# numbers, still routed via .ndo_do_ioctl).
|
||||
#
|
||||
# This patch adds a thin .ndo_siocdevprivate shim that rebuilds the iwreq
|
||||
# userspace-pointer field (now passed separately by the new ABI) and dispatches
|
||||
# into the existing rtw_ioctl() path. Unlocks rtwpriv v5.9.1 for:
|
||||
# - efuse_get realmap / realraw / rmap,XX,N (T3 EFUSE state-machine work)
|
||||
# - mp_start, mp_channel, mp_bandwidth, mp_rate, mp_txpower, mp_ctx, mp_query
|
||||
# (T4 MP-mode subcommand work)
|
||||
# - rfr / rfw via SIOCDEVPRIVATE (alternative to the iwpriv path the canary
|
||||
# diff oracle already uses)
|
||||
#
|
||||
# Apply
|
||||
# -----
|
||||
# cd /usr/src/8812au-5.6.4.2_35491.20191025
|
||||
# patch -p1 < /path/to/this/patch
|
||||
# dkms remove -m realtek-rtl88xxau -v 5.6.4.2~20230501 --all
|
||||
# dkms add /usr/src/8812au-5.6.4.2_35491.20191025
|
||||
# dkms build -m realtek-rtl88xxau -v 5.6.4.2~20230501
|
||||
# dkms install -m realtek-rtl88xxau -v 5.6.4.2~20230501 --force
|
||||
# rmmod 88XXau && modprobe 88XXau
|
||||
#
|
||||
# Verify
|
||||
# ------
|
||||
# iw dev wlxXXXX set type monitor && ip link set wlxXXXX up
|
||||
# iw dev wlxXXXX set channel 6
|
||||
# rtwpriv wlxXXXX mp_start # → "mp_start ok"
|
||||
# rtwpriv wlxXXXX efuse_get realmap # → 16-byte rows of EFUSE
|
||||
#
|
||||
# Tested against: Ubuntu 22.04 / 5.15.0-179-generic / aircrack-ng/8812au
|
||||
# v5.6.4.2_35491.20191025 + rtwpriv_x86_64 from rtwpriv_release_v5.9.1.20241014.
|
||||
|
||||
--- a/include/osdep_intf.h
|
||||
+++ b/include/osdep_intf.h
|
||||
@@ -52,6 +52,11 @@ struct intf_priv {
|
||||
#ifdef PLATFORM_LINUX
|
||||
int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
|
||||
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
|
||||
+int rtw_siocdevprivate(struct net_device *dev, struct ifreq *rq,
|
||||
+ void __user *data, int cmd);
|
||||
+#endif
|
||||
+
|
||||
int rtw_init_netdev_name(struct net_device *pnetdev, const char *ifname);
|
||||
struct net_device *rtw_init_netdev(_adapter *padapter);
|
||||
u16 rtw_recv_select_queue(struct sk_buff *skb);
|
||||
--- a/os_dep/linux/ioctl_linux.c
|
||||
+++ b/os_dep/linux/ioctl_linux.c
|
||||
@@ -12821,3 +12821,30 @@ int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
|
||||
|
||||
return ret;
|
||||
}
|
||||
+
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
|
||||
+/* Kernel 5.15+ deprecated SIOCDEVPRIVATE routing through .ndo_do_ioctl —
|
||||
+ * those ioctls now flow through .ndo_siocdevprivate with a separate
|
||||
+ * userspace pointer arg. Wrap rtw_ioctl so the existing dispatch logic
|
||||
+ * still receives SIOCDEVPRIVATE / SIOCDEVPRIVATE+1 etc.
|
||||
+ *
|
||||
+ * Without this shim, rtwpriv v5.9.1 (which talks via SIOCDEVPRIVATE) fails
|
||||
+ * with "Operation not supported" on every command, even though MP/EFUSE
|
||||
+ * handlers are compiled in. iwpriv keeps working because it uses
|
||||
+ * SIOCIWFIRSTPRIV+N which still routes via .ndo_do_ioctl.
|
||||
+ */
|
||||
+int rtw_siocdevprivate(struct net_device *dev, struct ifreq *rq,
|
||||
+ void __user *data, int cmd)
|
||||
+{
|
||||
+ struct iwreq *wrq = (struct iwreq *)rq;
|
||||
+
|
||||
+ /* The legacy rtw_ioctl reads the userspace buffer via copy_from_user
|
||||
+ * on `wrq->u.data.pointer`. The new ABI gives us that pointer
|
||||
+ * separately in `data`; rebuild the iwreq so the legacy path sees
|
||||
+ * what it expects. */
|
||||
+ if (cmd == SIOCDEVPRIVATE || cmd == SIOCDEVPRIVATE + 1)
|
||||
+ wrq->u.data.pointer = data;
|
||||
+
|
||||
+ return rtw_ioctl(dev, rq, cmd);
|
||||
+}
|
||||
+#endif
|
||||
--- a/os_dep/linux/os_intfs.c
|
||||
+++ b/os_dep/linux/os_intfs.c
|
||||
@@ -1535,6 +1535,9 @@ static const struct net_device_ops rtw_netdev_ops = {
|
||||
.ndo_get_stats = rtw_net_get_stats,
|
||||
#ifdef CONFIG_WIRELESS_EXT
|
||||
.ndo_do_ioctl = rtw_ioctl,
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
|
||||
+ .ndo_siocdevprivate = rtw_siocdevprivate,
|
||||
+#endif
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
@@ -2823,6 +2826,9 @@ static const struct net_device_ops rtw_netdev_ops = {
|
||||
.ndo_get_stats = rtw_net_get_stats,
|
||||
#ifdef CONFIG_WIRELESS_EXT
|
||||
.ndo_do_ioctl = rtw_ioctl,
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
|
||||
+ .ndo_siocdevprivate = rtw_siocdevprivate,
|
||||
+#endif
|
||||
#endif
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
|
||||
.ndo_select_queue = rtw_select_queue,
|
||||
Reference in New Issue
Block a user