<feed xmlns='http://www.w3.org/2005/Atom'>
<title>kernel.git/kernel/bpf/sockmap.c, branch linux-4.18.y</title>
<subtitle>Hosts the 0x221E linux distro kernel.
</subtitle>
<id>https://git.0xinfinity.dev/distro/kernel.git/atom?h=linux-4.18.y</id>
<link rel='self' href='https://git.0xinfinity.dev/distro/kernel.git/atom?h=linux-4.18.y'/>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/'/>
<updated>2018-10-20T07:47:08Z</updated>
<entry>
<title>bpf: sockmap, fix transition through disconnect without close</title>
<updated>2018-10-20T07:47:08Z</updated>
<author>
<name>John Fastabend</name>
</author>
<published>2018-09-18T16:01:49Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=19e43942cbb7d8721c926ecbce49b72e34a46944'/>
<id>urn:sha1:19e43942cbb7d8721c926ecbce49b72e34a46944</id>
<content type='text'>
[ Upstream commit b05545e15e1ff1d6a6a8593971275f9cc3e6b92b ]

It is possible (via shutdown()) for TCP socks to go trough TCP_CLOSE
state via tcp_disconnect() without actually calling tcp_close which
would then call our bpf_tcp_close() callback. Because of this a user
could disconnect a socket then put it in a LISTEN state which would
break our assumptions about sockets always being ESTABLISHED state.

To resolve this rely on the unhash hook, which is called in the
disconnect case, to remove the sock from the sockmap.

Reported-by: Eric Dumazet &lt;edumazet@google.com&gt;
Fixes: 1aa12bdf1bfb ("bpf: sockmap, add sock close() hook to remove socks")
Signed-off-by: John Fastabend &lt;john.fastabend@gmail.com&gt;
Acked-by: Yonghong Song &lt;yhs@fb.com&gt;
Signed-off-by: Daniel Borkmann &lt;daniel@iogearbox.net&gt;
Signed-off-by: Sasha Levin &lt;alexander.levin@microsoft.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>bpf: sockmap only allow ESTABLISHED sock state</title>
<updated>2018-10-20T07:47:08Z</updated>
<author>
<name>John Fastabend</name>
</author>
<published>2018-09-18T16:01:44Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=60c302b7aea508917611e6eb47c1bb1eba36fb5c'/>
<id>urn:sha1:60c302b7aea508917611e6eb47c1bb1eba36fb5c</id>
<content type='text'>
[ Upstream commit 5607fff303636d48b88414c6be353d9fed700af2 ]

After this patch we only allow socks that are in ESTABLISHED state or
are being added via a sock_ops event that is transitioning into an
ESTABLISHED state. By allowing sock_ops events we allow users to
manage sockmaps directly from sock ops programs. The two supported
sock_ops ops are BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB and
BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB.

Similar to TLS ULP this ensures sk_user_data is correct.

Reported-by: Eric Dumazet &lt;edumazet@google.com&gt;
Fixes: 1aa12bdf1bfb ("bpf: sockmap, add sock close() hook to remove socks")
Signed-off-by: John Fastabend &lt;john.fastabend@gmail.com&gt;
Acked-by: Yonghong Song &lt;yhs@fb.com&gt;
Signed-off-by: Daniel Borkmann &lt;daniel@iogearbox.net&gt;
Signed-off-by: Sasha Levin &lt;alexander.levin@microsoft.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>bpf: avoid misuse of psock when TCP_ULP_BPF collides with another ULP</title>
<updated>2018-10-10T06:55:55Z</updated>
<author>
<name>John Fastabend</name>
</author>
<published>2018-08-31T04:25:02Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=abb518640aaf758145c55dae868353247b23e30f'/>
<id>urn:sha1:abb518640aaf758145c55dae868353247b23e30f</id>
<content type='text'>
[ Upstream commit 597222f72a94118f593e4f32bf58ae7e049a0df1 ]

Currently we check sk_user_data is non NULL to determine if the sk
exists in a map. However, this is not sufficient to ensure the psock
or the ULP ops are not in use by another user, such as kcm or TLS. To
avoid this when adding a sock to a map also verify it is of the
correct ULP type. Additionally, when releasing a psock verify that
it is the TCP_ULP_BPF type before releasing the ULP. The error case
where we abort an update due to ULP collision can cause this error
path.

For example,

  __sock_map_ctx_update_elem()
     [...]
     err = tcp_set_ulp_id(sock, TCP_ULP_BPF) &lt;- collides with TLS
     if (err)                                &lt;- so err out here
        goto out_free
     [...]
  out_free:
     smap_release_sock() &lt;- calling tcp_cleanup_ulp releases the
                            TLS ULP incorrectly.

