<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux/kernel/bpf/verifier.c, branch v4.20</title>
<subtitle>Mirror of https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/
</subtitle>
<id>https://git.shady.money/linux/atom?h=v4.20</id>
<link rel='self' href='https://git.shady.money/linux/atom?h=v4.20'/>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/'/>
<updated>2018-12-13T18:35:40Z</updated>
<entry>
<title>bpf: verifier: make sure callees don't prune with caller differences</title>
<updated>2018-12-13T18:35:40Z</updated>
<author>
<name>Jakub Kicinski</name>
<email>jakub.kicinski@netronome.com</email>
</author>
<published>2018-12-13T00:29:07Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=7640ead939247e91e84b7ec6ec001f30193cc7df'/>
<id>urn:sha1:7640ead939247e91e84b7ec6ec001f30193cc7df</id>
<content type='text'>
Currently for liveness and state pruning the register parentage
chains don't include states of the callee.  This makes some sense
as the callee can't access those registers.  However, this means
that READs done after the callee returns will not propagate into
the states of the callee.  Callee will then perform pruning
disregarding differences in caller state.

Example:

   0: (85) call bpf_user_rnd_u32
   1: (b7) r8 = 0
   2: (55) if r0 != 0x0 goto pc+1
   3: (b7) r8 = 1
   4: (bf) r1 = r8
   5: (85) call pc+4
   6: (15) if r8 == 0x1 goto pc+1
   7: (05) *(u64 *)(r9 - 8) = r3
   8: (b7) r0 = 0
   9: (95) exit

   10: (15) if r1 == 0x0 goto pc+0
   11: (95) exit

Here we acquire unknown state with call to get_random() [1].  Then
we store this random state in r8 (either 0 or 1) [1 - 3], and make
a call on line 5.  Callee does nothing but a trivial conditional
jump (to create a pruning point).  Upon return caller checks the
state of r8 and either performs an unsafe read or not.

Verifier will first explore the path with r8 == 1, creating a pruning
point at [11].  The parentage chain for r8 will include only callers
states so once verifier reaches [6] it will mark liveness only on states
in the caller, and not [11].  Now when verifier walks the paths with
r8 == 0 it will reach [11] and since REG_LIVE_READ on r8 was not
propagated there it will prune the walk entirely (stop walking
the entire program, not just the callee).  Since [6] was never walked
with r8 == 0, [7] will be considered dead and replaced with "goto -1"
causing hang at runtime.

This patch weaves the callee's explored states onto the callers
parentage chain.  Rough parentage for r8 would have looked like this
before:

[0] [1] [2] [3] [4] [5]   [10]      [11]      [6]      [7]
     |           |      ,---|----.    |        |        |
  sl0:         sl0:    / sl0:     \ sl0:      sl0:     sl0:
  fr0: r8 &lt;-- fr0: r8&lt;+--fr0: r8   `fr0: r8  ,fr0: r8&lt;-fr0: r8
                       \ fr1: r8 &lt;- fr1: r8 /
                        \__________________/

after:

[0] [1] [2] [3] [4] [5]   [10]      [11]      [6]      [7]
     |           |          |         |        |        |
   sl0:         sl0:      sl0:       sl0:      sl0:     sl0:
   fr0: r8 &lt;-- fr0: r8 &lt;- fr0: r8 &lt;- fr0: r8 &lt;-fr0: r8&lt;-fr0: r8
                          fr1: r8 &lt;- fr1: r8

Now the mark from instruction 6 will travel through callees states.

Note that we don't have to connect r0 because its overwritten by
callees state on return and r1 - r5 because those are not alive
any more once a call is made.

v2:
 - don't connect the callees registers twice (Alexei: suggestion &amp; code)
 - add more details to the comment (Ed &amp; Alexei)
v1: don't unnecessarily link caller saved regs (Jiong)

Fixes: f4d7e40a5b71 ("bpf: introduce function calls (verification)")
Reported-by: David Beckett &lt;david.beckett@netronome.com&gt;
Signed-off-by: Jakub Kicinski &lt;jakub.kicinski@netronome.com&gt;
Reviewed-by: Jiong Wang &lt;jiong.wang@netronome.com&gt;
Reviewed-by: Edward Cree &lt;ecree@solarflare.com&gt;
Signed-off-by: Alexei Starovoitov &lt;ast@kernel.org&gt;
</content>
</entry>
<entry>
<title>bpf: add per-insn complexity limit</title>
<updated>2018-12-04T16:22:02Z</updated>
<author>
<name>Alexei Starovoitov</name>
<email>ast@kernel.org</email>
</author>
<published>2018-12-04T06:46:06Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=ceefbc96fa5c5b975d87bf8e89ba8416f6b764d9'/>
<id>urn:sha1:ceefbc96fa5c5b975d87bf8e89ba8416f6b764d9</id>
<content type='text'>
malicious bpf program may try to force the verifier to remember
a lot of distinct verifier states.
Put a limit to number of per-insn 'struct bpf_verifier_state'.
Note that hitting the limit doesn't reject the program.
It potentially makes the verifier do more steps to analyze the program.
It means that malicious programs will hit BPF_COMPLEXITY_LIMIT_INSNS sooner
instead of spending cpu time walking long link list.

The limit of BPF_COMPLEXITY_LIMIT_STATES==64 affects cilium progs
with slight increase in number of "steps" it takes to successfully verify
the programs:
                       before    after
bpf_lb-DLB_L3.o         1940      1940
bpf_lb-DLB_L4.o         3089      3089
bpf_lb-DUNKNOWN.o       1065      1065
bpf_lxc-DDROP_ALL.o     28052  |  28162
bpf_lxc-DUNKNOWN.o      35487  |  35541
bpf_netdev.o            10864     10864
bpf_overlay.o           6643      6643
bpf_lcx_jit.o           38437     38437

But it also makes malicious program to be rejected in 0.4 seconds vs 6.5
Hence apply this limit to unprivileged programs only.

Signed-off-by: Alexei Starovoitov &lt;ast@kernel.org&gt;
Acked-by: Daniel Borkmann &lt;daniel@iogearbox.net&gt;
Acked-by: Edward Cree &lt;ecree@solarflare.com&gt;
Signed-off-by: Daniel Borkmann &lt;daniel@iogearbox.net&gt;
</content>
</entry>
<entry>
<title>bpf: improve verifier branch analysis</title>
<updated>2018-12-04T16:22:02Z</updated>
<author>
<name>Alexei Starovoitov</name>
<email>ast@kernel.org</email>
</author>
<published>2018-12-04T06:46:05Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=4f7b3e82589e0de723780198ec7983e427144c0a'/>
<id>urn:sha1:4f7b3e82589e0de723780198ec7983e427144c0a</id>
<content type='text'>
pathological bpf programs may try to force verifier to explode in
the number of branch states:
  20: (d5) if r1 s&lt;= 0x24000028 goto pc+0
  21: (b5) if r0 &lt;= 0xe1fa20 goto pc+2
  22: (d5) if r1 s&lt;= 0x7e goto pc+0
  23: (b5) if r0 &lt;= 0xe880e000 goto pc+0
  24: (c5) if r0 s&lt; 0x2100ecf4 goto pc+0
  25: (d5) if r1 s&lt;= 0xe880e000 goto pc+1
  26: (c5) if r0 s&lt; 0xf4041810 goto pc+0
  27: (d5) if r1 s&lt;= 0x1e007e goto pc+0
  28: (b5) if r0 &lt;= 0xe86be000 goto pc+0
  29: (07) r0 += 16614
  30: (c5) if r0 s&lt; 0x6d0020da goto pc+0
  31: (35) if r0 &gt;= 0x2100ecf4 goto pc+0

Teach verifier to recognize always taken and always not taken branches.
This analysis is already done for == and != comparison.
Expand it to all other branches.

It also helps real bpf programs to be verified faster:
                       before  after
bpf_lb-DLB_L3.o         2003    1940
bpf_lb-DLB_L4.o         3173    3089
bpf_lb-DUNKNOWN.o       1080    1065
bpf_lxc-DDROP_ALL.o     29584   28052
bpf_lxc-DUNKNOWN.o      36916   35487
bpf_netdev.o            11188   10864
bpf_overlay.o           6679    6643
bpf_lcx_jit.o           39555   38437

Reported-by: Anatoly Trosinenko &lt;anatoly.trosinenko@gmail.com&gt;
Signed-off-by: Alexei Starovoitov &lt;ast@kernel.org&gt;
Acked-by: Daniel Borkmann &lt;daniel@iogearbox.net&gt;
Acked-by: Edward Cree &lt;ecree@solarflare.com&gt;
Signed-off-by: Daniel Borkmann &lt;daniel@iogearbox.net&gt;
</content>
</entry>
<entry>
<title>bpf: check pending signals while verifying programs</title>
<updated>2018-12-04T16:22:02Z</updated>
<author>
<name>Alexei Starovoitov</name>
<email>ast@kernel.org</email>
</author>
<published>2018-12-04T06:46:04Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=c3494801cd1785e2c25f1a5735fa19ddcf9665da'/>
<id>urn:sha1:c3494801cd1785e2c25f1a5735fa19ddcf9665da</id>
<content type='text'>
Malicious user space may try to force the verifier to use as much cpu
time and memory as possible. Hence check for pending signals
while verifying the program.
Note that suspend of sys_bpf(PROG_LOAD) syscall will lead to EAGAIN,
since the kernel has to release the resources used for program verification.

Reported-by: Anatoly Trosinenko &lt;anatoly.trosinenko@gmail.com&gt;
Signed-off-by: Alexei Starovoitov &lt;ast@kernel.org&gt;
Acked-by: Daniel Borkmann &lt;daniel@iogearbox.net&gt;
Acked-by: Edward Cree &lt;ecree@solarflare.com&gt;
Signed-off-by: Daniel Borkmann &lt;daniel@iogearbox.net&gt;
</content>
</entry>
<entry>
<title>bpf: fix off-by-one error in adjust_subprog_starts</title>
<updated>2018-11-17T05:10:00Z</updated>
<author>
<name>Edward Cree</name>
<email>ecree@solarflare.com</email>
</author>
<published>2018-11-16T12:00:07Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=afd594240806acc138cf696c09f2f4829d55d02f'/>
<id>urn:sha1:afd594240806acc138cf696c09f2f4829d55d02f</id>
<content type='text'>
When patching in a new sequence for the first insn of a subprog, the start
 of that subprog does not change (it's the first insn of the sequence), so
 adjust_subprog_starts should check start &lt;= off (rather than &lt; off).
Also added a test to test_verifier.c (it's essentially the syz reproducer).

Fixes: cc8b0b92a169 ("bpf: introduce function calls (function boundaries)")
Reported-by: syzbot+4fc427c7af994b0948be@syzkaller.appspotmail.com
Signed-off-by: Edward Cree &lt;ecree@solarflare.com&gt;
Acked-by: Yonghong Song &lt;yhs@fb.com&gt;
Signed-off-by: Alexei Starovoitov &lt;ast@kernel.org&gt;
</content>
</entry>
<entry>
<title>bpf: don't set id on after map lookup with ptr_to_map_val return</title>
<updated>2018-10-31T23:53:17Z</updated>
<author>
<name>Daniel Borkmann</name>
<email>daniel@iogearbox.net</email>
</author>
<published>2018-10-31T23:05:53Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=4d31f30148cea6e97e42616231eed55295117fe7'/>
<id>urn:sha1:4d31f30148cea6e97e42616231eed55295117fe7</id>
<content type='text'>
In the verifier there is no such semantics where registers with
PTR_TO_MAP_VALUE type have an id assigned to them. This is only
used in PTR_TO_MAP_VALUE_OR_NULL and later on nullified once the
test against NULL has been pattern matched and type transformed
into PTR_TO_MAP_VALUE.

Fixes: 3e6a4b3e0289 ("bpf/verifier: introduce BPF_PTR_TO_MAP_VALUE")
Signed-off-by: Daniel Borkmann &lt;daniel@iogearbox.net&gt;
Cc: Roman Gushchin &lt;guro@fb.com&gt;
Acked-by: Alexei Starovoitov &lt;ast@kernel.org&gt;
Signed-off-by: Alexei Starovoitov &lt;ast@kernel.org&gt;
</content>
</entry>
<entry>
<title>bpf: fix partial copy of map_ptr when dst is scalar</title>
<updated>2018-10-31T23:53:17Z</updated>
<author>
<name>Daniel Borkmann</name>
<email>daniel@iogearbox.net</email>
</author>
<published>2018-10-31T23:05:52Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=0962590e553331db2cc0aef2dc35c57f6300dbbe'/>
<id>urn:sha1:0962590e553331db2cc0aef2dc35c57f6300dbbe</id>
<content type='text'>
ALU operations on pointers such as scalar_reg += map_value_ptr are
handled in adjust_ptr_min_max_vals(). Problem is however that map_ptr
and range in the register state share a union, so transferring state
through dst_reg-&gt;range = ptr_reg-&gt;range is just buggy as any new
map_ptr in the dst_reg is then truncated (or null) for subsequent
checks. Fix this by adding a raw member and use it for copying state
over to dst_reg.

Fixes: f1174f77b50c ("bpf/verifier: rework value tracking")
Signed-off-by: Daniel Borkmann &lt;daniel@iogearbox.net&gt;
Cc: Edward Cree &lt;ecree@solarflare.com&gt;
Acked-by: Alexei Starovoitov &lt;ast@kernel.org&gt;
Signed-off-by: Alexei Starovoitov &lt;ast@kernel.org&gt;
</content>
</entry>
<entry>
<title>bpf: make direct packet write unclone more robust</title>
<updated>2018-10-26T00:02:06Z</updated>
<author>
<name>Daniel Borkmann</name>
<email>daniel@iogearbox.net</email>
</author>
<published>2018-10-24T20:05:49Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=b09928b976280d64060d7bee146d7df5c5a29bef'/>
<id>urn:sha1:b09928b976280d64060d7bee146d7df5c5a29bef</id>
<content type='text'>
Given this seems to be quite fragile and can easily slip through the
cracks, lets make direct packet write more robust by requiring that
future program types which allow for such write must provide a prologue
callback. In case of XDP and sk_msg it's noop, thus add a generic noop
handler there. The latter starts out with NULL data/data_end unconditionally
when sg pages are shared.

Signed-off-by: Daniel Borkmann &lt;daniel@iogearbox.net&gt;
Acked-by: Alexei Starovoitov &lt;ast@kernel.org&gt;
Acked-by: Song Liu &lt;songliubraving@fb.com&gt;
Signed-off-by: Alexei Starovoitov &lt;ast@kernel.org&gt;
</content>
</entry>
<entry>
<title>bpf: fix cg_skb types to hint access type in may_access_direct_pkt_data</title>
<updated>2018-10-26T00:02:06Z</updated>
<author>
<name>Daniel Borkmann</name>
<email>daniel@iogearbox.net</email>
</author>
<published>2018-10-24T20:05:46Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=d5563d367c2ce48ea3d675c77f7109f37311943d'/>
<id>urn:sha1:d5563d367c2ce48ea3d675c77f7109f37311943d</id>
<content type='text'>
Commit b39b5f411dcf ("bpf: add cg_skb_is_valid_access for
BPF_PROG_TYPE_CGROUP_SKB") added direct packet access for skbs in
cg_skb program types, however allowed access type was not added to
the may_access_direct_pkt_data() helper. Therefore the latter always
returns false. This is not directly an issue, it just means writes
are unconditionally disabled (which is correct) but also reads.
Latter is relevant in this function when BPF helpers may read direct
packet data which is unconditionally disabled then. Fix it by properly
adding BPF_PROG_TYPE_CGROUP_SKB to may_access_direct_pkt_data().

Fixes: b39b5f411dcf ("bpf: add cg_skb_is_valid_access for BPF_PROG_TYPE_CGROUP_SKB")
Signed-off-by: Daniel Borkmann &lt;daniel@iogearbox.net&gt;
Acked-by: Alexei Starovoitov &lt;ast@kernel.org&gt;
Cc: Song Liu &lt;songliubraving@fb.com&gt;
Signed-off-by: Alexei Starovoitov &lt;ast@kernel.org&gt;
</content>
</entry>
<entry>
<title>bpf: fix direct packet access for flow dissector progs</title>
<updated>2018-10-26T00:02:06Z</updated>
<author>
<name>Daniel Borkmann</name>
<email>daniel@iogearbox.net</email>
</author>
<published>2018-10-24T20:05:45Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=5d66fa7d9e9e9399ddfdc530f352dd6f7c724485'/>
<id>urn:sha1:5d66fa7d9e9e9399ddfdc530f352dd6f7c724485</id>
<content type='text'>
Commit d58e468b1112 ("flow_dissector: implements flow dissector BPF
hook") added direct packet access for skbs in may_access_direct_pkt_data()
function where this enables read and write access to the skb-&gt;data. This
is buggy because without a prologue generator such as bpf_unclone_prologue()
we would allow for writing into cloned skbs. Original intention might have
been to only allow read access where this is not needed (similar as the
flow_dissector_func_proto() indicates which enables only bpf_skb_load_bytes()
as well), therefore this patch fixes it to restrict to read-only.

Fixes: d58e468b1112 ("flow_dissector: implements flow dissector BPF hook")
Signed-off-by: Daniel Borkmann &lt;daniel@iogearbox.net&gt;
Acked-by: Alexei Starovoitov &lt;ast@kernel.org&gt;
Cc: Petar Penkov &lt;ppenkov@google.com&gt;
Signed-off-by: Alexei Starovoitov &lt;ast@kernel.org&gt;
</content>
</entry>
</feed>
