From patchwork Mon Jul 13 20:12:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= X-Patchwork-Id: 1328442 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=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=J1kb8M0l; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4B5FDt2jbcz9sQt for ; Tue, 14 Jul 2020 06:12:30 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726850AbgGMUM3 (ORCPT ); Mon, 13 Jul 2020 16:12:29 -0400 Received: from us-smtp-delivery-1.mimecast.com ([205.139.110.120]:45750 "EHLO us-smtp-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726798AbgGMUM2 (ORCPT ); Mon, 13 Jul 2020 16:12:28 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1594671146; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=8KBbdYNp281Pv1eNg+rkX8LCwwujbUA7nANkDYj0cio=; b=J1kb8M0lXgRqwiAVgCgawymJfAGZ3dtT9qeYMzgnnj8UKLEhfhf3Rt0fPvd0/PtOmFoEWw DdDOazXJ01tGmwOLBXhspAsdr3AKivzDdeWXD7NftZo0sfWFkv3w2lJlWHlpChjS4VbzsX gyH7a/46LvLP8Cb7O+pmCGLUmlYxVX8= Received: from mail-qv1-f71.google.com (mail-qv1-f71.google.com [209.85.219.71]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-466-Yz4W85LBPvqi4XOzStTm8A-1; Mon, 13 Jul 2020 16:12:24 -0400 X-MC-Unique: Yz4W85LBPvqi4XOzStTm8A-1 Received: by mail-qv1-f71.google.com with SMTP id u1so8104473qvu.18 for ; Mon, 13 Jul 2020 13:12:24 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:from:to:cc:date:message-id:in-reply-to :references:user-agent:mime-version:content-transfer-encoding; bh=8KBbdYNp281Pv1eNg+rkX8LCwwujbUA7nANkDYj0cio=; b=UIBQy+Zda44tk1x0MaDraGruBltkmJ7/t5R2T76ux/P0t9G6JfOzUYIsIn3M2qBeW/ 0eRNu7ZVqco808TAGz5zOAEIRVpHl06OxUkeONhXKjjieVXSnhF99nbt3L2oUYcw1Y7F mnnbIBzxOCF3nXMMzGlfggfx4eR/ZbrB2CSvlmwFQ3a3FErlHWTOJpB+XSbYqs5dg20K QocQfVnOpWwKdE7O0ckTynYpwWfDm30TbrfbNZ6Gozdx0TldR69zut2TSHsJeNrKS5RD qKY0CAaipFk8HUkcaH9ppDcW0j3+AR/qSi1sZDX+zRgr264sGUKN7Mk29K2LPH9B7VfV fbag== X-Gm-Message-State: AOAM532wRmZoAUFmUZuZv6qFpOgfZ6w/bKTGa3jXYf74uFRtGjyRwO0p SVoVh+uWnzrR/msQ2x4Ht16kmZ0n9reTVEBhs4MN/byiRz0YH+SiFUB+TlPDmF4gvRKkCnuKxtU 5CQ43RQRajqCnhbNU X-Received: by 2002:ac8:7ca7:: with SMTP id z7mr1132090qtv.275.1594671143798; Mon, 13 Jul 2020 13:12:23 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxaC871YtcsQ+MDCi4ySMgv15ZONkoGIkZxg+/wsxNCVlPNBtIQOMgcNgQYeo4G0mr4RJE5KQ== X-Received: by 2002:ac8:7ca7:: with SMTP id z7mr1132059qtv.275.1594671143439; Mon, 13 Jul 2020 13:12:23 -0700 (PDT) Received: from alrua-x1.borgediget.toke.dk ([45.145.92.2]) by smtp.gmail.com with ESMTPSA id p7sm19936932qki.61.2020.07.13.13.12.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 13 Jul 2020 13:12:22 -0700 (PDT) Received: by alrua-x1.borgediget.toke.dk (Postfix, from userid 1000) id DE393180653; Mon, 13 Jul 2020 22:12:20 +0200 (CEST) Subject: [PATCH bpf-next 1/6] bpf: change logging calls from verbose() to bpf_log() and use log pointer From: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= To: Alexei Starovoitov Cc: Daniel Borkmann , Martin KaFai Lau , Song Liu , Yonghong Song , Andrii Nakryiko , John Fastabend , KP Singh , netdev@vger.kernel.org, bpf@vger.kernel.org Date: Mon, 13 Jul 2020 22:12:20 +0200 Message-ID: <159467114081.370286.2622654090393388366.stgit@toke.dk> In-Reply-To: <159467113970.370286.17656404860101110795.stgit@toke.dk> References: <159467113970.370286.17656404860101110795.stgit@toke.dk> User-Agent: StGit/0.23 MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Toke Høiland-Jørgensen In preparation for moving code around, change a bunch of references to env->log (and the verbose() logging helper) to use bpf_log() and a direct pointer to struct bpf_verifier_log. While we're touching the function signature, mark the 'prog' argument to bpf_check_type_match() as const. Signed-off-by: Toke Høiland-Jørgensen --- include/linux/bpf.h | 2 +- kernel/bpf/btf.c | 6 +++--- kernel/bpf/verifier.c | 46 +++++++++++++++++++++++----------------------- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 0cd7f6884c5c..c547065387e4 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -1314,7 +1314,7 @@ int btf_check_func_arg_match(struct bpf_verifier_env *env, int subprog, struct bpf_reg_state *regs); int btf_prepare_func_args(struct bpf_verifier_env *env, int subprog, struct bpf_reg_state *reg); -int btf_check_type_match(struct bpf_verifier_env *env, struct bpf_prog *prog, +int btf_check_type_match(struct bpf_verifier_log *log, const struct bpf_prog *prog, struct btf *btf, const struct btf_type *t); struct bpf_prog *bpf_prog_by_id(u32 id); diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index 4c3007f428b1..ed60fa54378d 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -4366,7 +4366,7 @@ static int btf_check_func_type_match(struct bpf_verifier_log *log, } /* Compare BTFs of given program with BTF of target program */ -int btf_check_type_match(struct bpf_verifier_env *env, struct bpf_prog *prog, +int btf_check_type_match(struct bpf_verifier_log *log, const struct bpf_prog *prog, struct btf *btf2, const struct btf_type *t2) { struct btf *btf1 = prog->aux->btf; @@ -4374,7 +4374,7 @@ int btf_check_type_match(struct bpf_verifier_env *env, struct bpf_prog *prog, u32 btf_id = 0; if (!prog->aux->func_info) { - bpf_log(&env->log, "Program extension requires BTF\n"); + bpf_log(log, "Program extension requires BTF\n"); return -EINVAL; } @@ -4386,7 +4386,7 @@ int btf_check_type_match(struct bpf_verifier_env *env, struct bpf_prog *prog, if (!t1 || !btf_type_is_func(t1)) return -EFAULT; - return btf_check_func_type_match(&env->log, btf1, t1, btf2, t2); + return btf_check_func_type_match(log, btf1, t1, btf2, t2); } /* Compare BTF of a function with given bpf_reg_state. diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index b608185e1ffd..0db338567cf9 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -10729,6 +10729,7 @@ static int check_attach_btf_id(struct bpf_verifier_env *env) struct bpf_prog *prog = env->prog; bool prog_extension = prog->type == BPF_PROG_TYPE_EXT; struct bpf_prog *tgt_prog = prog->aux->linked_prog; + struct bpf_verifier_log *log = &env->log; u32 btf_id = prog->aux->attach_btf_id; const char prefix[] = "btf_trace_"; struct btf_func_model fmodel; @@ -10750,23 +10751,23 @@ static int check_attach_btf_id(struct bpf_verifier_env *env) return 0; if (!btf_id) { - verbose(env, "Tracing programs must provide btf_id\n"); + bpf_log(log, "Tracing programs must provide btf_id\n"); return -EINVAL; } btf = bpf_prog_get_target_btf(prog); if (!btf) { - verbose(env, + bpf_log(log, "FENTRY/FEXIT program can only be attached to another program annotated with BTF\n"); return -EINVAL; } t = btf_type_by_id(btf, btf_id); if (!t) { - verbose(env, "attach_btf_id %u is invalid\n", btf_id); + bpf_log(log, "attach_btf_id %u is invalid\n", btf_id); return -EINVAL; } tname = btf_name_by_offset(btf, t->name_off); if (!tname) { - verbose(env, "attach_btf_id %u doesn't have a name\n", btf_id); + bpf_log(log, "attach_btf_id %u doesn't have a name\n", btf_id); return -EINVAL; } if (tgt_prog) { @@ -10778,18 +10779,18 @@ static int check_attach_btf_id(struct bpf_verifier_env *env) break; } if (subprog == -1) { - verbose(env, "Subprog %s doesn't exist\n", tname); + bpf_log(log, "Subprog %s doesn't exist\n", tname); return -EINVAL; } conservative = aux->func_info_aux[subprog].unreliable; if (prog_extension) { if (conservative) { - verbose(env, + bpf_log(log, "Cannot replace static functions\n"); return -EINVAL; } if (!prog->jit_requested) { - verbose(env, + bpf_log(log, "Extension programs should be JITed\n"); return -EINVAL; } @@ -10797,7 +10798,7 @@ static int check_attach_btf_id(struct bpf_verifier_env *env) prog->expected_attach_type = tgt_prog->expected_attach_type; } if (!tgt_prog->jited) { - verbose(env, "Can attach to only JITed progs\n"); + bpf_log(log, "Can attach to only JITed progs\n"); return -EINVAL; } if (tgt_prog->type == prog->type) { @@ -10805,7 +10806,7 @@ static int check_attach_btf_id(struct bpf_verifier_env *env) * Cannot attach program extension to another extension. * It's ok to attach fentry/fexit to extension program. */ - verbose(env, "Cannot recursively attach\n"); + bpf_log(log, "Cannot recursively attach\n"); return -EINVAL; } if (tgt_prog->type == BPF_PROG_TYPE_TRACING && @@ -10827,13 +10828,13 @@ static int check_attach_btf_id(struct bpf_verifier_env *env) * reasonable stack size. Hence extending fentry is not * allowed. */ - verbose(env, "Cannot extend fentry/fexit\n"); + bpf_log(log, "Cannot extend fentry/fexit\n"); return -EINVAL; } key = ((u64)aux->id) << 32 | btf_id; } else { if (prog_extension) { - verbose(env, "Cannot replace kernel functions\n"); + bpf_log(log, "Cannot replace kernel functions\n"); return -EINVAL; } key = btf_id; @@ -10842,17 +10843,17 @@ static int check_attach_btf_id(struct bpf_verifier_env *env) switch (prog->expected_attach_type) { case BPF_TRACE_RAW_TP: if (tgt_prog) { - verbose(env, + bpf_log(log, "Only FENTRY/FEXIT progs are attachable to another BPF prog\n"); return -EINVAL; } if (!btf_type_is_typedef(t)) { - verbose(env, "attach_btf_id %u is not a typedef\n", + bpf_log(log, "attach_btf_id %u is not a typedef\n", btf_id); return -EINVAL; } if (strncmp(prefix, tname, sizeof(prefix) - 1)) { - verbose(env, "attach_btf_id %u points to wrong type name %s\n", + bpf_log(log, "attach_btf_id %u points to wrong type name %s\n", btf_id, tname); return -EINVAL; } @@ -10875,7 +10876,7 @@ static int check_attach_btf_id(struct bpf_verifier_env *env) return 0; case BPF_TRACE_ITER: if (!btf_type_is_func(t)) { - verbose(env, "attach_btf_id %u is not a function\n", + bpf_log(log, "attach_btf_id %u is not a function\n", btf_id); return -EINVAL; } @@ -10886,8 +10887,7 @@ static int check_attach_btf_id(struct bpf_verifier_env *env) prog->aux->attach_func_proto = t; if (!bpf_iter_prog_supported(prog)) return -EINVAL; - ret = btf_distill_func_proto(&env->log, btf, t, - tname, &fmodel); + ret = btf_distill_func_proto(log, btf, t, tname, &fmodel); return ret; default: if (!prog_extension) @@ -10899,18 +10899,18 @@ static int check_attach_btf_id(struct bpf_verifier_env *env) case BPF_TRACE_FEXIT: prog->aux->attach_func_name = tname; if (prog->type == BPF_PROG_TYPE_LSM) { - ret = bpf_lsm_verify_prog(&env->log, prog); + ret = bpf_lsm_verify_prog(log, prog); if (ret < 0) return ret; } if (!btf_type_is_func(t)) { - verbose(env, "attach_btf_id %u is not a function\n", + bpf_log(log, "attach_btf_id %u is not a function\n", btf_id); return -EINVAL; } if (prog_extension && - btf_check_type_match(env, prog, btf, t)) + btf_check_type_match(log, prog, btf, t)) return -EINVAL; t = btf_type_by_id(btf, t->type); if (!btf_type_is_func_proto(t)) @@ -10929,7 +10929,7 @@ static int check_attach_btf_id(struct bpf_verifier_env *env) prog->aux->attach_func_proto = NULL; t = NULL; } - ret = btf_distill_func_proto(&env->log, btf, t, + ret = btf_distill_func_proto(log, btf, t, tname, &tr->func.model); if (ret < 0) goto out; @@ -10941,7 +10941,7 @@ static int check_attach_btf_id(struct bpf_verifier_env *env) } else { addr = kallsyms_lookup_name(tname); if (!addr) { - verbose(env, + bpf_log(log, "The address of function %s cannot be found\n", tname); ret = -ENOENT; @@ -10952,7 +10952,7 @@ static int check_attach_btf_id(struct bpf_verifier_env *env) if (prog->expected_attach_type == BPF_MODIFY_RETURN) { ret = check_attach_modify_return(prog, addr); if (ret) - verbose(env, "%s() is not modifiable\n", + bpf_log(log, "%s() is not modifiable\n", prog->aux->attach_func_name); } From patchwork Mon Jul 13 20:12:21 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= X-Patchwork-Id: 1328445 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=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=BiKkAoH5; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4B5FDx6gSdz9sRR for ; Tue, 14 Jul 2020 06:12:33 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726929AbgGMUMd (ORCPT ); Mon, 13 Jul 2020 16:12:33 -0400 Received: from us-smtp-2.mimecast.com ([207.211.31.81]:31883 "EHLO us-smtp-delivery-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726830AbgGMUMa (ORCPT ); Mon, 13 Jul 2020 16:12:30 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1594671148; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=MasVFjyf+3i++tabfefew/QxMQNTXbpb8QnnRXeUgHo=; b=BiKkAoH5kHkuzRYNd1pDeEAe8cNMP1zZ0eHxISjhs1jAxZX0Mggv/ct+V3In4hQ7hdHkDs 6jzP08E+O/Wj601swRZltS7GaRBR4FEF1phOfRpiyn1mBW2S6Ja3Ee4elD7QIsQ2Mlfpwx Q5a7q10V8DAUOul6offfqWNVargV+sY= Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-289-1lhtjc7ONNegp5_XdwEgjw-1; Mon, 13 Jul 2020 16:12:25 -0400 X-MC-Unique: 1lhtjc7ONNegp5_XdwEgjw-1 Received: by mail-wr1-f70.google.com with SMTP id d11so18677519wrw.12 for ; Mon, 13 Jul 2020 13:12:25 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:from:to:cc:date:message-id:in-reply-to :references:user-agent:mime-version:content-transfer-encoding; bh=MasVFjyf+3i++tabfefew/QxMQNTXbpb8QnnRXeUgHo=; b=oCMJuLPGzqC0SaWBVzx5MssKerZUu0xRtnt+2M7FnIX9pefGHq48xmYupdAhfxcAex m4bUZIEsFEVmwt95zJW5sAFPSSjGorByUc/6slEGF7nGdXS1GRev+QQ6LkhHbtKiOo95 TCc9g3aQc9S424OJMcPPpIx8JOoPrxyENZcFVmWXseefxbi6aHBZ/4EaqdRVfbVuZ78K Q5hQU6tdrvixMce//ZlK67hdR934E9gxrtdSJInAKj7sBQYfbI4GtNO1OHD1JzR7bHsY /zuSZk3d4dV+t23xnDs10Jyipc/ZpOekAOvsCOHeF+7qPr1ka3md8+iT5ONKQFIriIJH AoOA== X-Gm-Message-State: AOAM5303eb2Yp35HIuYu+QKVjnzaNPbxaUlBcRFXX2IGPja4iJLUnSkb q2t2DeJKiXfyyWw6JC3K03r1Dsz1FZm+LWhm8vhG8XqOKRkja8vUs4d1PSy5ddfPLeuHvWJJmUc rl28+PGyoVxdbruqU X-Received: by 2002:adf:e68d:: with SMTP id r13mr1145667wrm.141.1594671143304; Mon, 13 Jul 2020 13:12:23 -0700 (PDT) X-Google-Smtp-Source: ABdhPJynHsF4eWH0HdBHdA2iw+WN4fRZIug1K5PB5wKUb4QlF7HFhiR00A9gMibXr2DQFaYSO1f4nw== X-Received: by 2002:adf:e68d:: with SMTP id r13mr1145651wrm.141.1594671142919; Mon, 13 Jul 2020 13:12:22 -0700 (PDT) Received: from alrua-x1.borgediget.toke.dk ([2a0c:4d80:42:443::2]) by smtp.gmail.com with ESMTPSA id t15sm933781wmj.14.2020.07.13.13.12.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 13 Jul 2020 13:12:22 -0700 (PDT) Received: by alrua-x1.borgediget.toke.dk (Postfix, from userid 1000) id ED2671804F0; Mon, 13 Jul 2020 22:12:21 +0200 (CEST) Subject: [PATCH bpf-next 2/6] bpf: verifier: refactor check_attach_btf_id() From: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= To: Alexei Starovoitov Cc: Daniel Borkmann , Martin KaFai Lau , Song Liu , Yonghong Song , Andrii Nakryiko , John Fastabend , KP Singh , netdev@vger.kernel.org, bpf@vger.kernel.org Date: Mon, 13 Jul 2020 22:12:21 +0200 Message-ID: <159467114191.370286.3577295271355257627.stgit@toke.dk> In-Reply-To: <159467113970.370286.17656404860101110795.stgit@toke.dk> References: <159467113970.370286.17656404860101110795.stgit@toke.dk> User-Agent: StGit/0.23 MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Toke Høiland-Jørgensen The check_attach_btf_id() function really does three things: 1. It performs a bunch of checks on the program to ensure that the attachment is valid. 2. It stores a bunch of state about the attachment being requested in the verifier environment and struct bpf_prog objects. 3. It allocates a trampoline for the attachment. This patch splits out (1.) and (3.) into separate functions in preparation for reusing them when the actual attachment is happening (in the raw_tracepoint_open syscall operation), which will allow tracing programs to have multiple (compatible) attachments. No functional change is intended with this patch. Signed-off-by: Toke Høiland-Jørgensen Reported-by: kernel test robot --- include/linux/bpf.h | 9 ++ include/linux/bpf_verifier.h | 9 ++ kernel/bpf/trampoline.c | 22 ++++++ kernel/bpf/verifier.c | 165 ++++++++++++++++++++++++------------------ 4 files changed, 133 insertions(+), 72 deletions(-) diff --git a/include/linux/bpf.h b/include/linux/bpf.h index c547065387e4..67310595f720 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -570,6 +570,9 @@ static __always_inline unsigned int bpf_dispatcher_nop_func( struct bpf_trampoline *bpf_trampoline_lookup(u64 key); int bpf_trampoline_link_prog(struct bpf_prog *prog); int bpf_trampoline_unlink_prog(struct bpf_prog *prog); +int bpf_trampoline_get(u64 key, void *addr, + struct btf_func_model *fmodel, + struct bpf_trampoline **trampoline); void bpf_trampoline_put(struct bpf_trampoline *tr); #define BPF_DISPATCHER_INIT(_name) { \ .mutex = __MUTEX_INITIALIZER(_name.mutex), \ @@ -626,6 +629,12 @@ static inline int bpf_trampoline_unlink_prog(struct bpf_prog *prog) { return -ENOTSUPP; } +static inline int bpf_trampoline_get(u64 key, void *addr, + struct btf_func_model *fmodel, + struct bpf_trampoline **trampoline) +{ + return -EOPNOTSUPP; +} static inline void bpf_trampoline_put(struct bpf_trampoline *tr) {} #define DEFINE_BPF_DISPATCHER(name) #define DECLARE_BPF_DISPATCHER(name) diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h index 53c7bd568c5d..b882185257cc 100644 --- a/include/linux/bpf_verifier.h +++ b/include/linux/bpf_verifier.h @@ -446,4 +446,13 @@ bpf_prog_offload_remove_insns(struct bpf_verifier_env *env, u32 off, u32 cnt); int check_ctx_reg(struct bpf_verifier_env *env, const struct bpf_reg_state *reg, int regno); +int bpf_check_attach_target(struct bpf_verifier_log *log, + const struct bpf_prog *prog, + const struct bpf_prog *tgt_prog, + u32 btf_id, + struct btf_func_model *fmodel, + long *tgt_addr, + const char **tgt_name, + const struct btf_type **tgt_type); + #endif /* _LINUX_BPF_VERIFIER_H */ diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c index 9be85aa4ec5f..fadfa330f728 100644 --- a/kernel/bpf/trampoline.c +++ b/kernel/bpf/trampoline.c @@ -331,6 +331,28 @@ int bpf_trampoline_unlink_prog(struct bpf_prog *prog) return err; } +int bpf_trampoline_get(u64 key, void *addr, + struct btf_func_model *fmodel, + struct bpf_trampoline **trampoline) +{ + struct bpf_trampoline *tr; + + tr = bpf_trampoline_lookup(key); + if (!tr) + return -ENOMEM; + + mutex_lock(&tr->mutex); + if (tr->func.addr) + goto out; + + memcpy(&tr->func.model, fmodel, sizeof(*fmodel)); + tr->func.addr = addr; +out: + mutex_unlock(&tr->mutex); + *trampoline = tr; + return 0; +} + void bpf_trampoline_put(struct bpf_trampoline *tr) { if (!tr) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 0db338567cf9..ff3c5c53982c 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -10724,31 +10724,23 @@ static int check_attach_modify_return(struct bpf_prog *prog, unsigned long addr) return -EINVAL; } -static int check_attach_btf_id(struct bpf_verifier_env *env) +int bpf_check_attach_target(struct bpf_verifier_log *log, + const struct bpf_prog *prog, + const struct bpf_prog *tgt_prog, + u32 btf_id, + struct btf_func_model *fmodel, + long *tgt_addr, + const char **tgt_name, + const struct btf_type **tgt_type) { - struct bpf_prog *prog = env->prog; bool prog_extension = prog->type == BPF_PROG_TYPE_EXT; - struct bpf_prog *tgt_prog = prog->aux->linked_prog; - struct bpf_verifier_log *log = &env->log; - u32 btf_id = prog->aux->attach_btf_id; const char prefix[] = "btf_trace_"; - struct btf_func_model fmodel; int ret = 0, subprog = -1, i; - struct bpf_trampoline *tr; const struct btf_type *t; bool conservative = true; const char *tname; struct btf *btf; long addr; - u64 key; - - if (prog->type == BPF_PROG_TYPE_STRUCT_OPS) - return check_struct_ops_btf_id(env); - - if (prog->type != BPF_PROG_TYPE_TRACING && - prog->type != BPF_PROG_TYPE_LSM && - !prog_extension) - return 0; if (!btf_id) { bpf_log(log, "Tracing programs must provide btf_id\n"); @@ -10794,8 +10786,6 @@ static int check_attach_btf_id(struct bpf_verifier_env *env) "Extension programs should be JITed\n"); return -EINVAL; } - env->ops = bpf_verifier_ops[tgt_prog->type]; - prog->expected_attach_type = tgt_prog->expected_attach_type; } if (!tgt_prog->jited) { bpf_log(log, "Can attach to only JITed progs\n"); @@ -10831,13 +10821,11 @@ static int check_attach_btf_id(struct bpf_verifier_env *env) bpf_log(log, "Cannot extend fentry/fexit\n"); return -EINVAL; } - key = ((u64)aux->id) << 32 | btf_id; } else { if (prog_extension) { bpf_log(log, "Cannot replace kernel functions\n"); return -EINVAL; } - key = btf_id; } switch (prog->expected_attach_type) { @@ -10867,13 +10855,7 @@ static int check_attach_btf_id(struct bpf_verifier_env *env) /* should never happen in valid vmlinux build */ return -EINVAL; - /* remember two read only pointers that are valid for - * the life time of the kernel - */ - prog->aux->attach_func_name = tname; - prog->aux->attach_func_proto = t; - prog->aux->attach_btf_trace = true; - return 0; + break; case BPF_TRACE_ITER: if (!btf_type_is_func(t)) { bpf_log(log, "attach_btf_id %u is not a function\n", @@ -10883,12 +10865,10 @@ static int check_attach_btf_id(struct bpf_verifier_env *env) t = btf_type_by_id(btf, t->type); if (!btf_type_is_func_proto(t)) return -EINVAL; - prog->aux->attach_func_name = tname; - prog->aux->attach_func_proto = t; - if (!bpf_iter_prog_supported(prog)) - return -EINVAL; - ret = btf_distill_func_proto(log, btf, t, tname, &fmodel); - return ret; + ret = btf_distill_func_proto(log, btf, t, tname, fmodel); + if (ret) + return ret; + break; default: if (!prog_extension) return -EINVAL; @@ -10897,13 +10877,6 @@ static int check_attach_btf_id(struct bpf_verifier_env *env) case BPF_LSM_MAC: case BPF_TRACE_FENTRY: case BPF_TRACE_FEXIT: - prog->aux->attach_func_name = tname; - if (prog->type == BPF_PROG_TYPE_LSM) { - ret = bpf_lsm_verify_prog(log, prog); - if (ret < 0) - return ret; - } - if (!btf_type_is_func(t)) { bpf_log(log, "attach_btf_id %u is not a function\n", btf_id); @@ -10915,24 +10888,14 @@ static int check_attach_btf_id(struct bpf_verifier_env *env) t = btf_type_by_id(btf, t->type); if (!btf_type_is_func_proto(t)) return -EINVAL; - tr = bpf_trampoline_lookup(key); - if (!tr) - return -ENOMEM; - /* t is either vmlinux type or another program's type */ - prog->aux->attach_func_proto = t; - mutex_lock(&tr->mutex); - if (tr->func.addr) { - prog->aux->trampoline = tr; - goto out; - } - if (tgt_prog && conservative) { - prog->aux->attach_func_proto = NULL; + + if (tgt_prog && conservative) t = NULL; - } - ret = btf_distill_func_proto(log, btf, t, - tname, &tr->func.model); + + ret = btf_distill_func_proto(log, btf, t, tname, fmodel); if (ret < 0) - goto out; + return ret; + if (tgt_prog) { if (subprog == 0) addr = (long) tgt_prog->bpf_func; @@ -10944,27 +10907,85 @@ static int check_attach_btf_id(struct bpf_verifier_env *env) bpf_log(log, "The address of function %s cannot be found\n", tname); - ret = -ENOENT; - goto out; + return -ENOENT; } } + break; + } - if (prog->expected_attach_type == BPF_MODIFY_RETURN) { - ret = check_attach_modify_return(prog, addr); - if (ret) - bpf_log(log, "%s() is not modifiable\n", - prog->aux->attach_func_name); - } + *tgt_addr = addr; + if (tgt_name) + *tgt_name = tname; + if (tgt_type) + *tgt_type = t; + return 0; +} - if (ret) - goto out; - tr->func.addr = (void *)addr; - prog->aux->trampoline = tr; -out: - mutex_unlock(&tr->mutex); - if (ret) - bpf_trampoline_put(tr); +static int check_attach_btf_id(struct bpf_verifier_env *env) +{ + struct bpf_prog *prog = env->prog; + struct bpf_prog *tgt_prog = prog->aux->linked_prog; + u32 btf_id = prog->aux->attach_btf_id; + struct btf_func_model fmodel; + const struct btf_type *t; + const char *tname; + long addr; + int ret; + u64 key; + + if (prog->type == BPF_PROG_TYPE_STRUCT_OPS) + return check_struct_ops_btf_id(env); + + if (prog->type != BPF_PROG_TYPE_TRACING && + prog->type != BPF_PROG_TYPE_LSM && + prog->type != BPF_PROG_TYPE_EXT) + return 0; + + ret = bpf_check_attach_target(&env->log, prog, tgt_prog, btf_id, + &fmodel, &addr, &tname, &t); + if (ret) return ret; + + if (tgt_prog) { + if (prog->type == BPF_PROG_TYPE_EXT) { + env->ops = bpf_verifier_ops[tgt_prog->type]; + prog->expected_attach_type = tgt_prog->expected_attach_type; + } + key = ((u64)tgt_prog->aux->id) << 32 | btf_id; + } else { + key = btf_id; + } + + prog->aux->attach_func_proto = t; + prog->aux->attach_func_name = tname; + + switch (prog->expected_attach_type) { + case BPF_TRACE_RAW_TP: + /* remember two read only pointers that are valid for + * the life time of the kernel + */ + prog->aux->attach_btf_trace = true; + return 0; + case BPF_TRACE_ITER: + if (!bpf_iter_prog_supported(prog)) + return -EINVAL; + return 0; + case BPF_MODIFY_RETURN: + ret = check_attach_modify_return(prog, addr); + if (ret) { + verbose(env, "%s() is not modifiable\n", + prog->aux->attach_func_name); + return ret; + } + fallthrough; + default: + if (prog->type == BPF_PROG_TYPE_LSM) { + ret = bpf_lsm_verify_prog(&env->log, prog); + if (ret < 0) + return ret; + } + return bpf_trampoline_get(key, (void *)addr, &fmodel, + &prog->aux->trampoline); } } From patchwork Mon Jul 13 20:12:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= X-Patchwork-Id: 1328451 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=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=GFsskRwG; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4B5FF54sxmz9sQt for ; Tue, 14 Jul 2020 06:12:41 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726962AbgGMUMk (ORCPT ); Mon, 13 Jul 2020 16:12:40 -0400 Received: from us-smtp-delivery-1.mimecast.com ([205.139.110.120]:23891 "EHLO us-smtp-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726892AbgGMUMf (ORCPT ); Mon, 13 Jul 2020 16:12:35 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1594671151; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=i1/BPEQw8RfyZcO+NWLHyd7BgTIrRVhqDQkxeEyIIXA=; b=GFsskRwG0gwuhzItEJNbP26/plZdBe7sV0p40OtoeaUjtHuQ+9lHjbqbQymSeuDwp3bDYG rhzsGN7B2WXlDlHYe82WhD3U97QDOxWnBycLUgklgaDLT0M9xWn7y7DzHxqexDrwkqWyxj 59cK7tXdbuR/OR2bvylqLAYWs92n9fc= Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-148-Ljz77xGfN_aUHw_wb2GHPw-1; Mon, 13 Jul 2020 16:12:29 -0400 X-MC-Unique: Ljz77xGfN_aUHw_wb2GHPw-1 Received: by mail-wr1-f70.google.com with SMTP id y18so18752004wrq.4 for ; Mon, 13 Jul 2020 13:12:29 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:from:to:cc:date:message-id:in-reply-to :references:user-agent:mime-version:content-transfer-encoding; bh=i1/BPEQw8RfyZcO+NWLHyd7BgTIrRVhqDQkxeEyIIXA=; b=G1dcScaIGkI2A2ZelzUB+9oT1upvn6S5Y72cTb2zAZT1ww4nobMIGwVpARr+m9CW0o SWYlG0aL99qqmDF8XnEtP+yqXCJccpmkTx4zEDHjbLTO4ugOBMDAsqgrpceKKxN00mQE blyykANQiyGc1couiF5W/PQGikmYsPO3GsIygCJiksCLJzesrUgWiEUuFBMroYNAqq70 V4Qn0xiimarJhP/zJWR2htkdw+uh63XSjH+nTQjjuLaJDyjD9TOfeEoZAchsKubPLjHN 6l8fVp26EzhkvmIBRBFFvc1w8EylwjH/hqnGFdzRlmDv9VbGm9MEqA+Ke9McOPHlh907 BkTA== X-Gm-Message-State: AOAM532mmwODMCA5dm1qGoxSSd69hxsgLw2J6BZHHGFgnF1l0Nz4Qsv/ fTtY9WUBNIxDmd6DBFRoDz8B04aFuG4PL8iQNb/uSHvDtx1N3TKfugGZz0O14A/EhqXnhtZrrYN Xx2fAWVX5YiDbVOQK X-Received: by 2002:a1c:7fd3:: with SMTP id a202mr1015711wmd.67.1594671147320; Mon, 13 Jul 2020 13:12:27 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxenBix3eFC0SsE9tO/h8hP/73/jfawbkU8TBpwBkAB5ElGGORP5U76cppDD3ZB1+Lzd0F82w== X-Received: by 2002:a1c:7fd3:: with SMTP id a202mr1015691wmd.67.1594671146944; Mon, 13 Jul 2020 13:12:26 -0700 (PDT) Received: from alrua-x1.borgediget.toke.dk ([2a0c:4d80:42:443::2]) by smtp.gmail.com with ESMTPSA id l1sm25853364wrb.12.2020.07.13.13.12.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 13 Jul 2020 13:12:25 -0700 (PDT) Received: by alrua-x1.borgediget.toke.dk (Postfix, from userid 1000) id 0D8711804F0; Mon, 13 Jul 2020 22:12:23 +0200 (CEST) Subject: [PATCH bpf-next 3/6] bpf: support attaching freplace programs to multiple attach points From: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= To: Alexei Starovoitov Cc: Daniel Borkmann , Martin KaFai Lau , Song Liu , Yonghong Song , Andrii Nakryiko , John Fastabend , KP Singh , netdev@vger.kernel.org, bpf@vger.kernel.org Date: Mon, 13 Jul 2020 22:12:23 +0200 Message-ID: <159467114297.370286.13434549915540848776.stgit@toke.dk> In-Reply-To: <159467113970.370286.17656404860101110795.stgit@toke.dk> References: <159467113970.370286.17656404860101110795.stgit@toke.dk> User-Agent: StGit/0.23 MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Toke Høiland-Jørgensen This enables support for attaching freplace programs to multiple attach points. It does this by amending UAPI for bpf_raw_tracepoint_open with a target prog fd and btf ID pair that can be used to supply the new attachment point. The target must be compatible with the target that was supplied at program load time. Since the checks for the attach target compatibility will output debug information about why the attachment was rejected to the verifier log, also add support for supplying a log buffer to bpf_raw_tracepoint_open. The implementation reuses the checks that were factored out of check_attach_btf_id() in the previous patch. It also moves the BPF trampoline out of prog->aux and into struct bpf_tracking_link where it is managed as part of the bpf_link structure. When a new target is specified, a reference to the target program is also kept in the bpf_link structure which removes the need to keep references to all attach targets in the bpf_prog structure itself. The code could theoretically support multiple-attach of other types of tracing programs as well, but since I don't have a use case for any of those, the bpf_tracing_prog_attach() function will reject new targets for anything other than PROG_TYPE_EXT programs. Signed-off-by: Toke Høiland-Jørgensen Reported-by: kernel test robot --- include/linux/bpf.h | 14 ++++--- include/uapi/linux/bpf.h | 9 +++- kernel/bpf/core.c | 1 kernel/bpf/syscall.c | 96 +++++++++++++++++++++++++++++++++++++++++++--- kernel/bpf/trampoline.c | 14 +++---- kernel/bpf/verifier.c | 16 +++++--- 6 files changed, 121 insertions(+), 29 deletions(-) diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 67310595f720..3d43778a1d05 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -568,8 +568,8 @@ static __always_inline unsigned int bpf_dispatcher_nop_func( } #ifdef CONFIG_BPF_JIT struct bpf_trampoline *bpf_trampoline_lookup(u64 key); -int bpf_trampoline_link_prog(struct bpf_prog *prog); -int bpf_trampoline_unlink_prog(struct bpf_prog *prog); +int bpf_trampoline_link_prog(struct bpf_prog *prog, struct bpf_trampoline *tr); +int bpf_trampoline_unlink_prog(struct bpf_prog *prog, struct bpf_trampoline *tr); int bpf_trampoline_get(u64 key, void *addr, struct btf_func_model *fmodel, struct bpf_trampoline **trampoline); @@ -621,11 +621,13 @@ static inline struct bpf_trampoline *bpf_trampoline_lookup(u64 key) { return NULL; } -static inline int bpf_trampoline_link_prog(struct bpf_prog *prog) +static inline int bpf_trampoline_link_prog(struct bpf_prog *prog, + struct bpf_trampoline *tr) { return -ENOTSUPP; } -static inline int bpf_trampoline_unlink_prog(struct bpf_prog *prog) +static inline int bpf_trampoline_unlink_prog(struct bpf_prog *prog, + struct bpf_trampoline *tr) { return -ENOTSUPP; } @@ -697,10 +699,12 @@ struct bpf_prog_aux { bool attach_btf_trace; /* true if attaching to BTF-enabled raw tp */ bool func_proto_unreliable; enum bpf_tramp_prog_type trampoline_prog_type; - struct bpf_trampoline *trampoline; struct hlist_node tramp_hlist; /* BTF_KIND_FUNC_PROTO for valid attach_btf_id */ const struct btf_type *attach_func_proto; + /* target BPF prog types for trace programs */ + enum bpf_prog_type tgt_prog_type; + enum bpf_attach_type tgt_attach_type; /* function name for valid attach_btf_id */ const char *attach_func_name; struct bpf_prog **func; diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index da9bf35a26f8..662a15e4a1a1 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -573,8 +573,13 @@ union bpf_attr { } query; struct { /* anonymous struct used by BPF_RAW_TRACEPOINT_OPEN command */ - __u64 name; - __u32 prog_fd; + __u64 name; + __u32 prog_fd; + __u32 log_level; /* verbosity level of log */ + __u32 log_size; /* size of user buffer */ + __aligned_u64 log_buf; /* user supplied buffer */ + __u32 tgt_prog_fd; + __u32 tgt_btf_id; } raw_tracepoint; struct { /* anonymous struct for BPF_BTF_LOAD */ diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index 9df4cc9a2907..ed4d7259316a 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -2087,7 +2087,6 @@ static void bpf_prog_free_deferred(struct work_struct *work) if (aux->prog->has_callchain_buf) put_callchain_buffers(); #endif - bpf_trampoline_put(aux->trampoline); for (i = 0; i < aux->func_cnt; i++) bpf_jit_free(aux->func[i]); if (aux->func_cnt) { diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 8da159936bab..eec6dc0f0a54 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -2483,11 +2484,21 @@ struct bpf_link *bpf_link_get_from_fd(u32 ufd) struct bpf_tracing_link { struct bpf_link link; enum bpf_attach_type attach_type; + struct bpf_trampoline *trampoline; + struct bpf_prog *tgt_prog; }; static void bpf_tracing_link_release(struct bpf_link *link) { - WARN_ON_ONCE(bpf_trampoline_unlink_prog(link->prog)); + struct bpf_tracing_link *tr_link = + container_of(link, struct bpf_tracing_link, link); + + WARN_ON_ONCE(bpf_trampoline_unlink_prog(link->prog, + tr_link->trampoline)); + + bpf_trampoline_put(tr_link->trampoline); + if (tr_link->tgt_prog) + bpf_prog_put(tr_link->tgt_prog); } static void bpf_tracing_link_dealloc(struct bpf_link *link) @@ -2527,10 +2538,18 @@ static const struct bpf_link_ops bpf_tracing_link_lops = { .fill_link_info = bpf_tracing_link_fill_link_info, }; -static int bpf_tracing_prog_attach(struct bpf_prog *prog) +static int bpf_tracing_prog_attach(struct bpf_prog *prog, + int tgt_prog_fd, + u32 btf_id, + struct bpf_verifier_log *log) { struct bpf_link_primer link_primer; + struct bpf_trampoline *tr = NULL; + struct bpf_prog *tgt_prog = NULL; struct bpf_tracing_link *link; + struct btf_func_model fmodel; + long addr; + u64 key; int err; switch (prog->type) { @@ -2559,6 +2578,43 @@ static int bpf_tracing_prog_attach(struct bpf_prog *prog) goto out_put_prog; } + if (tgt_prog_fd) { + /* For now we only allow new targets for BPF_PROG_TYPE_EXT */ + if (prog->type != BPF_PROG_TYPE_EXT || + !btf_id) { + err = -EINVAL; + goto out_put_prog; + } + tgt_prog = bpf_prog_get(tgt_prog_fd); + if (IS_ERR(tgt_prog)) { + err = PTR_ERR(tgt_prog); + tgt_prog = NULL; + goto out_put_prog; + } + + } else if (btf_id) { + err = -EINVAL; + goto out_put_prog; + } else { + btf_id = prog->aux->attach_btf_id; + tgt_prog = prog->aux->linked_prog; + if (tgt_prog) + bpf_prog_inc(tgt_prog); /* we call bpf_prog_put() on link release */ + } + err = bpf_check_attach_target(log, prog, tgt_prog, btf_id, + &fmodel, &addr, NULL, NULL); + if (err) + goto out_put_prog; + + if (tgt_prog) + key = ((u64)tgt_prog->aux->id) << 32 | btf_id; + else + key = btf_id; + + err = bpf_trampoline_get(key, (void *)addr, &fmodel, &tr); + if (err) + goto out_put_prog; + link = kzalloc(sizeof(*link), GFP_USER); if (!link) { err = -ENOMEM; @@ -2574,15 +2630,21 @@ static int bpf_tracing_prog_attach(struct bpf_prog *prog) goto out_put_prog; } - err = bpf_trampoline_link_prog(prog); + err = bpf_trampoline_link_prog(prog, tr); if (err) { bpf_link_cleanup(&link_primer); goto out_put_prog; } + link->trampoline = tr; + link->tgt_prog = tgt_prog; return bpf_link_settle(&link_primer); out_put_prog: bpf_prog_put(prog); + if (tgt_prog) + bpf_prog_put(tgt_prog); + if (tr) + bpf_trampoline_put(tr); return err; } @@ -2660,11 +2722,12 @@ static const struct bpf_link_ops bpf_raw_tp_link_lops = { .fill_link_info = bpf_raw_tp_link_fill_link_info, }; -#define BPF_RAW_TRACEPOINT_OPEN_LAST_FIELD raw_tracepoint.prog_fd +#define BPF_RAW_TRACEPOINT_OPEN_LAST_FIELD raw_tracepoint.tgt_btf_id static int bpf_raw_tracepoint_open(const union bpf_attr *attr) { struct bpf_link_primer link_primer; + struct bpf_verifier_log log = {}; struct bpf_raw_tp_link *link; struct bpf_raw_event_map *btp; struct bpf_prog *prog; @@ -2679,13 +2742,30 @@ static int bpf_raw_tracepoint_open(const union bpf_attr *attr) if (IS_ERR(prog)) return PTR_ERR(prog); + if (attr->raw_tracepoint.log_level || + attr->raw_tracepoint.log_buf || + attr->raw_tracepoint.log_size) { + /* user requested verbose verifier output + * and supplied buffer to store the verification trace + */ + log.level = attr->raw_tracepoint.log_level; + log.ubuf = (char __user *) (unsigned long) attr->raw_tracepoint.log_buf; + log.len_total = attr->raw_tracepoint.log_size; + + /* log attributes have to be sane */ + if (log.len_total < 128 || log.len_total > UINT_MAX >> 2 || + !log.level || !log.ubuf || log.level & ~BPF_LOG_MASK) + return -EINVAL; + } + switch (prog->type) { case BPF_PROG_TYPE_TRACING: case BPF_PROG_TYPE_EXT: case BPF_PROG_TYPE_LSM: if (attr->raw_tracepoint.name) { - /* The attach point for this category of programs - * should be specified via btf_id during program load. + /* The attach point for this category of programs should + * be specified via btf_id during program load, or using + * tgt_btf_id. */ err = -EINVAL; goto out_put_prog; @@ -2695,7 +2775,9 @@ static int bpf_raw_tracepoint_open(const union bpf_attr *attr) tp_name = prog->aux->attach_func_name; break; } - return bpf_tracing_prog_attach(prog); + return bpf_tracing_prog_attach(prog, + attr->raw_tracepoint.tgt_prog_fd, + attr->raw_tracepoint.tgt_btf_id, &log); case BPF_PROG_TYPE_RAW_TRACEPOINT: case BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE: if (strncpy_from_user(buf, diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c index fadfa330f728..40797405f1a0 100644 --- a/kernel/bpf/trampoline.c +++ b/kernel/bpf/trampoline.c @@ -256,14 +256,13 @@ static enum bpf_tramp_prog_type bpf_attach_type_to_tramp(struct bpf_prog *prog) } } -int bpf_trampoline_link_prog(struct bpf_prog *prog) +int bpf_trampoline_link_prog(struct bpf_prog *prog, + struct bpf_trampoline *tr) { enum bpf_tramp_prog_type kind; - struct bpf_trampoline *tr; int err = 0; int cnt; - tr = prog->aux->trampoline; kind = bpf_attach_type_to_tramp(prog); mutex_lock(&tr->mutex); if (tr->extension_prog) { @@ -296,7 +295,7 @@ int bpf_trampoline_link_prog(struct bpf_prog *prog) } hlist_add_head(&prog->aux->tramp_hlist, &tr->progs_hlist[kind]); tr->progs_cnt[kind]++; - err = bpf_trampoline_update(prog->aux->trampoline); + err = bpf_trampoline_update(tr); if (err) { hlist_del(&prog->aux->tramp_hlist); tr->progs_cnt[kind]--; @@ -307,13 +306,12 @@ int bpf_trampoline_link_prog(struct bpf_prog *prog) } /* bpf_trampoline_unlink_prog() should never fail. */ -int bpf_trampoline_unlink_prog(struct bpf_prog *prog) +int bpf_trampoline_unlink_prog(struct bpf_prog *prog, + struct bpf_trampoline *tr) { enum bpf_tramp_prog_type kind; - struct bpf_trampoline *tr; int err; - tr = prog->aux->trampoline; kind = bpf_attach_type_to_tramp(prog); mutex_lock(&tr->mutex); if (kind == BPF_TRAMP_REPLACE) { @@ -325,7 +323,7 @@ int bpf_trampoline_unlink_prog(struct bpf_prog *prog) } hlist_del(&prog->aux->tramp_hlist); tr->progs_cnt[kind]--; - err = bpf_trampoline_update(prog->aux->trampoline); + err = bpf_trampoline_update(tr); out: mutex_unlock(&tr->mutex); return err; diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index ff3c5c53982c..867bc14f5610 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -10889,6 +10889,12 @@ int bpf_check_attach_target(struct bpf_verifier_log *log, if (!btf_type_is_func_proto(t)) return -EINVAL; + if ((prog->aux->tgt_prog_type && + prog->aux->tgt_prog_type != tgt_prog->type) || + (prog->aux->tgt_attach_type && + prog->aux->tgt_attach_type != tgt_prog->expected_attach_type)) + return -EINVAL; + if (tgt_prog && conservative) t = NULL; @@ -10931,7 +10937,6 @@ static int check_attach_btf_id(struct bpf_verifier_env *env) const char *tname; long addr; int ret; - u64 key; if (prog->type == BPF_PROG_TYPE_STRUCT_OPS) return check_struct_ops_btf_id(env); @@ -10947,13 +10952,13 @@ static int check_attach_btf_id(struct bpf_verifier_env *env) return ret; if (tgt_prog) { + prog->aux->tgt_prog_type = tgt_prog->type; + prog->aux->tgt_attach_type = tgt_prog->expected_attach_type; + if (prog->type == BPF_PROG_TYPE_EXT) { env->ops = bpf_verifier_ops[tgt_prog->type]; prog->expected_attach_type = tgt_prog->expected_attach_type; } - key = ((u64)tgt_prog->aux->id) << 32 | btf_id; - } else { - key = btf_id; } prog->aux->attach_func_proto = t; @@ -10984,8 +10989,7 @@ static int check_attach_btf_id(struct bpf_verifier_env *env) if (ret < 0) return ret; } - return bpf_trampoline_get(key, (void *)addr, &fmodel, - &prog->aux->trampoline); + return 0; } } From patchwork Mon Jul 13 20:12:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= X-Patchwork-Id: 1328444 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=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=SIAlkDuq; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4B5FDx38gzz9sQt for ; Tue, 14 Jul 2020 06:12:33 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726855AbgGMUMc (ORCPT ); Mon, 13 Jul 2020 16:12:32 -0400 Received: from us-smtp-delivery-1.mimecast.com ([205.139.110.120]:26838 "EHLO us-smtp-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726798AbgGMUMa (ORCPT ); Mon, 13 Jul 2020 16:12:30 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1594671149; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=r62uEiX4gXx9on9wTU8Kbsa3mLKmRZ7+dNYoSyMkncA=; b=SIAlkDuqG1wYrJpEBs1JgJ2B2tlDM34Hdi6ga+6m5UMYstkxbdg+ePFiri1ydQ9GON2n5e JPmJYJML/2ULWpGS2u7s4/0mavbjYKD4fCllyXkpxJ7KI4lyzAanlL5si2BOErQT44YU3q JLVRpcxuFOo7SqhB2UI7rTWQziyhsSE= Received: from mail-wr1-f72.google.com (mail-wr1-f72.google.com [209.85.221.72]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-350-zp4qWreANya4iuQDisfEpA-1; Mon, 13 Jul 2020 16:12:27 -0400 X-MC-Unique: zp4qWreANya4iuQDisfEpA-1 Received: by mail-wr1-f72.google.com with SMTP id y16so18627793wrr.20 for ; Mon, 13 Jul 2020 13:12:26 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:from:to:cc:date:message-id:in-reply-to :references:user-agent:mime-version:content-transfer-encoding; bh=r62uEiX4gXx9on9wTU8Kbsa3mLKmRZ7+dNYoSyMkncA=; b=rcS9INEpp/yUY0XwlGbAOns/zq0VnrtFxCtskUlcmo7j/EYu4tjws+t/Q4nFV9gJh8 znYDpjgVGZxYEBfE8nkT80Pp2lfl89Pgb96U/oUMMz3I4eZFSbl5V/IsijOp8pfcILyw 1D49ZaLgx2/hj6p98W8+oeUUDN+2WO4eLOVpTsWVXb+j0r+pt+5RzCjONH5UEoXSaX8m qBqStqIuH4gay7Q4Mlo5y5tyKrzeDdV9Mstqs6jaWPkWDoHxXQRojW7wypuIpt3owSSI hCxUiR2f3AmL0Vp90504/paKWaLDIvMc6eCYDJqn5euVU6uFff7lD9UtyhojAjVHwkAx pwiw== X-Gm-Message-State: AOAM5317kwRWPT1c8kPIKj4n+DYiqbjxjgntkcOX8LMo/PVCkAWolPq+ 6f5euUs7xM5pJRg+3z7dvj670BL6iL0ut33sF+DOAAF9OhOnzVlNME6o9XzxzQHwYXEn3I0xTOR u40kqETDwUvkJfyko X-Received: by 2002:a05:6000:10c4:: with SMTP id b4mr1171134wrx.50.1594671146020; Mon, 13 Jul 2020 13:12:26 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwHuL1u53iYWEo0/trUpZpXNAJTAQGz0n6g3EupXuadC4qKdfTjweczjX09j3dGLz98+Hj6cA== X-Received: by 2002:a05:6000:10c4:: with SMTP id b4mr1171120wrx.50.1594671145870; Mon, 13 Jul 2020 13:12:25 -0700 (PDT) Received: from alrua-x1.borgediget.toke.dk ([2a0c:4d80:42:443::2]) by smtp.gmail.com with ESMTPSA id m4sm848784wmi.48.2020.07.13.13.12.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 13 Jul 2020 13:12:25 -0700 (PDT) Received: by alrua-x1.borgediget.toke.dk (Postfix, from userid 1000) id 26330180653; Mon, 13 Jul 2020 22:12:24 +0200 (CEST) Subject: [PATCH bpf-next 4/6] tools: add new members to bpf_attr.raw_tracepoint in bpf.h From: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= To: Alexei Starovoitov Cc: Daniel Borkmann , Martin KaFai Lau , Song Liu , Yonghong Song , Andrii Nakryiko , John Fastabend , KP Singh , netdev@vger.kernel.org, bpf@vger.kernel.org Date: Mon, 13 Jul 2020 22:12:24 +0200 Message-ID: <159467114405.370286.1690821122507970067.stgit@toke.dk> In-Reply-To: <159467113970.370286.17656404860101110795.stgit@toke.dk> References: <159467113970.370286.17656404860101110795.stgit@toke.dk> User-Agent: StGit/0.23 MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Toke Høiland-Jørgensen Sync addition of new members from main kernel tree. Signed-off-by: Toke Høiland-Jørgensen --- tools/include/uapi/linux/bpf.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index da9bf35a26f8..662a15e4a1a1 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -573,8 +573,13 @@ union bpf_attr { } query; struct { /* anonymous struct used by BPF_RAW_TRACEPOINT_OPEN command */ - __u64 name; - __u32 prog_fd; + __u64 name; + __u32 prog_fd; + __u32 log_level; /* verbosity level of log */ + __u32 log_size; /* size of user buffer */ + __aligned_u64 log_buf; /* user supplied buffer */ + __u32 tgt_prog_fd; + __u32 tgt_btf_id; } raw_tracepoint; struct { /* anonymous struct for BPF_BTF_LOAD */ From patchwork Mon Jul 13 20:12:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= X-Patchwork-Id: 1328446 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=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=boM9jGV1; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4B5FDz3xFnz9sQt for ; Tue, 14 Jul 2020 06:12:35 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726460AbgGMUMe (ORCPT ); Mon, 13 Jul 2020 16:12:34 -0400 Received: from us-smtp-2.mimecast.com ([207.211.31.81]:53850 "EHLO us-smtp-delivery-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726748AbgGMUMb (ORCPT ); Mon, 13 Jul 2020 16:12:31 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1594671149; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=6N16UjTiiaCaM01HWZd1AxR2a9Xuk8yHd46b6qpU0y4=; b=boM9jGV1lLISo2f4+fItWogLV6sXetAsX91uiOxlehafYby8SoIVLUJjVA2+jQI4VR/53b BbMc3G/5uiRDyDzDC/1m8klos0InC8sWp9copUEe0NUHjmPeLKEkSImei4u9uN7/kDAoHK DUj6KQTIRIyabJtx5rVT9lLPdwf4j78= Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-457-32tKiRc7MDuKH20Udzhwpg-1; Mon, 13 Jul 2020 16:12:27 -0400 X-MC-Unique: 32tKiRc7MDuKH20Udzhwpg-1 Received: by mail-wr1-f69.google.com with SMTP id y16so18627826wrr.20 for ; Mon, 13 Jul 2020 13:12:27 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:from:to:cc:date:message-id:in-reply-to :references:user-agent:mime-version:content-transfer-encoding; bh=6N16UjTiiaCaM01HWZd1AxR2a9Xuk8yHd46b6qpU0y4=; b=tUdM4oPGh3PCwgK24SWgaRwnnVlqSb5QFQB9qRk6Co9bnDGbSVV++9f2bYv82s5cgd lwH/hkOPCnpSd65jsQ5sq+OUqFxg7wDB6VG/nyD+Kt5X27Jko1fssq9HIDUjiGz5W/Lu w3wbutmpv8gV646GgZZP4fy33cBMu/r24HWML24Y9JKzwrnKlOexsAS53HWSALqzUmXo gUqkFkBHkf4xTfFPhvMNoNbfl0RkldGg/x9RHld1yoAHOoOC0nfZdiScbYhZjYXN4dBy IaVqHtMTpmj4a2g19IVlhBCx2vxEiRCcN1uCYsEiZ0e6OxQnQs/ElBH7xEu8DhsExVN5 WO3A== X-Gm-Message-State: AOAM530pPPjQ/54KJcsQupicbSlKXnKecdWlpp83j+CVHd5j9qjPNUl4 L4dxTBn9Gcbi4Ce7zaP6B9QxnGyt4/DXavouAEmpn6gggXzhNoe3XEdZNiNKoJKB5wKLHBmLvH3 Zg6j+Pb8vSvXBQLLv X-Received: by 2002:a05:600c:2295:: with SMTP id 21mr1027686wmf.29.1594671146693; Mon, 13 Jul 2020 13:12:26 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzOF2WiI4mZcNH8co/W0tjmT9+k0r0bee7CNBUk0s7d2wwstq02aXfL0cGMIefQT9gYCnW4QQ== X-Received: by 2002:a05:600c:2295:: with SMTP id 21mr1027675wmf.29.1594671146416; Mon, 13 Jul 2020 13:12:26 -0700 (PDT) Received: from alrua-x1.borgediget.toke.dk ([2a0c:4d80:42:443::2]) by smtp.gmail.com with ESMTPSA id n125sm914502wme.30.2020.07.13.13.12.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 13 Jul 2020 13:12:25 -0700 (PDT) Received: by alrua-x1.borgediget.toke.dk (Postfix, from userid 1000) id 3B777181C9D; Mon, 13 Jul 2020 22:12:25 +0200 (CEST) Subject: [PATCH bpf-next 5/6] libbpf: add support for supplying target to bpf_raw_tracepoint_open() From: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= To: Alexei Starovoitov Cc: Daniel Borkmann , Martin KaFai Lau , Song Liu , Yonghong Song , Andrii Nakryiko , John Fastabend , KP Singh , netdev@vger.kernel.org, bpf@vger.kernel.org Date: Mon, 13 Jul 2020 22:12:25 +0200 Message-ID: <159467114516.370286.16673271076079979202.stgit@toke.dk> In-Reply-To: <159467113970.370286.17656404860101110795.stgit@toke.dk> References: <159467113970.370286.17656404860101110795.stgit@toke.dk> User-Agent: StGit/0.23 MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Toke Høiland-Jørgensen This adds support for supplying a target fd and btf ID for the raw_tracepoint_open() BPF operation, using a new bpf_raw_tracepoint_opts structure. This can be used for attaching freplace programs to multiple destinations. Signed-off-by: Toke Høiland-Jørgensen --- tools/lib/bpf/bpf.c | 33 ++++++++++++++++++++++++++++++++- tools/lib/bpf/bpf.h | 12 ++++++++++++ tools/lib/bpf/libbpf.map | 1 + 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c index a7329b671c41..6e7690d8ddfb 100644 --- a/tools/lib/bpf/bpf.c +++ b/tools/lib/bpf/bpf.c @@ -793,17 +793,48 @@ int bpf_obj_get_info_by_fd(int bpf_fd, void *info, __u32 *info_len) return err; } -int bpf_raw_tracepoint_open(const char *name, int prog_fd) +int bpf_raw_tracepoint_open_opts(const char *name, int prog_fd, + struct bpf_raw_tracepoint_opts *opts) { union bpf_attr attr; + size_t log_buf_sz; + __u32 log_level; + char *log_buf; + + if (!OPTS_VALID(opts, bpf_raw_tracepoint_opts)) + return -EINVAL; + + log_buf = OPTS_GET(opts, log_buf, NULL); + log_buf_sz = OPTS_GET(opts, log_buf_sz, 0); + log_level = OPTS_GET(opts, log_level, 0); + + if (!log_buf != !log_buf_sz || log_level > (4 | 2 | 1) || + (log_level && !log_buf)) + return -EINVAL; memset(&attr, 0, sizeof(attr)); attr.raw_tracepoint.name = ptr_to_u64(name); attr.raw_tracepoint.prog_fd = prog_fd; + attr.raw_tracepoint.tgt_prog_fd = OPTS_GET(opts, tgt_prog_fd, 0); + attr.raw_tracepoint.tgt_btf_id = OPTS_GET(opts, tgt_btf_id, 0); + + attr.raw_tracepoint.log_level = log_level; + if (log_level) { + attr.raw_tracepoint.log_buf = ptr_to_u64(log_buf); + attr.raw_tracepoint.log_size = log_buf_sz; + } else { + attr.raw_tracepoint.log_buf = ptr_to_u64(NULL); + attr.raw_tracepoint.log_size = 0; + } return sys_bpf(BPF_RAW_TRACEPOINT_OPEN, &attr, sizeof(attr)); } +int bpf_raw_tracepoint_open(const char *name, int prog_fd) +{ + return bpf_raw_tracepoint_open_opts(name, prog_fd, NULL); +} + int bpf_load_btf(void *btf, __u32 btf_size, char *log_buf, __u32 log_buf_size, bool do_log) { diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h index 1b6015b21ba8..b6b8ebb6ce65 100644 --- a/tools/lib/bpf/bpf.h +++ b/tools/lib/bpf/bpf.h @@ -227,7 +227,19 @@ LIBBPF_API int bpf_obj_get_info_by_fd(int bpf_fd, void *info, __u32 *info_len); LIBBPF_API int bpf_prog_query(int target_fd, enum bpf_attach_type type, __u32 query_flags, __u32 *attach_flags, __u32 *prog_ids, __u32 *prog_cnt); +struct bpf_raw_tracepoint_opts { + size_t sz; /* size of this struct for forward/backward compatibility */ + __u32 log_level; + char *log_buf; + size_t log_buf_sz; + int tgt_prog_fd; /* target program to attach to */ + __u32 tgt_btf_id; /* BTF ID of target function */ +}; +#define bpf_raw_tracepoint_opts__last_field tgt_btf_id + LIBBPF_API int bpf_raw_tracepoint_open(const char *name, int prog_fd); +LIBBPF_API int bpf_raw_tracepoint_open_opts(const char *name, int prog_fd, + struct bpf_raw_tracepoint_opts *opts); LIBBPF_API int bpf_load_btf(void *btf, __u32 btf_size, char *log_buf, __u32 log_buf_size, bool do_log); LIBBPF_API int bpf_task_fd_query(int pid, int fd, __u32 flags, char *buf, diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map index 6544d2cd1ed6..f726805f5ec8 100644 --- a/tools/lib/bpf/libbpf.map +++ b/tools/lib/bpf/libbpf.map @@ -288,4 +288,5 @@ LIBBPF_0.1.0 { bpf_map__value_size; bpf_program__autoload; bpf_program__set_autoload; + bpf_raw_tracepoint_open_opts; } LIBBPF_0.0.9; From patchwork Mon Jul 13 20:12:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= X-Patchwork-Id: 1328448 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=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=QnWb5tzS; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4B5FF15hB4z9sRR for ; Tue, 14 Jul 2020 06:12:37 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726942AbgGMUMg (ORCPT ); Mon, 13 Jul 2020 16:12:36 -0400 Received: from us-smtp-1.mimecast.com ([207.211.31.81]:47770 "EHLO us-smtp-delivery-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726898AbgGMUMe (ORCPT ); Mon, 13 Jul 2020 16:12:34 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1594671152; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=vTIQaOPIQ+MaCndHFRhBSVSQrsv7BpdyNa0iaL4KcwE=; b=QnWb5tzSAt/38d2Caqzp1F2Re0pcyChCUgAA3Egp4TQqfG5cPtcDCjajT9caV//g0DC4HX P5wb4Jjvvn4RXkvYUO4mPiZ/ycmAQR5AEPE17mVLv4Xupey67j/N8J7oPbMOXCtm/4UYWa ao3wyczCZqQ5r9Aa+RQ7vC3piG5vA74= Received: from mail-qt1-f200.google.com (mail-qt1-f200.google.com [209.85.160.200]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-367-qZH0kP8MMNulz9QFsLSBQw-1; Mon, 13 Jul 2020 16:12:30 -0400 X-MC-Unique: qZH0kP8MMNulz9QFsLSBQw-1 Received: by mail-qt1-f200.google.com with SMTP id d45so10948098qte.12 for ; Mon, 13 Jul 2020 13:12:30 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:from:to:cc:date:message-id:in-reply-to :references:user-agent:mime-version:content-transfer-encoding; bh=vTIQaOPIQ+MaCndHFRhBSVSQrsv7BpdyNa0iaL4KcwE=; b=bDsxlQcFtxk31cDVBL9FyCLawjkB5Igfv+xBrDTpJ+um21rGG2K1+nqtLGYiotVnRG nJ4L+SeY8ALXI0HZUgncB7QzqwTkrY5fxYouRwJcCIzS4OzX+hd3Wg3eNlmt9HNM3BxH 7Kln7PWs/7wWDL2FjgQ8+trHfiuCTE45mRlHfzK38bKLaM8I0IVFr55NKZRRnDtZtH0k bH8yep8Exvfl7zkQu+bdOKC0WTltlGPNM3WpPDxZdhzFd5kgm1Okw2BkqH81bdkJoY/a Ktc4RtlZuj2O8SsCDDA0EYX3vg6I6vSRgS12A7Lg0W1jMi4PgbF7FCyIfckUGWxtupjl C+6g== X-Gm-Message-State: AOAM533nYhiZvOKVSl9ZKkj7ad+v8+EXF9+ZLk8bf3kU7/urLSVBQvSa FLxQn4fV8Zodsst2U16NPLPok8aB3Pu/SzkIp4/3kHqg+xdS4dSVNSXiJBGfnctXoMb6NaC98zr Zq3tzP92+JwbffnVr X-Received: by 2002:a37:27d3:: with SMTP id n202mr1284503qkn.95.1594671149818; Mon, 13 Jul 2020 13:12:29 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxkhVhM5EO8L7DniR0AoGbGc/Ta0NnTHf3EpE/4+IZeDr1C7+lZJC0hGRzBzUJufUV3AxyBig== X-Received: by 2002:a37:27d3:: with SMTP id n202mr1284483qkn.95.1594671149466; Mon, 13 Jul 2020 13:12:29 -0700 (PDT) Received: from alrua-x1.borgediget.toke.dk ([45.145.92.2]) by smtp.gmail.com with ESMTPSA id 16sm19015248qkn.106.2020.07.13.13.12.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 13 Jul 2020 13:12:27 -0700 (PDT) Received: by alrua-x1.borgediget.toke.dk (Postfix, from userid 1000) id 49E4F180653; Mon, 13 Jul 2020 22:12:26 +0200 (CEST) Subject: [PATCH bpf-next 6/6] selftests: add test for multiple attachments of freplace program From: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= To: Alexei Starovoitov Cc: Daniel Borkmann , Martin KaFai Lau , Song Liu , Yonghong Song , Andrii Nakryiko , John Fastabend , KP Singh , netdev@vger.kernel.org, bpf@vger.kernel.org Date: Mon, 13 Jul 2020 22:12:26 +0200 Message-ID: <159467114624.370286.16399454779226567555.stgit@toke.dk> In-Reply-To: <159467113970.370286.17656404860101110795.stgit@toke.dk> References: <159467113970.370286.17656404860101110795.stgit@toke.dk> User-Agent: StGit/0.23 MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Toke Høiland-Jørgensen This adds a selftest for attaching an freplace program to multiple targets simultaneously. Signed-off-by: Toke Høiland-Jørgensen --- .../selftests/bpf/prog_tests/fexit_bpf2bpf.c | 174 +++++++++++++++++--- .../selftests/bpf/progs/freplace_get_constant.c | 15 ++ 2 files changed, 160 insertions(+), 29 deletions(-) create mode 100644 tools/testing/selftests/bpf/progs/freplace_get_constant.c diff --git a/tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c b/tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c index a895bfed55db..60cf3e44a6ef 100644 --- a/tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c +++ b/tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c @@ -2,35 +2,78 @@ /* Copyright (c) 2019 Facebook */ #include #include +#include + +typedef int (*test_cb)(struct bpf_object *obj); + +static int check_data_map(struct bpf_object *obj, int prog_cnt, bool reset) +{ + struct bpf_map *data_map, *map; + const int zero = 0; + u64 *result = NULL; + __u32 duration = 0; + int ret = -1, i; + + result = malloc((prog_cnt + 32 /* spare */) * sizeof(u64)); + if (CHECK(!result, "alloc_memory", "failed to alloc memory")) + return -ENOMEM; + + bpf_object__for_each_map(map, obj) + if (bpf_map__is_internal(map)) { + data_map = map; + break; + } + if (CHECK(!data_map, "find_data_map", "data map not found\n")) + goto out; + + ret = bpf_map_lookup_elem(bpf_map__fd(data_map), &zero, result); + if (CHECK(ret, "get_result", + "failed to get output data: %d\n", ret)) + goto out; + + for (i = 0; i < prog_cnt; i++) { + if (CHECK(result[i] != 1, "result", "fexit_bpf2bpf failed err %ld\n", + result[i])) + goto out; + result[i] = 0; + } + if (reset) { + ret = bpf_map_update_elem(bpf_map__fd(data_map), &zero, result, 0); + if (CHECK(ret, "reset_result", "failed to reset result\n")) + goto out; + } + + ret = 0; +out: + free(result); + return ret; +} static void test_fexit_bpf2bpf_common(const char *obj_file, const char *target_obj_file, int prog_cnt, const char **prog_name, - bool run_prog) + bool run_prog, + test_cb cb) { - struct bpf_object *obj = NULL, *pkt_obj; - int err, pkt_fd, i; + struct bpf_object *obj = NULL, *tgt_obj; + int err, tgt_fd, i; struct bpf_link **link = NULL; struct bpf_program **prog = NULL; __u32 duration = 0, retval; - struct bpf_map *data_map; - const int zero = 0; - u64 *result = NULL; err = bpf_prog_load(target_obj_file, BPF_PROG_TYPE_UNSPEC, - &pkt_obj, &pkt_fd); + &tgt_obj, &tgt_fd); if (CHECK(err, "tgt_prog_load", "file %s err %d errno %d\n", target_obj_file, err, errno)) return; DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts, - .attach_prog_fd = pkt_fd, + .attach_prog_fd = tgt_fd, ); link = calloc(sizeof(struct bpf_link *), prog_cnt); prog = calloc(sizeof(struct bpf_program *), prog_cnt); - result = malloc((prog_cnt + 32 /* spare */) * sizeof(u64)); - if (CHECK(!link || !prog || !result, "alloc_memory", + if (CHECK(!link || !prog, "alloc_memory", "failed to alloc memory")) goto close_prog; @@ -53,39 +96,33 @@ static void test_fexit_bpf2bpf_common(const char *obj_file, goto close_prog; } - if (!run_prog) - goto close_prog; + if (cb) { + err = cb(obj); + if (err) + goto close_prog; + } - data_map = bpf_object__find_map_by_name(obj, "fexit_bp.bss"); - if (CHECK(!data_map, "find_data_map", "data map not found\n")) + if (!run_prog) goto close_prog; - err = bpf_prog_test_run(pkt_fd, 1, &pkt_v6, sizeof(pkt_v6), + err = bpf_prog_test_run(tgt_fd, 1, &pkt_v6, sizeof(pkt_v6), NULL, NULL, &retval, &duration); CHECK(err || retval, "ipv6", "err %d errno %d retval %d duration %d\n", err, errno, retval, duration); - err = bpf_map_lookup_elem(bpf_map__fd(data_map), &zero, result); - if (CHECK(err, "get_result", - "failed to get output data: %d\n", err)) + if (check_data_map(obj, prog_cnt, false)) goto close_prog; - for (i = 0; i < prog_cnt; i++) - if (CHECK(result[i] != 1, "result", "fexit_bpf2bpf failed err %ld\n", - result[i])) - goto close_prog; - close_prog: for (i = 0; i < prog_cnt; i++) if (!IS_ERR_OR_NULL(link[i])) bpf_link__destroy(link[i]); if (!IS_ERR_OR_NULL(obj)) bpf_object__close(obj); - bpf_object__close(pkt_obj); + bpf_object__close(tgt_obj); free(link); free(prog); - free(result); } static void test_target_no_callees(void) @@ -96,7 +133,7 @@ static void test_target_no_callees(void) test_fexit_bpf2bpf_common("./fexit_bpf2bpf_simple.o", "./test_pkt_md_access.o", ARRAY_SIZE(prog_name), - prog_name, true); + prog_name, true, NULL); } static void test_target_yes_callees(void) @@ -110,7 +147,7 @@ static void test_target_yes_callees(void) test_fexit_bpf2bpf_common("./fexit_bpf2bpf.o", "./test_pkt_access.o", ARRAY_SIZE(prog_name), - prog_name, true); + prog_name, true, NULL); } static void test_func_replace(void) @@ -127,7 +164,7 @@ static void test_func_replace(void) test_fexit_bpf2bpf_common("./fexit_bpf2bpf.o", "./test_pkt_access.o", ARRAY_SIZE(prog_name), - prog_name, true); + prog_name, true, NULL); } static void test_func_replace_verify(void) @@ -138,7 +175,85 @@ static void test_func_replace_verify(void) test_fexit_bpf2bpf_common("./freplace_connect4.o", "./connect4_prog.o", ARRAY_SIZE(prog_name), - prog_name, false); + prog_name, false, NULL); +} + +static int test_second_attach(struct bpf_object *obj) +{ + const char *prog_name = "freplace/get_constant"; + const char *tgt_name = prog_name + 9; /* cut off freplace/ */ + const char *tgt_obj_file = "./test_pkt_access.o"; + int err = 0, tgt_fd, tgt_btf_id, link_fd = -1; + struct bpf_program *prog = NULL; + struct bpf_object *tgt_obj; + __u32 duration = 0, retval; + size_t log_buf_sz = 1024; + char *log_buf = NULL; + struct btf *btf; + + prog = bpf_object__find_program_by_title(obj, prog_name); + if (CHECK(!prog, "find_prog", "prog %s not found\n", prog_name)) + return -ENOENT; + + log_buf = calloc(log_buf_sz, 1); + if (!log_buf) + return -ENOMEM; + + err = bpf_prog_load(tgt_obj_file, BPF_PROG_TYPE_UNSPEC, + &tgt_obj, &tgt_fd); + if (CHECK(err, "second_prog_load", "file %s err %d errno %d\n", + tgt_obj_file, err, errno)) + return err; + + btf = bpf_object__btf(tgt_obj); + tgt_btf_id = btf__find_by_name_kind(btf, tgt_name, BTF_KIND_FUNC); + if (CHECK(tgt_btf_id < 0, "find_btf", "no BTF ID found for func %s\n", prog_name)) { + err = -ENOENT; + goto out; + } + + DECLARE_LIBBPF_OPTS(bpf_raw_tracepoint_opts, opts, + .tgt_prog_fd = tgt_fd, + .tgt_btf_id = tgt_btf_id, + .log_buf = log_buf, + .log_buf_sz = log_buf_sz, + .log_level = 7, + ); + link_fd = bpf_raw_tracepoint_open_opts(NULL, bpf_program__fd(prog), &opts); + if (CHECK(link_fd < 0, "second_link", "err %d errno %d log %s", + link_fd, errno, log_buf)) { + err = link_fd; + goto out; + } + + err = bpf_prog_test_run(tgt_fd, 1, &pkt_v6, sizeof(pkt_v6), + NULL, NULL, &retval, &duration); + if (CHECK(err || retval, "ipv6", + "err %d errno %d retval %d duration %d\n", + err, errno, retval, duration)) + goto out; + + err = check_data_map(obj, 1, true); + if (err) + goto out; + +out: + if (link_fd >= 0) + close(link_fd); + bpf_object__close(tgt_obj); + free(log_buf); + return err; +} + +static void test_func_replace_multi(void) +{ + const char *prog_name[] = { + "freplace/get_constant", + }; + test_fexit_bpf2bpf_common("./freplace_get_constant.o", + "./test_pkt_access.o", + ARRAY_SIZE(prog_name), + prog_name, true, test_second_attach); } void test_fexit_bpf2bpf(void) @@ -147,4 +262,5 @@ void test_fexit_bpf2bpf(void) test_target_yes_callees(); test_func_replace(); test_func_replace_verify(); + test_func_replace_multi(); } diff --git a/tools/testing/selftests/bpf/progs/freplace_get_constant.c b/tools/testing/selftests/bpf/progs/freplace_get_constant.c new file mode 100644 index 000000000000..8f0ecf94e533 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/freplace_get_constant.c @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include + +volatile __u64 test_get_constant = 0; +SEC("freplace/get_constant") +int new_get_constant(long val) +{ + if (val != 123) + return 0; + test_get_constant = 1; + return test_get_constant; /* original get_constant() returns val - 122 */ +} +char _license[] SEC("license") = "GPL";