Patch "af_packet: fix vlan_get_protocol_dgram() vs MSG_PEEK" has been added to the 6.6-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    af_packet: fix vlan_get_protocol_dgram() vs MSG_PEEK

to the 6.6-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     af_packet-fix-vlan_get_protocol_dgram-vs-msg_peek.patch
and it can be found in the queue-6.6 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit eb2cda0a4e2d230511b3fe0c7416a6c8fd588732
Author: Eric Dumazet <edumazet@xxxxxxxxxx>
Date:   Mon Dec 30 16:10:04 2024 +0000

    af_packet: fix vlan_get_protocol_dgram() vs MSG_PEEK
    
    [ Upstream commit f91a5b8089389eb408501af2762f168c3aaa7b79 ]
    
    Blamed commit forgot MSG_PEEK case, allowing a crash [1] as found
    by syzbot.
    
    Rework vlan_get_protocol_dgram() to not touch skb at all,
    so that it can be used from many cpus on the same skb.
    
    Add a const qualifier to skb argument.
    
    [1]
    skbuff: skb_under_panic: text:ffffffff8a8ccd05 len:29 put:14 head:ffff88807fc8e400 data:ffff88807fc8e3f4 tail:0x11 end:0x140 dev:<NULL>
    ------------[ cut here ]------------
     kernel BUG at net/core/skbuff.c:206 !
    Oops: invalid opcode: 0000 [#1] PREEMPT SMP KASAN PTI
    CPU: 1 UID: 0 PID: 5892 Comm: syz-executor883 Not tainted 6.13.0-rc4-syzkaller-00054-gd6ef8b40d075 #0
    Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024
     RIP: 0010:skb_panic net/core/skbuff.c:206 [inline]
     RIP: 0010:skb_under_panic+0x14b/0x150 net/core/skbuff.c:216
    Code: 0b 8d 48 c7 c6 86 d5 25 8e 48 8b 54 24 08 8b 0c 24 44 8b 44 24 04 4d 89 e9 50 41 54 41 57 41 56 e8 5a 69 79 f7 48 83 c4 20 90 <0f> 0b 0f 1f 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 f3
    RSP: 0018:ffffc900038d7638 EFLAGS: 00010282
    RAX: 0000000000000087 RBX: dffffc0000000000 RCX: 609ffd18ea660600
    RDX: 0000000000000000 RSI: 0000000080000000 RDI: 0000000000000000
    RBP: ffff88802483c8d0 R08: ffffffff817f0a8c R09: 1ffff9200071ae60
    R10: dffffc0000000000 R11: fffff5200071ae61 R12: 0000000000000140
    R13: ffff88807fc8e400 R14: ffff88807fc8e3f4 R15: 0000000000000011
    FS:  00007fbac5e006c0(0000) GS:ffff8880b8700000(0000) knlGS:0000000000000000
    CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    CR2: 00007fbac5e00d58 CR3: 000000001238e000 CR4: 00000000003526f0
    DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
    DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
    Call Trace:
     <TASK>
      skb_push+0xe5/0x100 net/core/skbuff.c:2636
      vlan_get_protocol_dgram+0x165/0x290 net/packet/af_packet.c:585
      packet_recvmsg+0x948/0x1ef0 net/packet/af_packet.c:3552
      sock_recvmsg_nosec net/socket.c:1033 [inline]
      sock_recvmsg+0x22f/0x280 net/socket.c:1055
      ____sys_recvmsg+0x1c6/0x480 net/socket.c:2803
      ___sys_recvmsg net/socket.c:2845 [inline]
      do_recvmmsg+0x426/0xab0 net/socket.c:2940
      __sys_recvmmsg net/socket.c:3014 [inline]
      __do_sys_recvmmsg net/socket.c:3037 [inline]
      __se_sys_recvmmsg net/socket.c:3030 [inline]
      __x64_sys_recvmmsg+0x199/0x250 net/socket.c:3030
      do_syscall_x64 arch/x86/entry/common.c:52 [inline]
      do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
     entry_SYSCALL_64_after_hwframe+0x77/0x7f
    
    Fixes: 79eecf631c14 ("af_packet: Handle outgoing VLAN packets without hardware offloading")
    Reported-by: syzbot+74f70bb1cb968bf09e4f@xxxxxxxxxxxxxxxxxxxxxxxxx
    Closes: https://lore.kernel.org/netdev/6772c485.050a0220.2f3838.04c5.GAE@xxxxxxxxxx/T/#u
    Signed-off-by: Eric Dumazet <edumazet@xxxxxxxxxx>
    Cc: Chengen Du <chengen.du@xxxxxxxxxxxxx>
    Reviewed-by: Willem de Bruijn <willemb@xxxxxxxxxx>
    Link: https://patch.msgid.link/20241230161004.2681892-2-edumazet@xxxxxxxxxx
    Signed-off-by: Jakub Kicinski <kuba@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index 3028af87716e..430749a0f362 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -585,13 +585,16 @@ static inline int vlan_get_tag(const struct sk_buff *skb, u16 *vlan_tci)
  * vlan_get_protocol - get protocol EtherType.
  * @skb: skbuff to query
  * @type: first vlan protocol
+ * @mac_offset: MAC offset
  * @depth: buffer to store length of eth and vlan tags in bytes
  *
  * Returns the EtherType of the packet, regardless of whether it is
  * vlan encapsulated (normal or hardware accelerated) or not.
  */
-static inline __be16 __vlan_get_protocol(const struct sk_buff *skb, __be16 type,
-					 int *depth)
+static inline __be16 __vlan_get_protocol_offset(const struct sk_buff *skb,
+						__be16 type,
+						int mac_offset,
+						int *depth)
 {
 	unsigned int vlan_depth = skb->mac_len, parse_depth = VLAN_MAX_DEPTH;
 
@@ -610,7 +613,8 @@ static inline __be16 __vlan_get_protocol(const struct sk_buff *skb, __be16 type,
 		do {
 			struct vlan_hdr vhdr, *vh;
 
-			vh = skb_header_pointer(skb, vlan_depth, sizeof(vhdr), &vhdr);
+			vh = skb_header_pointer(skb, mac_offset + vlan_depth,
+						sizeof(vhdr), &vhdr);
 			if (unlikely(!vh || !--parse_depth))
 				return 0;
 
@@ -625,6 +629,12 @@ static inline __be16 __vlan_get_protocol(const struct sk_buff *skb, __be16 type,
 	return type;
 }
 
+static inline __be16 __vlan_get_protocol(const struct sk_buff *skb, __be16 type,
+					 int *depth)
+{
+	return __vlan_get_protocol_offset(skb, type, 0, depth);
+}
+
 /**
  * vlan_get_protocol - get protocol EtherType.
  * @skb: skbuff to query
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 96eca4a290ad..4abf7e9ac4f2 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -568,21 +568,13 @@ static u16 vlan_get_tci(const struct sk_buff *skb, struct net_device *dev)
 	return ntohs(vh->h_vlan_TCI);
 }
 
-static __be16 vlan_get_protocol_dgram(struct sk_buff *skb)
+static __be16 vlan_get_protocol_dgram(const struct sk_buff *skb)
 {
 	__be16 proto = skb->protocol;
 
-	if (unlikely(eth_type_vlan(proto))) {
-		u8 *skb_orig_data = skb->data;
-		int skb_orig_len = skb->len;
-
-		skb_push(skb, skb->data - skb_mac_header(skb));
-		proto = __vlan_get_protocol(skb, proto, NULL);
-		if (skb_orig_data != skb->data) {
-			skb->data = skb_orig_data;
-			skb->len = skb_orig_len;
-		}
-	}
+	if (unlikely(eth_type_vlan(proto)))
+		proto = __vlan_get_protocol_offset(skb, proto,
+						   skb_mac_offset(skb), NULL);
 
 	return proto;
 }




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux