ath10k: Fix NULL pointer dereference in AHB device probe
[platform/kernel/linux-starfive.git] / tools / testing / selftests / bpf / progs / bpf_iter_netlink.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2020 Facebook */
3 /* "undefine" structs in vmlinux.h, because we "override" them below */
4 #define bpf_iter_meta bpf_iter_meta___not_used
5 #define bpf_iter__netlink bpf_iter__netlink___not_used
6 #include "vmlinux.h"
7 #undef bpf_iter_meta
8 #undef bpf_iter__netlink
9 #include <bpf/bpf_helpers.h>
10 #include <bpf/bpf_tracing.h>
11
12 char _license[] SEC("license") = "GPL";
13
14 #define sk_rmem_alloc   sk_backlog.rmem_alloc
15 #define sk_refcnt       __sk_common.skc_refcnt
16
17 struct bpf_iter_meta {
18         struct seq_file *seq;
19         __u64 session_id;
20         __u64 seq_num;
21 } __attribute__((preserve_access_index));
22
23 struct bpf_iter__netlink {
24         struct bpf_iter_meta *meta;
25         struct netlink_sock *sk;
26 } __attribute__((preserve_access_index));
27
28 static inline struct inode *SOCK_INODE(struct socket *socket)
29 {
30         return &container_of(socket, struct socket_alloc, socket)->vfs_inode;
31 }
32
33 SEC("iter/netlink")
34 int dump_netlink(struct bpf_iter__netlink *ctx)
35 {
36         struct seq_file *seq = ctx->meta->seq;
37         struct netlink_sock *nlk = ctx->sk;
38         unsigned long group, ino;
39         struct inode *inode;
40         struct socket *sk;
41         struct sock *s;
42
43         if (nlk == (void *)0)
44                 return 0;
45
46         if (ctx->meta->seq_num == 0)
47                 BPF_SEQ_PRINTF(seq, "sk               Eth Pid        Groups   "
48                                     "Rmem     Wmem     Dump  Locks    Drops    "
49                                     "Inode\n");
50
51         s = &nlk->sk;
52         BPF_SEQ_PRINTF(seq, "%pK %-3d ", s, s->sk_protocol);
53
54         if (!nlk->groups)  {
55                 group = 0;
56         } else {
57                 /* FIXME: temporary use bpf_probe_read here, needs
58                  * verifier support to do direct access.
59                  */
60                 bpf_probe_read(&group, sizeof(group), &nlk->groups[0]);
61         }
62         BPF_SEQ_PRINTF(seq, "%-10u %08x %-8d %-8d %-5d %-8d ",
63                        nlk->portid, (u32)group,
64                        s->sk_rmem_alloc.counter,
65                        s->sk_wmem_alloc.refs.counter - 1,
66                        nlk->cb_running, s->sk_refcnt.refs.counter);
67
68         sk = s->sk_socket;
69         if (!sk) {
70                 ino = 0;
71         } else {
72                 /* FIXME: container_of inside SOCK_INODE has a forced
73                  * type conversion, and direct access cannot be used
74                  * with current verifier.
75                  */
76                 inode = SOCK_INODE(sk);
77                 bpf_probe_read(&ino, sizeof(ino), &inode->i_ino);
78         }
79         BPF_SEQ_PRINTF(seq, "%-8u %-8lu\n", s->sk_drops.counter, ino);
80
81         return 0;
82 }