From patchwork Thu Sep 27 23:26:59 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joe Stringer X-Patchwork-Id: 975967 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="gtZmA6HJ"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 42LrZ93pr8z9s1c for ; Fri, 28 Sep 2018 09:27:29 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728700AbeI1FsG (ORCPT ); Fri, 28 Sep 2018 01:48:06 -0400 Received: from mail-yw1-f66.google.com ([209.85.161.66]:32954 "EHLO mail-yw1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728672AbeI1FsG (ORCPT ); Fri, 28 Sep 2018 01:48:06 -0400 Received: by mail-yw1-f66.google.com with SMTP id r187-v6so1055568ywg.0 for ; Thu, 27 Sep 2018 16:27:20 -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=gtZmA6HJE8p7KO9LyJ88PQyY0OKrvGzR0lIF2XhOGyMYxBOED4BQC+cKd6e9doLYjn Ih8C/78i76qMqnKAwux/7kQ79VrrFmIJV6HS0L7fBGIq1KT4gsZFIM8DL5QxJ5YeYS1r SW5VfTaHEZSY+ZWaliP+UtlnhHVkUr2WghL8Ew+ZRzILxWCFZsfvqMDAS5SXliUQ0hPy MC8NSbi1S75g7290d+tY/KQwL3Az1Ag228G2JmjRqA4+JBESk1NqO5PmPqs5BmMKblYM 4/0cJBkbhgjyTYJh93mGTkC8jNA07KD8+zMZvo7LoNQqbo6OtTwynUYbTp7dE6k9P/MC XtwA== 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=BXfh/nSEowxwGqPEHC4OP1TJu8PRoXarT4NoG8JMFTYguPe8t4+awlsjX0XxgiRQZd jW4x6PiXmBIxR7KfnD1ivo+EEfM7X8phfnluKWHfyT1A11+6ofhU3uw+PeKC8DuA8WvR 6Fwf5RyF0z9HdQtCKsXFWp+qHcvz3l/6FISoywKnhY7HUGBh2Xws1hPY8VZNm3gxtaV2 f5aPHdbU+Yk1Vg+qhimoQZct229IAEuYplvwQEyGtvNuABrevFVLkHQAS3gUaDxPk/Qe HLyStjym+kDytJxQdyoQmpVg/r/YLqndE2FWnXFr6o3DWI56YyD1UxptrmSwXrLeVHsy WQMw== X-Gm-Message-State: ABuFfoinVWTm4+3SeMaA1Ku9YeVdTeEfbTQm68yyVsjt3+3TH2l4F9Dr KgQucFWurjqHuuHPvqq/xyj7Oipq X-Google-Smtp-Source: ACcGV60OMbRy+IdzWvNA/ZB2BfLoGW6EYonBX5JVQ+hRFAIjtAFA2qlMRA1PSd+ZSJZ8sAOIsmTNuQ== X-Received: by 2002:a0d:d045:: with SMTP id s66-v6mr4679061ywd.113.1538090840052; Thu, 27 Sep 2018 16:27:20 -0700 (PDT) Received: from localhost.localdomain ([99.0.85.34]) by smtp.gmail.com with ESMTPSA id w6-v6sm4810717ywg.3.2018.09.27.16.27.18 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 27 Sep 2018 16:27:19 -0700 (PDT) From: Joe Stringer To: daniel@iogearbox.net Cc: netdev@vger.kernel.org, ast@kernel.org, john.fastabend@gmail.com, tgraf@suug.ch, kafai@fb.com, nitin.hande@gmail.com, mauricio.vasquez@polito.it Subject: [PATCHv3 bpf-next 12/12] Documentation: Describe bpf reference tracking Date: Thu, 27 Sep 2018 16:26:59 -0700 Message-Id: <20180927232659.14348-13-joe@wand.net.nz> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180927232659.14348-1-joe@wand.net.nz> References: <20180927232659.14348-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 -------