Fixes: 2f857d04601a ("bpf: sockmap, remove STRPARSER map_flags and add multi-map support")
Signed-off-by: John Fastabend &lt;john.fastabend@gmail.com&gt;
Signed-off-by: Daniel Borkmann &lt;daniel@iogearbox.net&gt;
Signed-off-by: Sasha Levin &lt;alexander.levin@microsoft.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>bpf: sockmap, decrement copied count correctly in redirect error case</title>
<updated>2018-10-10T06:55:51Z</updated>
<author>
<name>John Fastabend</name>
</author>
<published>2018-08-25T00:37:00Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=36de3d48270d530be6e5fb916a3bb52c36b87aba'/>
<id>urn:sha1:36de3d48270d530be6e5fb916a3bb52c36b87aba</id>
<content type='text'>
[ Upstream commit 501ca81760c204ec59b73e4a00bee5971fc0f1b1 ]

Currently, when a redirect occurs in sockmap and an error occurs in
the redirect call we unwind the scatterlist once in the error path
of bpf_tcp_sendmsg_do_redirect() and then again in sendmsg(). Then
in the error path of sendmsg we decrement the copied count by the
send size.

However, its possible we partially sent data before the error was
generated. This can happen if do_tcp_sendpages() partially sends the
scatterlist before encountering a memory pressure error. If this
happens we need to decrement the copied value (the value tracking
how many bytes were actually sent to TCP stack) by the number of
remaining bytes _not_ the entire send size. Otherwise we risk
confusing userspace.

Also we don't need two calls to free the scatterlist one is
good enough. So remove the one in bpf_tcp_sendmsg_do_redirect() and
then properly reduce copied by the number of remaining bytes which
may in fact be the entire send size if no bytes were sent.

To do this use bool to indicate if free_start_sg() should do mem
accounting or not.

Signed-off-by: John Fastabend &lt;john.fastabend@gmail.com&gt;
Signed-off-by: Daniel Borkmann &lt;daniel@iogearbox.net&gt;
Signed-off-by: Sasha Levin &lt;alexander.levin@microsoft.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>bpf, sockmap: fix psock refcount leak in bpf_tcp_recvmsg</title>
<updated>2018-10-10T06:55:51Z</updated>
<author>
<name>Daniel Borkmann</name>
</author>
<published>2018-08-24T20:08:51Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=7feb1f2b5d8d2b878adb7afcc23b6cb3df0eebbe'/>
<id>urn:sha1:7feb1f2b5d8d2b878adb7afcc23b6cb3df0eebbe</id>
<content type='text'>
[ Upstream commit 15c480efab01197c965ce0562a43ffedd852b8f9 ]

In bpf_tcp_recvmsg() we first took a reference on the psock, however
once we find that there are skbs in the normal socket's receive queue
we return with processing them through tcp_recvmsg(). Problem is that
we leak the taken reference on the psock in that path. Given we don't
really do anything with the psock at this point, move the skb_queue_empty()
test before we fetch the psock to fix this case.

Fixes: 8934ce2fd081 ("bpf: sockmap redirect ingress support")
Signed-off-by: Daniel Borkmann &lt;daniel@iogearbox.net&gt;
Acked-by: John Fastabend &lt;john.fastabend@gmail.com&gt;
Signed-off-by: Alexei Starovoitov &lt;ast@kernel.org&gt;
Signed-off-by: Sasha Levin &lt;alexander.levin@microsoft.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>bpf, sockmap: fix potential use after free in bpf_tcp_close</title>
<updated>2018-10-10T06:55:51Z</updated>
<author>
<name>Daniel Borkmann</name>
</author>
<published>2018-08-24T20:08:50Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=427e7707d9325a2cbf308221cc24e2761fa7245d'/>
<id>urn:sha1:427e7707d9325a2cbf308221cc24e2761fa7245d</id>
<content type='text'>
[ Upstream commit e06fa9c16ce4b740996189fa5610eabcee734e6c ]

bpf_tcp_close() we pop the psock linkage to a map via psock_map_pop().
A parallel update on the sock hash map can happen between psock_map_pop()
and lookup_elem_raw() where we override the element under link-&gt;hash /
link-&gt;key. In bpf_tcp_close()'s lookup_elem_raw() we subsequently only
test whether an element is present, but we do not test whether the
element is infact the element we were looking for.

We lock the sock in bpf_tcp_close() during that time, so do we hold
the lock in sock_hash_update_elem(). However, the latter locks the
sock which is newly updated, not the one we're purging from the hash
table. This means that while one CPU is doing the lookup from bpf_tcp_close(),
another CPU is doing the map update in parallel, dropped our sock from
the hlist and released the psock.

