From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.remote-ip=85.215.255.50 ARC-Seal: i=2; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=fail; t=1792669359; b=X3CMY45G5Of9WKIspTOt2rvYNc1XNSiCayq9fjxuL1H54jdTfSrZ+JigIysGNjbUZfFy qFgcNdZUUtW6BZyEYis3/4ATk1opn5oJ4nEaNLbHIdghhdNa4lfUp8j0BVNS4LhTeXCZm eE+6jjbwBkwAldLhaWPOUqNmMpUjR+4BQvAQ1dLOQ972vZpu5W1oicFzic+wZbNjNUuxI w4pWNYOHWIOtF5jlSHV6mlhGskC4yQcT3PyP7nmvV1rmnRTHcrkHeVUr17GCKpRf6It+k KjzaTj6nathDVD6M0TJB5HzNYk68CmExMqpJwgXHl1rAWe69uE4EITGO6GDezb1+p5w== ARC-Message-Signature: i=2; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1792669359; h=DMARC-Filter:X-RZG-CLASS-ID:DKIM-Signature:DKIM-Signature:X-RZG-AUTH: Received:From:To:Cc:Subject:Date:Message-ID:X-Mailer:In-Reply-To: References:MIME-Version:Content-Transfer-Encoding:Content-Type; bh=KZYd9VblaYmBT57UxtED41ec1jbkb+z1alkVxY08M68=; b=P3mC0eIwn9d0dM7wTQ0zrxSibnFyG5jJTA1HkpvGQKx4jcbn0AntzVrLuX5IUvpOJPnM 9tQUr4Uhi8FzIzOrO0ySMtxruY5NVkY5C8ckfrsJqWGQ5oKQvd9bruFI4CbiZjGx0WxW/ 4PvLUCOYAkwtmaQN+N1+auAvR+cmOTGm3yzhBCRovQ7kJy2rwLY1od5NpHKWzOhFimx2j +W2KLrknUWUtfrmt1mmSw472Q2MTB5VlVlbxGVg54eAcMA188MAeyNyaSqhvqWw9KHyxO 2v1KpAa4oZ3ecoU8Qvs1F1kZ8xHnfXDEp3Z5eVmHE3mPKTbUcg27lECudSpRWJxmAdA== ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass header.from=hartkopp.net; spf=fail smtp.mailfrom=hartkopp.net; dkim=pass header.d=hartkopp.net header.i=@hartkopp.net header.a=rsa-sha256 header.s=strato-dkim-0002 header.b="WTtRbJ/m"; dkim=pass header.d=hartkopp.net header.i=@hartkopp.net header.a=ed25519-sha256 header.s=strato-dkim-0003 header.b=EKOfRNd3; arc=fail smtp.remote-ip=85.215.255.50 Received: from mo4-p01-ob.smtp.rzone.de (mo4-p01-ob.smtp.rzone.de [85.215.255.50]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AE377606A31A for ; Thu, 22 Oct 2026 11:42:38 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.2 smtp.subspace.kernel.org AE377606A31A Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=hartkopp.net Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=hartkopp.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key, unprotected) header.d=hartkopp.net header.i=@hartkopp.net header.a=rsa-sha256 header.s=strato-dkim-0002 header.b=WTtRbJ/m; dkim=pass header.d=hartkopp.net header.i=@hartkopp.net header.a=ed25519-sha256 header.s=strato-dkim-0003 header.b=EKOfRNd3 ARC-Seal: i=1; a=rsa-sha256; t=1792669338; cv=none; d=strato.com; s=strato-dkim-0002; b=LoIoX/VkdtStIWIresnYyVKsere0t3V1r1n7iPlBo1881SGj92j005kMqC/Q9yQlnQ bxwwO3ZHM6EYdlJTl+kFpJ/cmTE7UbUzXr2D6qQcqYfjaYYZispXQz3nji2RM3h/iuAx QHIYCshe80hZ/1NXJpdKfr+JVE435yzR6jIaF/Ey6qOOnCdY22isos8nJiLwds8LJJGs YOJswKPxOwbMoppQ9XNyRy1/Bm959XbLWmwNOdQdTcC43074MPWOc7ik/mN0u7GFQ3b7 lqTcqudRS9ZM5nKsCXEliYvMP2/YRpQqU++7i9Ygjul1LCu33ejGAdrLRoqtMn9uuMeh GNJg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; t=1792669338; s=strato-dkim-0002; d=strato.com; h=References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=KZYd9VblaYmBT57UxtED41ec1jbkb+z1alkVxY08M68=; b=k4pcSSI/3RC8TJ8y1HuyfRt0gUG8a5VanCcFunx37VwrLOHpDKk9LnDM7PamFZxGYH FwxRZ9HVyinDsD/iikC53EZXJywlgRVmGQCAuIOj/uFb3zdgWnUijzP9U4nydYC1OJo+ 6b0DIJXKpQADsiv6Tp+La42MBrGjyPR3eBzFpQVRZy53s6nQZuHnZYCEprebxIjl+tlG amcxgqwcfylJQhZ0USmJHQUueLsApM88rQtH+CwOwnJ0JPWzGEoJ8gITiF6jlrAmqEbY QOi8V+WItTo+pbaWs2IWi1HMY9qAFiW9AwLDbr6TqUwPfK2muYhwMwwseycw4uM8Uv49 iVnA== ARC-Authentication-Results: i=1; strato.com; arc=none; dkim=none X-RZG-CLASS-ID: mo01 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1792669338; s=strato-dkim-0002; d=hartkopp.net; h=References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=KZYd9VblaYmBT57UxtED41ec1jbkb+z1alkVxY08M68=; b=WTtRbJ/m+U9BtIQrjn9HtDEZA0VKrZNw/xXvpMVJ5mDgP176Mm+9xpxniNTMOu++SP fZPJ/YLT/1VIWavMKfiuMDE8okm/YgEO9v2STKbMWxraOzuzJ/6vW83lMZXEaLzLZdRY IYzRnOjQUuAa7T/dNVrhSWI2pSuONV9nqhhW3Iu5IrAx5ONk5N6RsmyUlNrLSf9KZfhI 8Q9ug4dSJavTz+Wz2gmwN0Y2M3n+4MboFVAk9ahnznb05Ci56gQf2Gsa+fDR7+zqleuW e448pqpU13s4fidovGiofuwoesm4/tQ25GK3SmIizQ2KeNp/6LvJVHeNlZ/oJLFevCWk OCSQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; t=1792669338; s=strato-dkim-0003; d=hartkopp.net; h=References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=KZYd9VblaYmBT57UxtED41ec1jbkb+z1alkVxY08M68=; b=EKOfRNd3azkxFo5oVF36MmBBSF+Ik0BfTMFsq7nR2MUeVgBXaMzvZWh42jD0kriwDh n2FAMXA1sWMwYxr3aLAg== X-RZG-AUTH: ":P2MHfkW8eP4Mre39l357AZT/I7AY/7nT2yrDxb8mjH4JKvMdQv2tTUsMrZpkO3Mw3lZ/t54cFxeEQ7s8bDup0Q==" Received: from vivo.lan by smtp.strato.de (RZmta 55.6.3 AUTH) with ESMTPSA id Kfdf2a29MBgIo53 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits)) (Client did not present a certificate); Thu, 22 Oct 2026 13:42:18 +0200 (CEST) From: Oliver Hartkopp To: linux-can@vger.kernel.org Cc: Oliver Hartkopp , Sebastian Andrzej Siewior Subject: [PATCH can-next v7 3/5] can: proc: remove pointers from CAN specific proc output Date: Thu, 22 Oct 2026 13:41:59 +0200 Message-ID: <20261022114202.180023-4-socketcan@hartkopp.net> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20261022114202.180023-1-socketcan@hartkopp.net> References: <20261022114202.180023-1-socketcan@hartkopp.net> X-Mailing-List: linux-can@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="us-ascii" The proc content in /proc/net/can/ and /proc/net/can-bcm/ is intended to check the internal filter lists (af_can, can_raw) and the efficiency and functionality of can_bcm jobs. While exposing kernel addresses was acceptable when this code was written the times have changed and multiple attempts have been made to hash or remove such now sensitive data. This patch removes the disclosure of pointers and instead provides the function names and sock inode numbers when available. When the function name can not be resolved (e.g. KALLSYMS=n or stripped module symbols) %ps would fall back to the raw text address. Therefore (unknown) is printed instead in this case. As there's no known tooling around the CAN specific proc output breaking the ABI with this rework creates no issue. Suggested-by: Sebastian Andrzej Siewior Signed-off-by: Oliver Hartkopp --- Documentation/networking/can.rst | 16 ++++++++++------ include/linux/can/core.h | 2 +- net/can/af_can.c | 6 +++--- net/can/af_can.h | 2 +- net/can/bcm.c | 14 +++++++------- net/can/gw.c | 2 +- net/can/isotp.c | 4 ++-- net/can/j1939/main.c | 2 +- net/can/proc.c | 26 ++++++++++++++++---------- net/can/raw.c | 4 ++-- 10 files changed, 44 insertions(+), 34 deletions(-) diff --git a/Documentation/networking/can.rst b/Documentation/networking/can.rst index 536ff411da1d..51bc70748f75 100644 --- a/Documentation/networking/can.rst +++ b/Documentation/networking/can.rst @@ -1038,21 +1038,25 @@ procfs content As described in :ref:`socketcan-receive-lists` the SocketCAN core uses several filter lists to deliver received CAN frames to CAN protocol modules. These receive lists, their filters and the count of filter matches can be checked in the appropriate receive list. All entries contain the -device and a protocol module identifier:: +CAN network device, the filter (can_id/can_mask), the number of filter +matches, the inode number of the subscribing socket and the name of the +receive function. A sock_inode of 0 denotes a kernel internal subscriber +without a socket (e.g. CAN gateway or J1939). When the function name can +not be resolved (e.g. with CONFIG_KALLSYMS=n) "(unknown)" is printed:: foo@bar:~$ cat /proc/net/can/rcvlist_all receive list 'rx_all': - (vcan3: no entry) - (vcan2: no entry) - (vcan1: no entry) - device can_id can_mask function userdata matches ident - vcan0 000 00000000 f88e6370 f6c6f400 0 raw (any: no entry) + device can_id can_mask matches sock_inode function + vcan0 000 00000000 0 63586 raw_rcv [can_raw] + (vcan1: no entry) + (vcan2: no entry) + (vcan3: no entry) In this example an application requests any CAN traffic from vcan0:: rcvlist_all - list for unfiltered entries (no filter operations) rcvlist_eff - list for single extended frame (EFF) entries diff --git a/include/linux/can/core.h b/include/linux/can/core.h index 2de74c2b78b6..effb5c31ef40 100644 --- a/include/linux/can/core.h +++ b/include/linux/can/core.h @@ -49,11 +49,11 @@ 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 *net, struct net_device *dev, canid_t can_id, canid_t mask, void (*func)(struct sk_buff *, void *), - void *data, char *ident, struct sock *sk); + void *data, u64 ino, struct sock *sk); extern void can_rx_unregister(struct net *net, struct net_device *dev, canid_t can_id, canid_t mask, void (*func)(struct sk_buff *, void *), void *data); diff --git a/net/can/af_can.c b/net/can/af_can.c index 34fe3b28d576..6ebe9d3689ac 100644 --- a/net/can/af_can.c +++ b/net/can/af_can.c @@ -416,11 +416,11 @@ static struct hlist_head *can_rcv_list_find(canid_t *can_id, canid_t *mask, * @dev: pointer to netdevice (NULL => subscribe from 'all' CAN devices list) * @can_id: CAN identifier (see description) * @mask: CAN mask (see description) * @func: callback function on filter match * @data: returned parameter for callback function - * @ident: string for calling module identification + * @ino: inode number of sock (0 = unknown) * @sk: socket pointer (might be NULL) * * Description: * Invokes the callback function with the received sk_buff and the given * parameter 'data' on a matching receive filter. A filter matches, when @@ -441,11 +441,11 @@ static struct hlist_head *can_rcv_list_find(canid_t *can_id, canid_t *mask, * -ENOMEM on missing cache mem to create subscription entry * -ENODEV unknown device */ int can_rx_register(struct net *net, struct net_device *dev, canid_t can_id, canid_t mask, void (*func)(struct sk_buff *, void *), - void *data, char *ident, struct sock *sk) + void *data, u64 ino, struct sock *sk) { struct receiver *rcv; struct hlist_head *rcv_list; struct can_dev_rcv_lists *dev_rcv_lists; struct can_rcv_lists_stats *rcv_lists_stats = net->can.rcv_lists_stats; @@ -470,11 +470,11 @@ int can_rx_register(struct net *net, struct net_device *dev, canid_t can_id, rcv->can_id = can_id; rcv->mask = mask; atomic_long_set(&rcv->matches, 0); rcv->func = func; rcv->data = data; - rcv->ident = ident; + rcv->ino = ino; rcv->sk = sk; hlist_add_head_rcu(&rcv->list, rcv_list); dev_rcv_lists->entries++; diff --git a/net/can/af_can.h b/net/can/af_can.h index 87887014f562..6e593ed5db5f 100644 --- a/net/can/af_can.h +++ b/net/can/af_can.h @@ -53,11 +53,11 @@ struct receiver { canid_t can_id; canid_t mask; atomic_long_t matches; void (*func)(struct sk_buff *skb, void *data); void *data; - char *ident; + u64 ino; struct sock *sk; struct rcu_head rcu; }; /* statistic structures */ diff --git a/net/can/bcm.c b/net/can/bcm.c index 3d637a1e0ac1..6c85a76477c3 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c @@ -218,13 +218,11 @@ static int bcm_proc_show(struct seq_file *m, void *v) struct net *net = m->private; struct sock *sk = (struct sock *)pde_data(m->file->f_inode); struct bcm_sock *bo = bcm_sk(sk); struct bcm_op *op; - seq_printf(m, ">>> socket %pK", sk->sk_socket); - seq_printf(m, " / sk %pK", sk); - seq_printf(m, " / bo %pK", bo); + seq_printf(m, ">>> sock inode %s", bo->procname); seq_printf(m, " / dropped %lu", bo->dropped_usr_msgs); seq_printf(m, " / bound %s", bcm_proc_getifname(net, ifname, bo->ifindex)); seq_printf(m, " <<<\n"); rcu_read_lock(); @@ -1534,11 +1532,11 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, if (dev) { err = can_rx_register(sock_net(sk), dev, op->can_id, REGMASK(op->can_id), bcm_rx_handler, op, - "bcm", sk); + sock_i_ino(sk), sk); /* keep a tracked reference so that a later * unregister can safely reach the device even * if a concurrent NETDEV_UNREGISTER has * already unlisted it by ifindex @@ -1558,11 +1556,12 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, } } else { err = can_rx_register(sock_net(sk), NULL, op->can_id, REGMASK(op->can_id), - bcm_rx_handler, op, "bcm", sk); + bcm_rx_handler, op, + sock_i_ino(sk), sk); } if (err) { /* newly created bcm rx op is broken -> remove it */ if (new_op) { @@ -2038,12 +2037,13 @@ static int bcm_connect(struct socket *sock, struct sockaddr_unsized *uaddr, int bo->ifindex = 0; } #if IS_ENABLED(CONFIG_PROC_FS) if (net->can.bcmproc_dir) { - /* unique socket address as filename */ - sprintf(bo->procname, "%llu", sock_i_ino(sk)); + /* use unique socket inode number as filename */ + snprintf(bo->procname, sizeof(bo->procname), + "%llu", sock_i_ino(sk)); bo->bcm_proc_read = proc_create_net_single(bo->procname, 0644, net->can.bcmproc_dir, bcm_proc_show, sk); if (!bo->bcm_proc_read) { ret = -ENOMEM; diff --git a/net/can/gw.c b/net/can/gw.c index 5793cb2420ed..36f9aa0f7026 100644 --- a/net/can/gw.c +++ b/net/can/gw.c @@ -577,11 +577,11 @@ static void can_can_gw_rcv(struct sk_buff *skb, void *data) static inline int cgw_register_filter(struct net *net, struct cgw_job *gwj) { return can_rx_register(net, gwj->src.dev, gwj->ccgw.filter.can_id, gwj->ccgw.filter.can_mask, can_can_gw_rcv, - gwj, "gw", NULL); + gwj, 0, NULL); } static inline void cgw_unregister_filter(struct net *net, struct cgw_job *gwj) { can_rx_unregister(net, gwj->src.dev, gwj->ccgw.filter.can_id, diff --git a/net/can/isotp.c b/net/can/isotp.c index f5dc9d04bd68..b239f4b45518 100644 --- a/net/can/isotp.c +++ b/net/can/isotp.c @@ -1623,18 +1623,18 @@ static int isotp_bind(struct socket *sock, struct sockaddr_unsized *uaddr, int l ifindex = dev->ifindex; if (isotp_register_rxid(so)) can_rx_register(net, dev, rx_id, SINGLE_MASK(rx_id), - isotp_rcv, sk, "isotp", sk); + isotp_rcv, sk, sock_i_ino(sk), sk); /* no consecutive frame echo skb in flight */ WRITE_ONCE(so->cfecho, 0); /* register for echo skb's */ can_rx_register(net, dev, tx_id, SINGLE_MASK(tx_id), - isotp_rcv_echo, sk, "isotpe", sk); + isotp_rcv_echo, sk, sock_i_ino(sk), sk); /* switch to new settings */ so->ifindex = ifindex; so->rxid = rx_id; so->txid = tx_id; diff --git a/net/can/j1939/main.c b/net/can/j1939/main.c index 5e5e6c228f22..d9384cf0e356 100644 --- a/net/can/j1939/main.c +++ b/net/can/j1939/main.c @@ -182,11 +182,11 @@ static int j1939_can_rx_register(struct j1939_priv *priv) struct net_device *ndev = priv->ndev; int ret; j1939_priv_get(priv); ret = can_rx_register(dev_net(ndev), ndev, J1939_CAN_ID, J1939_CAN_MASK, - j1939_can_recv, priv, "j1939", NULL); + j1939_can_recv, priv, 0, NULL); if (ret < 0) { j1939_priv_put(priv); return ret; } diff --git a/net/can/proc.c b/net/can/proc.c index fb144d2adc35..b7496d2a37cd 100644 --- a/net/can/proc.c +++ b/net/can/proc.c @@ -202,30 +202,36 @@ static void can_print_rcvlist(struct seq_file *m, struct hlist_head *rx_list, struct net_device *dev) { struct receiver *r; hlist_for_each_entry_rcu(r, rx_list, list) { + char symcheck[4]; char *fmt = (r->can_id & CAN_EFF_FLAG)? - " %-5s %08x %08x %pK %pK %8ld %s\n" : - " %-5s %03x %08x %pK %pK %8ld %s\n"; + " %6s %08x %08x %8ld %10llu" : + " %6s %03x %08x %8ld %10llu"; seq_printf(m, fmt, DNAME(dev), r->can_id, r->mask, - r->func, r->data, atomic_long_read(&r->matches), - r->ident); + atomic_long_read(&r->matches), r->ino); + + /* %ps falls back to the raw text address when the symbol + * can not be resolved (KALLSYMS=n, stripped module symbols) + */ + snprintf(symcheck, sizeof(symcheck), "%ps", r->func); + if (strncmp(symcheck, "0x", 2)) + seq_printf(m, " %ps\n", r->func); + else + seq_puts(m, " (unknown)\n"); } } static void can_print_recv_banner(struct seq_file *m) { /* - * can1. 00000000 00000000 00000000 - * ....... 0 tp20 + * device can_id can_mask matches sock_inode function + * vcan0 000 00000000 0 43798 raw_rcv [can_raw] */ - if (IS_ENABLED(CONFIG_64BIT)) - seq_puts(m, " device can_id can_mask function userdata matches ident\n"); - else - seq_puts(m, " device can_id can_mask function userdata matches ident\n"); + seq_puts(m, " device can_id can_mask matches sock_inode function\n"); } static int can_stats_proc_show(struct seq_file *m, void *v) { struct net *net = m->private; diff --git a/net/can/raw.c b/net/can/raw.c index 6944ebab3feb..3e57f72a3afe 100644 --- a/net/can/raw.c +++ b/net/can/raw.c @@ -224,11 +224,11 @@ static int raw_enable_filters(struct net *net, struct net_device *dev, int i; for (i = 0; i < count; i++) { err = can_rx_register(net, dev, filter[i].can_id, filter[i].can_mask, - raw_rcv, sk, "raw", sk); + raw_rcv, sk, sock_i_ino(sk), sk); if (err) { /* clean up successfully registered filters */ while (--i >= 0) can_rx_unregister(net, dev, filter[i].can_id, filter[i].can_mask, @@ -245,11 +245,11 @@ static int raw_enable_errfilter(struct net *net, struct net_device *dev, { int err = 0; if (err_mask) err = can_rx_register(net, dev, 0, err_mask | CAN_ERR_FLAG, - raw_rcv, sk, "raw", sk); + raw_rcv, sk, sock_i_ino(sk), sk); return err; } static void raw_disable_filters(struct net *net, struct net_device *dev, -- 2.43.0