From patchwork Fri Sep 21 17:10:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joe Stringer X-Patchwork-Id: 973335 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=wand.net.nz Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="dDalJn4U"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 42H0Vj1mC5z9sBn for ; Sat, 22 Sep 2018 03:11:09 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2390937AbeIUXAz (ORCPT ); Fri, 21 Sep 2018 19:00:55 -0400 Received: from mail-yb1-f193.google.com ([209.85.219.193]:34976 "EHLO mail-yb1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390925AbeIUXAw (ORCPT ); Fri, 21 Sep 2018 19:00:52 -0400 Received: by mail-yb1-f193.google.com with SMTP id o63-v6so5726490yba.2 for ; Fri, 21 Sep 2018 10:11:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=IR/+GosL/jA+s56tyuOnjR4AxDbcwJGGA0zzm16Un+I=; b=dDalJn4UNRp8pHXB5UYET4p8j8bwNNMKzptB47cJbDEw1uwGhk+8QpXglQJchcIqcd dAti6XKfYRFyvDuwHl4Ow9K6puReP/xRpFdD92cdFAwyYDRcnb0BBNixiFYZy02Y1+Ph hG+2fQ/PlPwkk+LHabG0wlgJjimf6alNSMNfsBiYUck9LKS1gPB62LH+Vmdz7XR4XeR0 z1FYHf7Unc51tJGLTZnVJOBkwsypJeEMCxNMTboe+jr4T2LdeoevyZHEjOX06N1Fhf60 uLVKbyOERImt4tcn0/fLFon5S8BTvq9NYnSTNCDXWInAmCDSQXZbgWIeS5GNz8fT61Gb l1Cg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=IR/+GosL/jA+s56tyuOnjR4AxDbcwJGGA0zzm16Un+I=; b=EKfq8HBKaUu+LR3kw4carfpWrLzbw/2H2nmEV6rHk6PRSo3YChj3eEW2kHJNv1Js29 +/axpvrtRG1GN5OCcksdgDTt3T4YwU1L/RQzKwKmlG5ErHCshEf20KixjaG+owCtZ3Py 5waTzTtxzJpkGAzSjDNGH1b6RamTw59bfABwRe93ntD8YpUzkW52+ynrTljMr4F5p9A8 UaxjL7EOMKrfB1fKQcDN7AbyvxH9o4i1rGASPREosY9TEWH9ORcOKLVl7A07evzOgIZd GMfizKzfxJYIFclfN09O/Y6cIoMlJK8IKBHfTsToZ1xoUpBnYAhR78kt5QOWYtdgoj7B H3/Q== X-Gm-Message-State: APzg51DPfhc+aeLsG0kd1w67LHT6C0XUXuoMlhPSxE6vvhF5GsNZiKz4 8FQuz2N2eZhRuwyCSr7SssI= X-Google-Smtp-Source: ANB0VdZAiYaI3vd7WwL1oh6oGSa+956S2emDWsNdSlQVaXXq+p5gD4IvA6OAUutgg3KQxKrSnF/FMA== X-Received: by 2002:a25:4155:: with SMTP id o82-v6mr18107839yba.310.1537549864271; Fri, 21 Sep 2018 10:11:04 -0700 (PDT) Received: from localhost.localdomain ([99.0.85.34]) by smtp.gmail.com with ESMTPSA id h10-v6sm9930972ywa.35.2018.09.21.10.11.03 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 21 Sep 2018 10:11:03 -0700 (PDT) From: Joe Stringer To: ast@kernel.org Cc: netdev@vger.kernel.org, daniel@iogearbox.net, john.fastabend@gmail.com, tgraf@suug.ch, kafai@fb.com, nitin.hande@gmail.com, mauricio.vasquez@polito.it Subject: [PATCHv2 bpf-next 11/11] Documentation: Describe bpf reference tracking Date: Fri, 21 Sep 2018 10:10:43 -0700 Message-Id: <20180921171043.20823-12-joe@wand.net.nz> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180921171043.20823-1-joe@wand.net.nz> References: <20180921171043.20823-1-joe@wand.net.nz> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Document the new pointer types in the verifier and how the pointer ID tracking works to ensure that references which are taken are later released. Signed-off-by: Joe Stringer Acked-by: Alexei Starovoitov --- Documentation/networking/filter.txt | 64 +++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/Documentation/networking/filter.txt b/Documentation/networking/filter.txt index e6b4ebb2b243..4443ce958862 100644 --- a/Documentation/networking/filter.txt +++ b/Documentation/networking/filter.txt @@ -1125,6 +1125,14 @@ pointer type. The types of pointers describe their base, as follows: PTR_TO_STACK Frame pointer. PTR_TO_PACKET skb->data. 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 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 @@ -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 bytes (NET_IP_ALIGN) gives a 4-byte alignment and so word-sized accesses through 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 -------------------- @@ -1444,6 +1459,55 @@ Error: 8: (7a) *(u64 *)(r0 +0) = 1 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 -------