From: sashiko-bot@kernel.org
To: "Birger Koblitz" <mail@birger-koblitz.de>
Cc: linux-usb@vger.kernel.org
Subject: Re: [PATCH net-next v20 07/13] ax88179_178a: Add VLAN offload support for AX88179A
Date: Sat, 07 Nov 2026 07:21:53 +0000 [thread overview]
Message-ID: <sashiko-outbox-202697@kernel.org> (raw)
In-Reply-To: <20261106-ax88179a-v20-7-37b5a1189983@birger-koblitz.de>
Thank you for your contribution! Sashiko AI review found 5 potential
issues to consider:
- [Medium] net: usb: ax88179: unchecked USB writes in
ax88179a_set_features() loop
- [Medium] net: usb: ax88179: uninitialized stack read on short USB read
- [Medium] net: usb: ax88179_178a: unchecked writes and partial state in
ax88179a_set_features()
- [Medium] net: usb: ax88179_178a: TX VLAN tag drop race in
ax88179a_tx_fixup()
- [Low] net: usb: ax88179_178a: duplicated VLAN filter update logic in
add/kill vid
--
commit 6bf60c56c4445f3486e6c4282f90f25fbd952f48
Author: Birger Koblitz <mail@birger-koblitz.de>
ax88179_178a: Add VLAN offload support for AX88179A
This commit adds TX VLAN tagging, RX VLAN stripping, and RX VLAN filter
offload configuration for AX88179A-based USB network devices.
> diff --git a/drivers/net/usb/ax88179a_devices.c b/drivers/net/usb/ax88179a_devices.c
> index 272e923656832..4207d2cc2b865 100644
> --- a/drivers/net/usb/ax88179a_devices.c
> +++ b/drivers/net/usb/ax88179a_devices.c
> @@ -258,6 +258,88 @@ static const struct ethtool_ops ax88179a_ethtool_ops = {
> .get_ts_info = ethtool_op_get_ts_info,
> };
>
> +static int ax88179a_vlan_rx_kill_vid(struct net_device *net, __be16 proto, u16 vid)
> +{
> + struct usbnet *dev = netdev_priv(net);
> + u16 reg16 = 0;
> + u8 vlan_ctrl;
> + int ret = 0;
> + u8 reg8 = 0;
> +
> + ret = ax88179_read_cmd(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_CONTROL, 1, 1, ®8);
> + if (ret < 0)
> + return ret;
> + vlan_ctrl = reg8;
> +
> + /* Address */
> + reg8 = (vid / 16);
> + ret = ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_ADDRESS, 1, 1, ®8);
> + if (ret < 0)
> + return ret;
> +
> + /* Data */
> + reg8 = vlan_ctrl | AX_VLAN_CONTROL_RD;
> + ret = ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_CONTROL, 1, 1, ®8);
> + if (ret < 0)
> + return ret;
> +
> + ret = ax88179_read_cmd(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_DATA0, 2, 2, ®16);
> + if (ret < 0)
> + return ret;
> + reg16 &= ~(1 << (vid % 16));
> + ret = ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_DATA0, 2, 2, ®16);
> + if (ret < 0)
> + return ret;
> +
> + reg8 = vlan_ctrl | AX_VLAN_CONTROL_WE;
> + ret = ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_CONTROL, 1, 1, ®8);
> + if (ret < 0)
> + return ret;
> +
> + return 0;
> +}
> +
> +static int ax88179a_vlan_rx_add_vid(struct net_device *net, __be16 proto, u16 vid)
> +{
> + struct usbnet *dev = netdev_priv(net);
> + u8 vlan_ctrl;
> + int ret = 0;
> + u16 reg16;
> + u8 reg8;
> +
> + ret = ax88179_read_cmd(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_CONTROL, 1, 1, ®8);
> + if (ret < 0)
> + return ret;
> + vlan_ctrl = reg8;
[Severity: Medium]
Can ax88179a_vlan_rx_add_vid() and ax88179a_set_features() read
uninitialized stack memory from reg8 and tmp when a 1-byte
ax88179_read_cmd() returns 0?
Unlike the size == 2 and size == 4 cases in ax88179_read_cmd(), a 1-byte
read passes the caller's pointer directly to __usbnet_read_cmd(), which
only copies into data when usb_control_msg() returns err > 0. If a short
transfer returns 0, reg8 here and tmp in the NETIF_F_HW_VLAN_CTAG_FILTER
disable and NETIF_F_HW_VLAN_CTAG_RX paths of ax88179a_set_features() are
left uninitialized and then written back to AX88179A_VLAN_ID_CONTROL,
corrupting the register and leaking a stack byte over USB.
> +
> + /* Address */
> + reg8 = (vid / 16);
> + ret = ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_ADDRESS, 1, 1, ®8);
> + if (ret < 0)
> + return ret;
> +
> + /* Data */
> + reg8 = vlan_ctrl | AX_VLAN_CONTROL_RD;
> + ret = ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_CONTROL, 1, 1, ®8);
> + if (ret < 0)
> + return ret;
> +
> + ret = ax88179_read_cmd(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_DATA0, 2, 2, ®16);
> + if (ret < 0)
> + return ret;
> + reg16 |= (1 << (vid % 16));
> + ret = ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_DATA0, 2, 2, ®16);
> + if (ret < 0)
> + return ret;
> +
> + reg8 = vlan_ctrl | AX_VLAN_CONTROL_WE;
> + ret = ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_CONTROL, 1, 1, ®8);
> + if (ret < 0)
> + return ret;
> +
> + return 0;
> +}
[Severity: Low]
This isn't a bug, but ax88179a_vlan_rx_kill_vid() and
ax88179a_vlan_rx_add_vid() duplicate the same five-step register sequence
and only differ in whether they clear or set the bit in reg16 (and the two
copies have already diverged in how reg8 and reg16 are initialized). A
shared helper taking a boolean flag would avoid the duplication.
> @@ -517,6 +599,75 @@ static int ax88179a_mii_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
> return phylink_mii_ioctl(data->phylink, rq, cmd);
> }
>
> +static int ax88179a_set_features(struct net_device *net, netdev_features_t features)
> +{
> + struct usbnet *dev = netdev_priv(net);
> + netdev_features_t changed;
> + int ret;
> + u8 tmp;
> +
> + changed = net->features ^ features;
> +
> + ret = ax88179_set_features(net, features);
> + if (ret)
> + return ret;
> +
> + if (changed & NETIF_F_HW_VLAN_CTAG_FILTER) {
> + if (features & NETIF_F_HW_VLAN_CTAG_FILTER) {
> + u8 vlan_state = 0;
> +
> + ret = ax88179_read_cmd(dev, AX_ACCESS_MAC,
> + AX88179A_VLAN_ID_CONTROL, 1, 1, &vlan_state);
> + if (ret < 0)
> + return ret;
> +
> + for (int i = 0; i < 256; i++) {
> + /* Address */
> + tmp = i;
> + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_ADDRESS,
> + 1, 1, &tmp);
> + /* Data */
> + ax88179_write_u16(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_DATA0,
> + 2, 0);
> + /* Write-Execute */
> + ax88179_write_u8(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_CONTROL,
> + 1, vlan_state | AX_VLAN_CONTROL_WE);\n> + }
[Severity: Medium]
Should the three USB writes inside this loop check for errors and break out
early?
If a write fails transiently and the final AX_VLAN_CONTROL_VFE write
succeeds, hardware VLAN filtering is enabled with stale entries left in the
filter table. On a persistent USB error or timeout, the loop runs all 768
synchronous control transfers under rtnl_lock, stalling for up to 768 *
USB_CTRL_SET_TIMEOUT and logging a warning on each failed transfer.
> + vlan_state |= AX_VLAN_CONTROL_VFE;
> + ret = ax88179_write_cmd(dev, AX_ACCESS_MAC,
> + AX88179A_VLAN_ID_CONTROL, 1, 1, &vlan_state);
> + if (ret < 0)
> + return ret;
> + } else {
> + ret = ax88179_read_cmd(dev, AX_ACCESS_MAC,
> + AX88179A_VLAN_ID_CONTROL, 1, 1, &tmp);
> + if (ret < 0)
> + return ret;
> + tmp &= ~AX_VLAN_CONTROL_VFE;
> + ret = ax88179_write_cmd(dev, AX_ACCESS_MAC,
> + AX88179A_VLAN_ID_CONTROL, 1, 1, &tmp);
> + if (ret < 0)
> + return ret;
> + }
> + }
> +
> + if (changed & NETIF_F_HW_VLAN_CTAG_RX) {
> + ret = ax88179_read_cmd(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_CONTROL,
> + 1, 1, &tmp);
> + if (ret < 0)
> + return ret;
> + if (features & NETIF_F_HW_VLAN_CTAG_RX)
> + tmp |= AX_VLAN_CONTROL_VSO;
> + else
> + tmp &= ~AX_VLAN_CONTROL_VSO;
> + ret = ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_CONTROL,
> + 1, 1, &tmp);
> + if (ret < 0)
> + return ret;
> + }
> + return 0;
> +}
[Severity: Medium]
Can a failure partway through ax88179a_set_features() leave hardware
offload state out of sync with net->features?
When multiple features change in one call (for example, enabling both
NETIF_F_HW_VLAN_CTAG_FILTER and NETIF_F_HW_VLAN_CTAG_RX) and the later
step fails, returning a negative error causes __netdev_update_features() to
leave dev->features unchanged and skip vlan_get_rx_ctag_filter_info().
AX_VLAN_CONTROL_VFE (or checksum offload changes from
ax88179_set_features()) then stays active in hardware with an all-zero
filter table while dev->features still reports the feature as disabled.
[ ... ]
> @@ -612,9 +766,11 @@ static int ax88179a_bind(struct usbnet *dev, struct usb_interface *intf)
> dev->mii.supports_gmii = 1;
>
> dev->net->features |= NETIF_F_SG | NETIF_F_IP_CSUM |
> - NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM | NETIF_F_TSO;
> + NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM | NETIF_F_TSO |
> + NETIF_F_HW_VLAN_CTAG_TX;
>
> dev->net->hw_features |= dev->net->features;
> + dev->net->hw_features |= NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_FILTER;
[Severity: Medium]
Does enabling NETIF_F_HW_VLAN_CTAG_TX here expose a race in
ax88179a_tx_fixup() that drops VLAN tags when the feature is toggled?
drivers/net/usb/ax88179a_devices.c:ax88179a_tx_fixup() {
...
if ((dev->net->features & NETIF_F_HW_VLAN_CTAG_TX) && (vlan_get_tag(skb, &tci) >= 0)) {
tx_desc |= AX179A_TX_DESC_VLAN;
tx_desc |= FIELD_PREP(AX179A_TX_DESC_VLAN_ID, (u64)tci);
}
...
}
CPU0 CPU1
validate_xmit_skb()
validate_xmit_vlan()
/* NETIF_F_HW_VLAN_CTAG_TX set:
* tag stays in skb->vlan_tci
*/
__netdev_update_features()
dev->features &=
~NETIF_F_HW_VLAN_CTAG_TX;
ax88179a_tx_fixup()
if (dev->net->features &
NETIF_F_HW_VLAN_CTAG_TX)
<-- false, frame sent untagged
ax88179a_tx_fixup() (added in commit "ax88179_178a: Add HW support for
AX179A-based chips") checks dev->net->features & NETIF_F_HW_VLAN_CTAG_TX
and calls vlan_get_tag() instead of checking skb_vlan_tag_present(skb) and
skb_vlan_tag_get(skb). If NETIF_F_HW_VLAN_CTAG_TX is cleared after
validate_xmit_vlan() has already left the tag out-of-band in skb->vlan_tci,
the frame is transmitted without its VLAN tag.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261106-ax88179a-v20-0-37b5a1189983@birger-koblitz.de?part=7
next prev parent reply other threads:[~2026-11-07 7:21 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-06 7:21 [PATCH net-next v20 00/13] ax88179_178a: Add support for AX88179A-based chips Birger Koblitz
2026-11-06 7:21 ` [PATCH net-next v20 01/13] phylink: Add phylink_mac_interrupt Birger Koblitz
2026-11-06 10:11 ` Maxime Chevallier
2026-11-06 15:32 ` Birger Koblitz
2026-11-06 15:55 ` Andrew Lunn
2026-11-07 7:21 ` sashiko-bot
2026-11-10 1:38 ` netdev-bot+sashiko
2026-11-10 4:46 ` Birger Koblitz
2026-11-10 16:30 ` Andrew Lunn
2026-11-10 16:58 ` Birger Koblitz
2026-11-06 7:21 ` [PATCH net-next v20 02/13] phylib: Add support for PHYs with broken forced mode Birger Koblitz
2026-11-07 7:21 ` sashiko-bot
2026-11-06 7:21 ` [PATCH net-next v20 03/13] ax88179_178a: Split driver into library and device specific code Birger Koblitz
2026-11-07 7:21 ` sashiko-bot
2026-11-10 1:38 ` netdev-bot+sashiko
2026-11-06 7:21 ` [PATCH net-next v20 04/13] ax88179_178a: Add HW support for AX179A-based chips Birger Koblitz
2026-11-07 7:21 ` sashiko-bot
2026-11-10 1:38 ` netdev-bot+sashiko
2026-11-06 7:21 ` [PATCH net-next v20 05/13] ax88179_178a: Add EEE configuration support for AX88179A MACs Birger Koblitz
2026-11-07 7:21 ` sashiko-bot
2026-11-10 1:38 ` netdev-bot+sashiko
2026-11-06 7:21 ` [PATCH net-next v20 06/13] ax88179_178a: Add EEE configuration support for AX88179A PHYs Birger Koblitz
2026-11-07 7:21 ` sashiko-bot
2026-11-10 1:38 ` netdev-bot+sashiko
2026-11-06 7:21 ` [PATCH net-next v20 07/13] ax88179_178a: Add VLAN offload support for AX88179A Birger Koblitz
2026-11-07 7:21 ` sashiko-bot [this message]
2026-11-10 1:38 ` netdev-bot+sashiko
2026-11-06 7:21 ` [PATCH net-next v20 08/13] ax88179_178a: Add AX179A/AX279 multicast configuration Birger Koblitz
2026-11-07 7:21 ` sashiko-bot
2026-11-10 1:38 ` netdev-bot+sashiko
2026-11-06 7:21 ` [PATCH net-next v20 09/13] ax88179_178a: Add Suspend/resume support for AX88179A/772D/279 Birger Koblitz
2026-11-07 7:21 ` sashiko-bot
2026-11-10 1:38 ` netdev-bot+sashiko
2026-11-06 7:21 ` [PATCH net-next v20 10/13] ax88179_178a: Add ethtool get_drvinfo Birger Koblitz
2026-11-07 7:21 ` sashiko-bot
2026-11-10 1:38 ` netdev-bot+sashiko
2026-11-06 7:21 ` [PATCH net-next v20 11/13] ax88179_178a: Update driver name and information Birger Koblitz
2026-11-07 7:21 ` sashiko-bot
2026-11-10 1:38 ` netdev-bot+sashiko
2026-11-06 7:21 ` [PATCH net-next v20 12/13] ax88179_178a: Add support for AX88179A/772D/279 EEPROM access Birger Koblitz
2026-11-07 7:21 ` sashiko-bot
2026-11-10 1:38 ` netdev-bot+sashiko
2026-11-06 7:21 ` [PATCH net-next v20 13/13] ax88796b: Add support for AX88772D, AX88179A and AX88279 Birger Koblitz
2026-11-07 7:21 ` sashiko-bot
2026-11-10 1:38 ` netdev-bot+sashiko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=sashiko-outbox-202697@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=mail@birger-koblitz.de \
--cc=sashiko-reviews@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.