Subsequently the first CPU will find the new sock and attempts to drop
and release the old sock yet another time. Fix is that we need to check
the elements for a match after lookup, similar as we do in the sock map.
Note that the hash tab elems are freed via RCU, so access to their
link-&gt;hash / link-&gt;key is fine since we're under RCU read side there.

Fixes: e9db4ef6bf4c ("bpf: sockhash fix omitted bucket lock in sock_close")
Signed-off-by: Daniel Borkmann &lt;daniel@iogearbox.net&gt;
Acked-by: John Fastabend &lt;john.fastabend@gmail.com&gt;
Signed-off-by: Alexei Starovoitov &lt;ast@kernel.org&gt;
Signed-off-by: Sasha Levin &lt;alexander.levin@microsoft.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>bpf: sockmap: write_space events need to be passed to TCP handler</title>
<updated>2018-10-03T23:59:22Z</updated>
<author>
<name>John Fastabend</name>
</author>
<published>2018-08-22T15:37:37Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=a5c7547b45b43fd1e48fb4b34ea30261043356b9'/>
<id>urn:sha1:a5c7547b45b43fd1e48fb4b34ea30261043356b9</id>
<content type='text'>
[ Upstream commit 9b2e0388bec8ec5427403e23faff3b58dd1c3200 ]

When sockmap code is using the stream parser it also handles the write
space events in order to handle the case where (a) verdict redirects
skb to another socket and (b) the sockmap then sends the skb but due
to memory constraints (or other EAGAIN errors) needs to do a retry.

But the initial code missed a third case where the
skb_send_sock_locked() triggers an sk_wait_event(). A typically case
would be when sndbuf size is exceeded. If this happens because we
do not pass the write_space event to the lower layers we never wake
up the event and it will wait for sndtimeo. Which as noted in ktls
fix may be rather large and look like a hang to the user.

To reproduce the best test is to reduce the sndbuf size and send
1B data chunks to stress the memory handling. To fix this pass the
event from the upper layer to the lower layer.

Signed-off-by: John Fastabend &lt;john.fastabend@gmail.com&gt;
Signed-off-by: Daniel Borkmann &lt;daniel@iogearbox.net&gt;
Signed-off-by: Sasha Levin &lt;alexander.levin@microsoft.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>bpf, sockmap: fix sock hash count in alloc_sock_hash_elem</title>
<updated>2018-10-03T23:59:22Z</updated>
<author>
<name>Daniel Borkmann</name>
</author>
<published>2018-08-22T16:09:17Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=a0be77d6d94081333dbe79f531f2dc2866e58d94'/>
<id>urn:sha1:a0be77d6d94081333dbe79f531f2dc2866e58d94</id>
<content type='text'>
[ Upstream commit eb29429d81e31b191f3b2bd19cf820279cec6463 ]

When we try to allocate a new sock hash entry and the allocation
fails, then sock hash map fails to reduce the map element counter,
meaning we keep accounting this element although it was never used.
Fix it by dropping the element counter on error.

Fixes: 81110384441a ("bpf: sockmap, add hash map support")
Signed-off-by: Daniel Borkmann &lt;daniel@iogearbox.net&gt;
Acked-by: John Fastabend &lt;john.fastabend@gmail.com&gt;
Signed-off-by: Sasha Levin &lt;alexander.levin@microsoft.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>bpf, sockmap: fix sock_hash_alloc and reject zero-sized keys</title>
<updated>2018-10-03T23:59:22Z</updated>
<author>
<name>Daniel Borkmann</name>
</author>
<published>2018-08-21T13:55:00Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=efed642bc585c8d26bdba3b4de97d78057874bcf'/>
<id>urn:sha1:efed642bc585c8d26bdba3b4de97d78057874bcf</id>
<content type='text'>
[ Upstream commit b845c898b2f1ea458d5453f0fa1da6e2dfce3bb4 ]

Currently, it is possible to create a sock hash map with key size
of 0 and have the kernel return a fd back to user space. This is
invalid for hash maps (and kernel also hasn't been tested for zero
key size support in general at this point). Thus, reject such
configuration.

Fixes: 81110384441a ("bpf: sockmap, add hash map support")
Signed-off-by: Daniel Borkmann &lt;daniel@iogearbox.net&gt;
Acked-by: John Fastabend &lt;john.fastabend@gmail.com&gt;
Acked-by: Song Liu &lt;songliubraving@fb.com&gt;
Signed-off-by: Sasha Levin &lt;alexander.levin@microsoft.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>bpf, sockmap: fix leakage of smap_psock_map_entry</title>
<updated>2018-09-15T07:46:48Z</updated>
<author>
<name>Daniel Borkmann</name>
</author>
<published>2018-08-16T19:49:08Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=2262b26d750dce70bdaaa2fe68c016a18e1b5ff7'/>
<id>urn:sha1:2262b26d750dce70bdaaa2fe68c016a18e1b5ff7</id>
<content type='text'>
[ Upstream commit d40b0116c94bd8fc2b63aae35ce8e66bb53bba42 ]

