mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-18 08:28:03 +07:00
f1712c7371
Zhang Yanmin reported crashes [1] and provided a patch adding a synchronize_rcu() call in can_rx_unregister() The main problem seems that the sockets themselves are not RCU protected. If CAN uses RCU for delivery, then sockets should be freed only after one RCU grace period. Recent kernels could use sock_set_flag(sk, SOCK_RCU_FREE), but let's ease stable backports with the following fix instead. [1] BUG: unable to handle kernel NULL pointer dereference at (null) IP: [<ffffffff81495e25>] selinux_socket_sock_rcv_skb+0x65/0x2a0 Call Trace: <IRQ> [<ffffffff81485d8c>] security_sock_rcv_skb+0x4c/0x60 [<ffffffff81d55771>] sk_filter+0x41/0x210 [<ffffffff81d12913>] sock_queue_rcv_skb+0x53/0x3a0 [<ffffffff81f0a2b3>] raw_rcv+0x2a3/0x3c0 [<ffffffff81f06eab>] can_rcv_filter+0x12b/0x370 [<ffffffff81f07af9>] can_receive+0xd9/0x120 [<ffffffff81f07beb>] can_rcv+0xab/0x100 [<ffffffff81d362ac>] __netif_receive_skb_core+0xd8c/0x11f0 [<ffffffff81d36734>] __netif_receive_skb+0x24/0xb0 [<ffffffff81d37f67>] process_backlog+0x127/0x280 [<ffffffff81d36f7b>] net_rx_action+0x33b/0x4f0 [<ffffffff810c88d4>] __do_softirq+0x184/0x440 [<ffffffff81f9e86c>] do_softirq_own_stack+0x1c/0x30 <EOI> [<ffffffff810c76fb>] do_softirq.part.18+0x3b/0x40 [<ffffffff810c8bed>] do_softirq+0x1d/0x20 [<ffffffff81d30085>] netif_rx_ni+0xe5/0x110 [<ffffffff8199cc87>] slcan_receive_buf+0x507/0x520 [<ffffffff8167ef7c>] flush_to_ldisc+0x21c/0x230 [<ffffffff810e3baf>] process_one_work+0x24f/0x670 [<ffffffff810e44ed>] worker_thread+0x9d/0x6f0 [<ffffffff810e4450>] ? rescuer_thread+0x480/0x480 [<ffffffff810ebafc>] kthread+0x12c/0x150 [<ffffffff81f9ccef>] ret_from_fork+0x3f/0x70 Reported-by: Zhang Yanmin <yanmin.zhang@intel.com> Signed-off-by: Eric Dumazet <edumazet@google.com> Acked-by: Oliver Hartkopp <socketcan@hartkopp.net> Signed-off-by: David S. Miller <davem@davemloft.net>
61 lines
1.7 KiB
C
61 lines
1.7 KiB
C
/*
|
|
* linux/can/core.h
|
|
*
|
|
* Protoypes and definitions for CAN protocol modules using the PF_CAN core
|
|
*
|
|
* Authors: Oliver Hartkopp <oliver.hartkopp@volkswagen.de>
|
|
* Urs Thuermann <urs.thuermann@volkswagen.de>
|
|
* Copyright (c) 2002-2007 Volkswagen Group Electronic Research
|
|
* All rights reserved.
|
|
*
|
|
*/
|
|
|
|
#ifndef _CAN_CORE_H
|
|
#define _CAN_CORE_H
|
|
|
|
#include <linux/can.h>
|
|
#include <linux/skbuff.h>
|
|
#include <linux/netdevice.h>
|
|
|
|
#define CAN_VERSION "20120528"
|
|
|
|
/* increment this number each time you change some user-space interface */
|
|
#define CAN_ABI_VERSION "9"
|
|
|
|
#define CAN_VERSION_STRING "rev " CAN_VERSION " abi " CAN_ABI_VERSION
|
|
|
|
#define DNAME(dev) ((dev) ? (dev)->name : "any")
|
|
|
|
/**
|
|
* struct can_proto - CAN protocol structure
|
|
* @type: type argument in socket() syscall, e.g. SOCK_DGRAM.
|
|
* @protocol: protocol number in socket() syscall.
|
|
* @ops: pointer to struct proto_ops for sock->ops.
|
|
* @prot: pointer to struct proto structure.
|
|
*/
|
|
struct can_proto {
|
|
int type;
|
|
int protocol;
|
|
const struct proto_ops *ops;
|
|
struct proto *prot;
|
|
};
|
|
|
|
/* function prototypes for the CAN networklayer core (af_can.c) */
|
|
|
|
extern int can_proto_register(const struct can_proto *cp);
|
|
extern void can_proto_unregister(const struct can_proto *cp);
|
|
|
|
int can_rx_register(struct net_device *dev, canid_t can_id, canid_t mask,
|
|
void (*func)(struct sk_buff *, void *),
|
|
void *data, char *ident, struct sock *sk);
|
|
|
|
extern void can_rx_unregister(struct net_device *dev, canid_t can_id,
|
|
canid_t mask,
|
|
void (*func)(struct sk_buff *, void *),
|
|
void *data);
|
|
|
|
extern int can_send(struct sk_buff *skb, int loop);
|
|
extern int can_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
|
|
|
|
#endif /* !_CAN_CORE_H */
|