From patchwork Tue Oct 2 20:35:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joe Stringer X-Patchwork-Id: 978025 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="PkEq5MPD"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 42PrX70Yv9z9s3C for ; Wed, 3 Oct 2018 06:36:07 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727879AbeJCDVO (ORCPT ); Tue, 2 Oct 2018 23:21:14 -0400 Received: from mail-yb1-f193.google.com ([209.85.219.193]:39464 "EHLO mail-yb1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727837AbeJCDVN (ORCPT ); Tue, 2 Oct 2018 23:21:13 -0400 Received: by mail-yb1-f193.google.com with SMTP id c4-v6so1397031ybl.6 for ; Tue, 02 Oct 2018 13:36: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=PkEq5MPDa/sw5n2gsYz7yWZvE82B4SDy/0IX7I8WYezb9nY1urVJnxneyfrqhQE0nE KpN4yCZM3x5pzcVqwig8nyM2ADGxcrBwApEEgE6UieGpPLAbZuSvYvecZdyowsQV8M/T cyyZQic0zVnb4f3a42R6Zf11H87tlAFHGODe+FANso7hEe7LKgCnQGpLuXZrMHK9n95o 1L27cb9zqt/DnZrxeH3cavU3bbUVVgSmr0/ZRdNnQ43H39ZMkReO2CCxRl706fqpkPMx wEu6R7mt/T1Nqo+8LV5MHmrr1Zu+RwS8EBdIUnQAKMdAKMhpyaXZNF2S5Kffm3dUr/HA YRfw== 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=YC+boxKvQHqWpURyfOww/bdNCD/55pL2a+MvREMQDoziG0a6UatlcL0h/5HBjBpw/6 IjuaOXGQlN2UQzr0DEBcXfdKrhQdiy5LrMa7fTVuBATqRl9joedhiL8hp0TNdIJHTjwX nlGqvdL0/6O02TyVgMMyCSmc3nVDv3qYh9pqZC4X0x+W2nHmryOTjuVTMhzvz0xzQ9B2 GhCNcWwhtTwNCeDROqtutd2WpbCOSPvSDx1W3uth6RYA/FkI4fmC5u4HODflnMF+GxNN H44lxk/zQrp7Y5jlt4iAkU52C8dhuFSOCqumQHPQ2TE6Hb0CU0hWL+REWA/VsHtp6D67 k/0w== X-Gm-Message-State: ABuFfohTAQk0nq3+IB1CmFf88b1Ad91LeQlYgCZT3aVU7bkA0Mz4VaEX kogSIY9SHI7H8msAfpJojd0xVsD4 X-Google-Smtp-Source: ACcGV62JoA9opeJi4MVab8rREjp4YVGo37O1EMAWF9/zM1Vy4b741TpK2j5VycgAjsQ13CuIpESItA== X-Received: by 2002:a25:db02:: with SMTP id g2-v6mr9354247ybf.493.1538512563474; Tue, 02 Oct 2018 13:36:03 -0700 (PDT) Received: from localhost.localdomain ([99.0.85.34]) by smtp.gmail.com with ESMTPSA id o131-v6sm4555361ywb.107.2018.10.02.13.36.02 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 02 Oct 2018 13:36:02 -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: [PATCHv4 bpf-next 13/13] Documentation: Describe bpf reference tracking Date: Tue, 2 Oct 2018 13:35:41 -0700 Message-Id: <20181002203541.26599-14-joe@wand.net.nz> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181002203541.26599-1-joe@wand.net.nz> References: <20181002203541.26599-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 -------