|
@@ -1125,6 +1125,14 @@ pointer type. The types of pointers describe their base, as follows:
|
|
PTR_TO_STACK Frame pointer.
|
|
PTR_TO_STACK Frame pointer.
|
|
PTR_TO_PACKET skb->data.
|
|
PTR_TO_PACKET skb->data.
|
|
PTR_TO_PACKET_END skb->data + headlen; arithmetic forbidden.
|
|
PTR_TO_PACKET_END skb->data + headlen; arithmetic forbidden.
|
|
|
|
+ PTR_TO_SOCKET Pointer to struct bpf_sock_ops, implicitly refcounted.
|
|
|
|
+ PTR_TO_SOCKET_OR_NULL
|
|
|
|
+ Either a pointer to a socket, or NULL; socket lookup
|
|
|
|
+ returns this type, which becomes a PTR_TO_SOCKET when
|
|
|
|
+ checked != NULL. PTR_TO_SOCKET is reference-counted,
|
|
|
|
+ so programs must release the reference through the
|
|
|
|
+ socket release function before the end of the program.
|
|
|
|
+ Arithmetic on these pointers is forbidden.
|
|
However, a pointer may be offset from this base (as a result of pointer
|
|
However, a pointer may be offset from this base (as a result of pointer
|
|
arithmetic), and this is tracked in two parts: the 'fixed offset' and 'variable
|
|
arithmetic), and this is tracked in two parts: the 'fixed offset' and 'variable
|
|
offset'. The former is used when an exactly-known value (e.g. an immediate
|
|
offset'. The former is used when an exactly-known value (e.g. an immediate
|
|
@@ -1171,6 +1179,13 @@ over the Ethernet header, then reads IHL and addes (IHL * 4), the resulting
|
|
pointer will have a variable offset known to be 4n+2 for some n, so adding the 2
|
|
pointer will have a variable offset known to be 4n+2 for some n, so adding the 2
|
|
bytes (NET_IP_ALIGN) gives a 4-byte alignment and so word-sized accesses through
|
|
bytes (NET_IP_ALIGN) gives a 4-byte alignment and so word-sized accesses through
|
|
that pointer are safe.
|
|
that pointer are safe.
|
|
|
|
+The 'id' field is also used on PTR_TO_SOCKET and PTR_TO_SOCKET_OR_NULL, common
|
|
|
|
+to all copies of the pointer returned from a socket lookup. This has similar
|
|
|
|
+behaviour to the handling for PTR_TO_MAP_VALUE_OR_NULL->PTR_TO_MAP_VALUE, but
|
|
|
|
+it also handles reference tracking for the pointer. PTR_TO_SOCKET implicitly
|
|
|
|
+represents a reference to the corresponding 'struct sock'. To ensure that the
|
|
|
|
+reference is not leaked, it is imperative to NULL-check the reference and in
|
|
|
|
+the non-NULL case, and pass the valid reference to the socket release function.
|
|
|
|
|
|
Direct packet access
|
|
Direct packet access
|
|
--------------------
|
|
--------------------
|
|
@@ -1444,6 +1459,55 @@ Error:
|
|
8: (7a) *(u64 *)(r0 +0) = 1
|
|
8: (7a) *(u64 *)(r0 +0) = 1
|
|
R0 invalid mem access 'imm'
|
|
R0 invalid mem access 'imm'
|
|
|
|
|
|
|
|
+Program that performs a socket lookup then sets the pointer to NULL without
|
|
|
|
+checking it:
|
|
|
|
+value:
|
|
|
|
+ BPF_MOV64_IMM(BPF_REG_2, 0),
|
|
|
|
+ BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_2, -8),
|
|
|
|
+ BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
|
|
|
|
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
|
|
|
|
+ BPF_MOV64_IMM(BPF_REG_3, 4),
|
|
|
|
+ BPF_MOV64_IMM(BPF_REG_4, 0),
|
|
|
|
+ BPF_MOV64_IMM(BPF_REG_5, 0),
|
|
|
|
+ BPF_EMIT_CALL(BPF_FUNC_sk_lookup_tcp),
|
|
|
|
+ BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
|
|
+ BPF_EXIT_INSN(),
|
|
|
|
+Error:
|
|
|
|
+ 0: (b7) r2 = 0
|
|
|
|
+ 1: (63) *(u32 *)(r10 -8) = r2
|
|
|
|
+ 2: (bf) r2 = r10
|
|
|
|
+ 3: (07) r2 += -8
|
|
|
|
+ 4: (b7) r3 = 4
|
|
|
|
+ 5: (b7) r4 = 0
|
|
|
|
+ 6: (b7) r5 = 0
|
|
|
|
+ 7: (85) call bpf_sk_lookup_tcp#65
|
|
|
|
+ 8: (b7) r0 = 0
|
|
|
|
+ 9: (95) exit
|
|
|
|
+ Unreleased reference id=1, alloc_insn=7
|
|
|
|
+
|
|
|
|
+Program that performs a socket lookup but does not NULL-check the returned
|
|
|
|
+value:
|
|
|
|
+ BPF_MOV64_IMM(BPF_REG_2, 0),
|
|
|
|
+ BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_2, -8),
|
|
|
|
+ BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
|
|
|
|
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
|
|
|
|
+ BPF_MOV64_IMM(BPF_REG_3, 4),
|
|
|
|
+ BPF_MOV64_IMM(BPF_REG_4, 0),
|
|
|
|
+ BPF_MOV64_IMM(BPF_REG_5, 0),
|
|
|
|
+ BPF_EMIT_CALL(BPF_FUNC_sk_lookup_tcp),
|
|
|
|
+ BPF_EXIT_INSN(),
|
|
|
|
+Error:
|
|
|
|
+ 0: (b7) r2 = 0
|
|
|
|
+ 1: (63) *(u32 *)(r10 -8) = r2
|
|
|
|
+ 2: (bf) r2 = r10
|
|
|
|
+ 3: (07) r2 += -8
|
|
|
|
+ 4: (b7) r3 = 4
|
|
|
|
+ 5: (b7) r4 = 0
|
|
|
|
+ 6: (b7) r5 = 0
|
|
|
|
+ 7: (85) call bpf_sk_lookup_tcp#65
|
|
|
|
+ 8: (95) exit
|
|
|
|
+ Unreleased reference id=1, alloc_insn=7
|
|
|
|
+
|
|
Testing
|
|
Testing
|
|
-------
|
|
-------
|
|
|
|
|