While working on sockmap I noticed that we do not always kfree the
struct smap_psock_map_entry list elements which track psocks attached
to maps. In the case of sock_hash_ctx_update_elem(), these map entries
are allocated outside of __sock_map_ctx_update_elem() with their
linkage to the socket hash table filled. In the case of sock array,
the map entries are allocated inside of __sock_map_ctx_update_elem()
and added with their linkage to the psock-&gt;maps. Both additions are
under psock-&gt;maps_lock each.

Now, we drop these elements from their psock-&gt;maps list in a few
occasions: i) in sock array via smap_list_map_remove() when an entry
is either deleted from the map from user space, or updated via
user space or BPF program where we drop the old socket at that map
slot, or the sock array is freed via sock_map_free() and drops all
its elements; ii) for sock hash via smap_list_hash_remove() in exactly
the same occasions as just described for sock array; iii) in the
bpf_tcp_close() where we remove the elements from the list via
psock_map_pop() and iterate over them dropping themselves from either
sock array or sock hash; and last but not least iv) once again in
smap_gc_work() which is a callback for deferring the work once the
psock refcount hit zero and thus the socket is being destroyed.

Problem is that the only case where we kfree() the list entry is
in case iv), which at that point should have an empty list in
normal cases. So in cases from i) to iii) we unlink the elements
without freeing where they go out of reach from us. Hence fix is
to properly kfree() them as well to stop the leakage. Given these
are all handled under psock-&gt;maps_lock there is no need for deferred
RCU freeing.

I later also ran with kmemleak detector and it confirmed the finding
as well where in the state before the fix the object goes unreferenced
while after the patch no kmemleak report related to BPF showed up.

  [...]
  unreferenced object 0xffff880378eadae0 (size 64):
    comm "test_sockmap", pid 2225, jiffies 4294720701 (age 43.504s)
    hex dump (first 32 bytes):
      00 01 00 00 00 00 ad de 00 02 00 00 00 00 ad de  ................
      50 4d 75 5d 03 88 ff ff 00 00 00 00 00 00 00 00  PMu]............
    backtrace:
      [&lt;000000005225ac3c&gt;] sock_map_ctx_update_elem.isra.21+0xd8/0x210
      [&lt;0000000045dd6d3c&gt;] bpf_sock_map_update+0x29/0x60
      [&lt;00000000877723aa&gt;] ___bpf_prog_run+0x1e1f/0x4960
      [&lt;000000002ef89e83&gt;] 0xffffffffffffffff
  unreferenced object 0xffff880378ead240 (size 64):
    comm "test_sockmap", pid 2225, jiffies 4294720701 (age 43.504s)
    hex dump (first 32 bytes):
      00 01 00 00 00 00 ad de 00 02 00 00 00 00 ad de  ................
      00 44 75 5d 03 88 ff ff 00 00 00 00 00 00 00 00  .Du]............
    backtrace:
      [&lt;000000005225ac3c&gt;] sock_map_ctx_update_elem.isra.21+0xd8/0x210
      [&lt;0000000030e37a3a&gt;] sock_map_update_elem+0x125/0x240
      [&lt;000000002e5ce36e&gt;] map_update_elem+0x4eb/0x7b0
      [&lt;00000000db453cc9&gt;] __x64_sys_bpf+0x1f9/0x360
      [&lt;0000000000763660&gt;] do_syscall_64+0x9a/0x300
      [&lt;00000000422a2bb2&gt;] entry_SYSCALL_64_after_hwframe+0x44/0xa9
      [&lt;000000002ef89e83&gt;] 0xffffffffffffffff
  [...]

Fixes: e9db4ef6bf4c ("bpf: sockhash fix omitted bucket lock in sock_close")
Fixes: 54fedb42c653 ("bpf: sockmap, fix smap_list_map_remove when psock is in many maps")
Fixes: 2f857d04601a ("bpf: sockmap, remove STRPARSER map_flags and add multi-map support")
Signed-off-by: Daniel Borkmann &lt;daniel@iogearbox.net&gt;
Acked-by: John Fastabend &lt;john.fastabend@gmail.com&gt;
Acked-by: Song Liu &lt;songliubraving@fb.com&gt;
Signed-off-by: Alexei Starovoitov &lt;ast@kernel.org&gt;
Signed-off-by: Sasha Levin &lt;alexander.levin@microsoft.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
</feed>
