netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Alexei Starovoitov <ast@fb.com>
To: Sandipan Das <sandipan@linux.vnet.ibm.com>, <netdev@vger.kernel.org>
Cc: <linux-kernel@vger.kernel.org>, <daniel@iogearbox.net>,
	<naveen.n.rao@linux.vnet.ibm.com>,
	Martin KaFai Lau <kafai@fb.com>
Subject: Re: [RFC PATCH] bpf: Add helpers to read useful task_struct members
Date: Sat, 4 Nov 2017 18:34:27 +0900	[thread overview]
Message-ID: <94a4761f-1b51-8b70-fb7f-3cea91c69717@fb.com> (raw)
In-Reply-To: <20171103065833.8076-1-sandipan@linux.vnet.ibm.com>

On 11/3/17 3:58 PM, Sandipan Das wrote:
> For added security, the layout of some structures can be
> randomized by enabling CONFIG_GCC_PLUGIN_RANDSTRUCT. One
> such structure is task_struct. To build BPF programs, we
> use Clang which does not support this feature. So, if we
> attempt to read a field of a structure with a randomized
> layout within a BPF program, we do not get the expected
> value because of incorrect offsets. To observe this, it
> is not mandatory to have CONFIG_GCC_PLUGIN_RANDSTRUCT
> enabled because the structure annotations/members added
> for this purpose are enough to cause this. So, all kernel
> builds are affected.
>
> For example, considering samples/bpf/offwaketime_kern.c,
> if we try to print the values of pid and comm inside the
> task_struct passed to waker() by adding the following
> lines of code at the appropriate place
>
>   char fmt[] = "waker(): p->pid = %u, p->comm = %s\n";
>   bpf_trace_printk(fmt, sizeof(fmt), _(p->pid), _(p->comm));
>
> it is seen that upon rebuilding and running this sample
> followed by inspecting /sys/kernel/debug/tracing/trace,
> the output looks like the following
>
>                                _-----=> irqs-off
>                               / _----=> need-resched
>                              | / _---=> hardirq/softirq
>                              || / _--=> preempt-depth
>                              ||| /     delay
>             TASK-PID   CPU#  ||||    TIMESTAMP  FUNCTION
>                | |       |   ||||       |         |
>           <idle>-0     [007] d.s.  1883.443594: 0x00000001: waker(): p->pid = 0, p->comm =
>           <idle>-0     [018] d.s.  1883.453588: 0x00000001: waker(): p->pid = 0, p->comm =
>           <idle>-0     [007] d.s.  1883.463584: 0x00000001: waker(): p->pid = 0, p->comm =
>           <idle>-0     [009] d.s.  1883.483586: 0x00000001: waker(): p->pid = 0, p->comm =
>           <idle>-0     [005] d.s.  1883.493583: 0x00000001: waker(): p->pid = 0, p->comm =
>           <idle>-0     [009] d.s.  1883.503583: 0x00000001: waker(): p->pid = 0, p->comm =
>           <idle>-0     [018] d.s.  1883.513578: 0x00000001: waker(): p->pid = 0, p->comm =
>  systemd-journal-3140  [003] d...  1883.627660: 0x00000001: waker(): p->pid = 0, p->comm =
>  systemd-journal-3140  [003] d...  1883.627704: 0x00000001: waker(): p->pid = 0, p->comm =
>  systemd-journal-3140  [003] d...  1883.627723: 0x00000001: waker(): p->pid = 0, p->comm =
>
> To avoid this, we add new BPF helpers that read the
> correct values for some of the important task_struct
> members such as pid, tgid, comm and flags which are
> extensively used in BPF-based analysis tools such as
> bcc. Since these helpers are built with GCC, they use
> the correct offsets when referencing a member.
>
> Signed-off-by: Sandipan Das <sandipan@linux.vnet.ibm.com>
...
> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
> index f90860d1f897..324508d27bd2 100644
> --- a/include/uapi/linux/bpf.h
> +++ b/include/uapi/linux/bpf.h
> @@ -338,6 +338,16 @@ union bpf_attr {
>   *     @skb: pointer to skb
>   *     Return: classid if != 0
>   *
> + * u64 bpf_get_task_pid_tgid(struct task_struct *task)
> + *     Return: task->tgid << 32 | task->pid
> + *
> + * int bpf_get_task_comm(struct task_struct *task)
> + *     Stores task->comm into buf
> + *     Return: 0 on success or negative error
> + *
> + * u32 bpf_get_task_flags(struct task_struct *task)
> + *     Return: task->flags
> + *

I don't think it's a solution.
Tracing scripts read other fields too.
Making it work for these 3 fields is a drop in a bucket.
If randomization is used I think we have to accept
that existing bpf scripts won't be usable.
Long term solution is to support 'BPF Type Format' or BTF
(which is old C-Type Format) for kernel data structures,
so bcc scripts wouldn't need to use kernel headers and clang.
The proper offsets will be described in BTF.
We were planning to use it initially to describe map key/value,
but it applies for this case as well.
There will be a tool that will take dwarf from vmlinux and
compress it into BTF. Kernel will also be able to verify
that BTF is a valid BTF.
I'm assuming that gcc randomization plugin produces dwarf
with correct offsets, if not, it would have to be fixed.

  reply	other threads:[~2017-11-04  9:34 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-03  6:58 [RFC PATCH] bpf: Add helpers to read useful task_struct members Sandipan Das
2017-11-04  9:34 ` Alexei Starovoitov [this message]
2017-11-04 17:31   ` Naveen N. Rao
2017-11-04 21:10     ` Alexei Starovoitov
2017-11-06 15:55       ` Naveen N. Rao
2017-11-07  8:08         ` Alexei Starovoitov
2017-11-07  8:37           ` Naveen N. Rao
2017-11-07 21:14             ` Y Song
2017-11-07 21:31               ` Atish Patra
2017-11-07 21:45                 ` Y Song
2017-11-07 21:39               ` Alexei Starovoitov
2017-11-07 21:47                 ` Y Song
2017-11-07 22:04                   ` Alexei Starovoitov
2017-11-07 22:42                     ` Y Song
2017-11-08  0:29                       ` Atish Patra
2017-11-08  1:25                         ` Y Song
2017-11-06  5:16     ` Sandipan Das
2017-11-07  0:16 ` Tushar Dave

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=94a4761f-1b51-8b70-fb7f-3cea91c69717@fb.com \
    --to=ast@fb.com \
    --cc=daniel@iogearbox.net \
    --cc=kafai@fb.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=naveen.n.rao@linux.vnet.ibm.com \
    --cc=netdev@vger.kernel.org \
    --cc=sandipan@linux.vnet.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).