Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright (c) 2020 Facebook */
0003 #include "bpf_iter.h"
0004 #include <bpf/bpf_helpers.h>
0005 
0006 char _license[] SEC("license") = "GPL";
0007 
0008 #define MAX_STACK_TRACE_DEPTH   64
0009 unsigned long entries[MAX_STACK_TRACE_DEPTH] = {};
0010 #define SIZE_OF_ULONG (sizeof(unsigned long))
0011 
0012 SEC("iter/task")
0013 int dump_task_stack(struct bpf_iter__task *ctx)
0014 {
0015     struct seq_file *seq = ctx->meta->seq;
0016     struct task_struct *task = ctx->task;
0017     long i, retlen;
0018 
0019     if (task == (void *)0)
0020         return 0;
0021 
0022     retlen = bpf_get_task_stack(task, entries,
0023                     MAX_STACK_TRACE_DEPTH * SIZE_OF_ULONG, 0);
0024     if (retlen < 0)
0025         return 0;
0026 
0027     BPF_SEQ_PRINTF(seq, "pid: %8u num_entries: %8u\n", task->pid,
0028                retlen / SIZE_OF_ULONG);
0029     for (i = 0; i < MAX_STACK_TRACE_DEPTH; i++) {
0030         if (retlen > i * SIZE_OF_ULONG)
0031             BPF_SEQ_PRINTF(seq, "[<0>] %pB\n", (void *)entries[i]);
0032     }
0033     BPF_SEQ_PRINTF(seq, "\n");
0034 
0035     return 0;
0036 }
0037 
0038 SEC("iter/task")
0039 int get_task_user_stacks(struct bpf_iter__task *ctx)
0040 {
0041     struct seq_file *seq = ctx->meta->seq;
0042     struct task_struct *task = ctx->task;
0043     uint64_t buf_sz = 0;
0044     int64_t res;
0045 
0046     if (task == (void *)0)
0047         return 0;
0048 
0049     res = bpf_get_task_stack(task, entries,
0050             MAX_STACK_TRACE_DEPTH * SIZE_OF_ULONG, BPF_F_USER_STACK);
0051     if (res <= 0)
0052         return 0;
0053 
0054     buf_sz += res;
0055 
0056     /* If the verifier doesn't refine bpf_get_task_stack res, and instead
0057      * assumes res is entirely unknown, this program will fail to load as
0058      * the verifier will believe that max buf_sz value allows reading
0059      * past the end of entries in bpf_seq_write call
0060      */
0061     bpf_seq_write(seq, &entries, buf_sz);
0062     return 0;
0063 }