From patchwork Tue Feb 27 12:13:46 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sandipan Das X-Patchwork-Id: 878489 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@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=linux.vnet.ibm.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zrHfy6gDQz9s1j for ; Tue, 27 Feb 2018 23:14:02 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752300AbeB0MN7 (ORCPT ); Tue, 27 Feb 2018 07:13:59 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:34058 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752012AbeB0MN6 (ORCPT ); Tue, 27 Feb 2018 07:13:58 -0500 Received: from pps.filterd (m0098394.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w1RC9XQJ051719 for ; Tue, 27 Feb 2018 07:13:57 -0500 Received: from e06smtp13.uk.ibm.com (e06smtp13.uk.ibm.com [195.75.94.109]) by mx0a-001b2d01.pphosted.com with ESMTP id 2gd5t4kgry-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Tue, 27 Feb 2018 07:13:57 -0500 Received: from localhost by e06smtp13.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 27 Feb 2018 12:13:51 -0000 Received: from b06cxnps3074.portsmouth.uk.ibm.com (9.149.109.194) by e06smtp13.uk.ibm.com (192.168.101.143) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Tue, 27 Feb 2018 12:13:49 -0000 Received: from d06av21.portsmouth.uk.ibm.com (d06av21.portsmouth.uk.ibm.com [9.149.105.232]) by b06cxnps3074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w1RCDmfI60424240; Tue, 27 Feb 2018 12:13:48 GMT Received: from d06av21.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 7755152045; Tue, 27 Feb 2018 11:05:35 +0000 (GMT) Received: from localhost.localdomain (unknown [9.40.193.84]) by d06av21.portsmouth.uk.ibm.com (Postfix) with ESMTP id 574215203F; Tue, 27 Feb 2018 11:05:34 +0000 (GMT) From: Sandipan Das To: daniel@iogearbox.net, naveen.n.rao@linux.vnet.ibm.com Cc: ast@fb.com, mpe@ellerman.id.au, jakub.kicinski@netronome.com, netdev@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Subject: [RFC][PATCH bpf] tools: bpftool: Fix tags for bpf-to-bpf calls Date: Tue, 27 Feb 2018 17:43:46 +0530 X-Mailer: git-send-email 2.14.3 In-Reply-To: <1519153431.im5wioxel1.naveen@linux.ibm.com> References: <1519153431.im5wioxel1.naveen@linux.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 18022712-0012-0000-0000-000005B5F6C7 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18022712-0013-0000-0000-000019320145 Message-Id: <20180227121346.16199-1-sandipan@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2018-02-27_05:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1011 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1709140000 definitions=main-1802270152 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org "Naveen N. Rao" wrote: > I'm wondering if we can instead encode the bpf prog id in > imm32. That way, we should be able to indicate the BPF > function being called into. Daniel, is that something we > can consider? Since each subprog does not get a separate id, we cannot fetch the fd and therefore the tag of a subprog. Instead we can use the tag of the complete program as shown below. "Daniel Borkmann" wrote: > I think one limitation that would still need to be addressed later > with such approach would be regarding the xlated prog dump in bpftool, > see 'BPF calls via JIT' in 7105e828c087 ("bpf: allow for correlation > of maps and helpers in dump"). Any ideas for this (potentially if we > could use off + imm for calls, we'd get to 48 bits, but that seems > still not be enough as you say)? As an alternative, this is what I am thinking of: Currently, for bpf-to-bpf calls, if bpf_jit_kallsyms is enabled, bpftool looks up the name of the corresponding symbol for the JIT-ed subprogram and shows it in the xlated dump alongside the actual call instruction. However, the lookup is based on the target address which is calculated using the imm field of the instruction. So, once again, if imm is truncated, we will end up with the wrong address. Also, the subprog aux data (which has been proposed as a mitigation for this) is not accessible from this tool. We can still access the tag for the complete bpf program and use this with the correct offset in an objdump-like notation as an alterative for the name of the subprog that is the target of a bpf-to-bpf call instruction. Currently, an xlated dump looks like this: 0: (85) call pc+2#bpf_prog_5f76847930402518_F 1: (b7) r0 = 1 2: (95) exit 3: (b7) r0 = 2 4: (95) exit With this patch, it will look like this: 0: (85) call pc+2#bpf_prog_8f85936f29a7790a+3 1: (b7) r0 = 1 2: (95) exit 3: (b7) r0 = 2 4: (95) exit where 8f85936f29a7790a is the tag of the bpf program and 3 is the offset to the start of the subprog from the start of the program. Signed-off-by: Sandipan Das --- tools/bpf/bpftool/prog.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c index e8e2baaf93c2..93746d5d1e3c 100644 --- a/tools/bpf/bpftool/prog.c +++ b/tools/bpf/bpftool/prog.c @@ -415,9 +415,11 @@ struct kernel_sym { }; struct dump_data { + unsigned char prog_tag[BPF_TAG_SIZE]; unsigned long address_call_base; struct kernel_sym *sym_mapping; __u32 sym_count; + unsigned int curr_line; char scratch_buff[SYM_MAX_NAME]; }; @@ -499,16 +501,16 @@ static void print_insn(struct bpf_verifier_env *env, const char *fmt, ...) } static const char *print_call_pcrel(struct dump_data *dd, - struct kernel_sym *sym, - unsigned long address, const struct bpf_insn *insn) { - if (sym) - snprintf(dd->scratch_buff, sizeof(dd->scratch_buff), - "%+d#%s", insn->off, sym->name); - else - snprintf(dd->scratch_buff, sizeof(dd->scratch_buff), - "%+d#0x%lx", insn->off, address); + snprintf(dd->scratch_buff, sizeof(dd->scratch_buff), + "+%d#bpf_prog_%02x%02x%02x%02x%02x%02x%02x%02x+%d", + insn->off, + dd->prog_tag[0], dd->prog_tag[1], + dd->prog_tag[2], dd->prog_tag[3], + dd->prog_tag[4], dd->prog_tag[5], + dd->prog_tag[6], dd->prog_tag[7], + dd->curr_line + insn->off + 1); return dd->scratch_buff; } @@ -534,7 +536,7 @@ static const char *print_call(void *private_data, sym = kernel_syms_search(dd, address); if (insn->src_reg == BPF_PSEUDO_CALL) - return print_call_pcrel(dd, sym, address, insn); + return print_call_pcrel(dd, insn); else return print_call_helper(dd, sym, address); } @@ -576,6 +578,7 @@ static void dump_xlated_plain(struct dump_data *dd, void *buf, double_insn = insn[i].code == (BPF_LD | BPF_IMM | BPF_DW); printf("% 4d: ", i); + dd->curr_line = i; print_bpf_insn(&cbs, NULL, insn + i, true); if (opcodes) { @@ -628,6 +631,7 @@ static void dump_xlated_json(struct dump_data *dd, void *buf, jsonw_start_object(json_wtr); jsonw_name(json_wtr, "disasm"); + dd->curr_line = i; print_bpf_insn(&cbs, NULL, insn + i, true); if (opcodes) { @@ -788,6 +792,7 @@ static int do_dump(int argc, char **argv) disasm_print_insn(buf, *member_len, opcodes, name); } else { + memcpy(dd.prog_tag, info.tag, sizeof(info.tag)); kernel_syms_load(&dd); if (json_output) dump_xlated_json(&dd, buf, *member_len, opcodes);