diff mbox series

[net,v3] vlan: enforce underlying device type

Message ID 20250303155619.8918-1-oscmaes92@gmail.com (mailing list archive)
State New
Delegated to: Netdev Maintainers
Headers show
Series [net,v3] vlan: enforce underlying device type | expand

Checks

Context Check Description
netdev/series_format success Single patches do not need cover letters
netdev/tree_selection success Clearly marked for net
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag present in non-next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 0 this patch: 0
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers success CCed 7 of 7 maintainers
netdev/build_clang success Errors and warnings before: 0 this patch: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 2 this patch: 2
netdev/checkpatch warning WARNING: line length of 93 exceeds 80 columns
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
netdev/contest success net-next-2025-03-03--18-00 (tests: 893)

Commit Message

Oscar Maes March 3, 2025, 3:56 p.m. UTC
Currently, VLAN devices can be created on top of non-ethernet devices.

Besides the fact that it doesn't make much sense, this also causes a
bug which leaks the address of a kernel function to usermode.

When creating a VLAN device, we initialize GARP (garp_init_applicant)
and MRP (mrp_init_applicant) for the underlying device.

As part of the initialization process, we add the multicast address of
each applicant to the underlying device, by calling dev_mc_add.

__dev_mc_add uses dev->addr_len to determine the length of the new
multicast address.

This causes an out-of-bounds read if dev->addr_len is greater than 6,
since the multicast addresses provided by GARP and MRP are only 6
bytes long.

This behaviour can be reproduced using the following commands:

ip tunnel add gretest mode ip6gre local ::1 remote ::2 dev lo
ip l set up dev gretest
ip link add link gretest name vlantest type vlan id 100

Then, the following command will display the address of garp_pdu_rcv:

ip maddr show | grep 01:80:c2:00:00:21

Fix the bug by enforcing the type of the underlying device during VLAN
device initialization.

Fixes: 22bedad3ce11 ("net: convert multicast list to list_head")
Reported-by: syzbot+91161fe81857b396c8a0@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/netdev/000000000000ca9a81061a01ec20@google.com/
Signed-off-by: Oscar Maes <oscmaes92@gmail.com>
---
 net/8021q/vlan.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Jiri Pirko March 3, 2025, 4:01 p.m. UTC | #1
Mon, Mar 03, 2025 at 04:56:19PM +0100, oscmaes92@gmail.com wrote:
>Currently, VLAN devices can be created on top of non-ethernet devices.
>
>Besides the fact that it doesn't make much sense, this also causes a
>bug which leaks the address of a kernel function to usermode.
>
>When creating a VLAN device, we initialize GARP (garp_init_applicant)
>and MRP (mrp_init_applicant) for the underlying device.
>
>As part of the initialization process, we add the multicast address of
>each applicant to the underlying device, by calling dev_mc_add.
>
>__dev_mc_add uses dev->addr_len to determine the length of the new
>multicast address.
>
>This causes an out-of-bounds read if dev->addr_len is greater than 6,
>since the multicast addresses provided by GARP and MRP are only 6
>bytes long.
>
>This behaviour can be reproduced using the following commands:
>
>ip tunnel add gretest mode ip6gre local ::1 remote ::2 dev lo
>ip l set up dev gretest
>ip link add link gretest name vlantest type vlan id 100
>
>Then, the following command will display the address of garp_pdu_rcv:
>
>ip maddr show | grep 01:80:c2:00:00:21
>
>Fix the bug by enforcing the type of the underlying device during VLAN
>device initialization.
>
>Fixes: 22bedad3ce11 ("net: convert multicast list to list_head")
>Reported-by: syzbot+91161fe81857b396c8a0@syzkaller.appspotmail.com
>Closes: https://lore.kernel.org/netdev/000000000000ca9a81061a01ec20@google.com/
>Signed-off-by: Oscar Maes <oscmaes92@gmail.com>


Reviewed-by: Jiri Pirko <jiri@nvidia.com>
diff mbox series

Patch

diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index e45187b88..73a92e748 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -131,7 +131,7 @@  int vlan_check_real_dev(struct net_device *real_dev,
 {
 	const char *name = real_dev->name;
 
-	if (real_dev->features & NETIF_F_VLAN_CHALLENGED) {
+	if (real_dev->features & NETIF_F_VLAN_CHALLENGED || real_dev->type != ARPHRD_ETHER) {
 		pr_info("VLANs not supported on %s\n", name);
 		NL_SET_ERR_MSG_MOD(extack, "VLANs not supported on device");
 		return -EOPNOTSUPP;