From patchwork Tue Feb 12 23:42:38 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Fomichev X-Patchwork-Id: 1040911 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=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="hqdvbI2r"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43zfN55xw6z9sML for ; Wed, 13 Feb 2019 10:42:45 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732323AbfBLXmo (ORCPT ); Tue, 12 Feb 2019 18:42:44 -0500 Received: from mail-it1-f202.google.com ([209.85.166.202]:40160 "EHLO mail-it1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731318AbfBLXmn (ORCPT ); Tue, 12 Feb 2019 18:42:43 -0500 Received: by mail-it1-f202.google.com with SMTP id 135so885082itk.5 for ; Tue, 12 Feb 2019 15:42:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:message-id:mime-version:subject:from:to:cc; bh=hVNXhfUgyDln/acD8TPHun7ZObubPshN7ZpZWEULSiY=; b=hqdvbI2rABuXkK4Qwk29d73NTB4rGqZCY3o3bdmHhMyMqZY8AZC4UMhNOEJaoYvrrt wyDMTOKCcbhbs58+2bEqcKnyxcfX6slE0b9XGEHj3miRT/IS7PEkoq+T0c8FsF8eMuwM 85TmGiE17fjyvgTOz/EvGdqxnMnDRqa8KKA9QDIGIh/xz31vNRAgwCXxa8NvMZZmkp1v 9ib14XCBgmGAQI2b355iu3xMQ5cpjhmyFWdwDbt0oKsNGlswfPg4gwv/xO8MfA8BEU5Z LOMm0ji4BUmH0t1+Q60oAMELsnsSkSCBRGf4LYVE3H7Wcnl0Y/G3hdWY4xHejU+udClH euQA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:message-id:mime-version:subject:from:to:cc; bh=hVNXhfUgyDln/acD8TPHun7ZObubPshN7ZpZWEULSiY=; b=qv+WCael4kgMGXamMUWpjFn8n1KAxWqdR0CG056pseEEv5cAD4BoY+gXRZtcdz0Sab 2n/4u/gJCZgQK8JhwMXz484Yh9DUUP8mWU4zE5KY9CKR3u55Q6bsPHgnSrSscqlcPsL1 g9Skg7YW3Bl8EEuyOK9RAL068VvXbITh4ZrJs/AKNmjS84HKs8ZDOj0bHy/glSDbzwl/ cSjkypzZMjMn69pDtEPXdtL+UVrT0Y36CiofKtgIIKKQD04deWqrPGYytZi+SrGDGbbQ n2f+VfI4DukklujtOaftT80WnhawZ+QEV1wTj6KOw1wV/dKTphbpKEqc80Kz3wQjGGA6 HQog== X-Gm-Message-State: AHQUAua/Qv61oQyLMwkBixPv4n4VbcrraWamFP8oZLj7L8Kf3v1z0ysL M6Z93oNGiE2j7qcnDonlEDLtdT5CVhpzL5qa6GA2uo/drXkaREw6t9ukAbLf7mdiF9oALtjaxFG ypB9jmjcx+I4t95OdTajk7gGHl7m3LjNkS3qTwGLiuQyDTP+aPLFW8Q== X-Google-Smtp-Source: AHgI3IY4kgoGTTGNHlExrZXkcUrGn7u+anamrAGftggWZuvHdGDbxx4tV5ZbuHuHwOPIFzCsTC2gwkA= X-Received: by 2002:a24:7084:: with SMTP id f126mr842114itc.32.1550014962431; Tue, 12 Feb 2019 15:42:42 -0800 (PST) Date: Tue, 12 Feb 2019 15:42:38 -0800 Message-Id: <20190212234239.174386-1-sdf@google.com> Mime-Version: 1.0 X-Mailer: git-send-email 2.20.1.791.gb4d0f1c61a-goog Subject: [PATCH bpf 1/2] bpf/test_run: fix unkillable BPF_PROG_TEST_RUN From: Stanislav Fomichev To: netdev@vger.kernel.org Cc: davem@davemloft.net, ast@kernel.org, daniel@iogearbox.net, Stanislav Fomichev , syzbot Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Syzbot found out that running BPF_PROG_TEST_RUN with repeat=0xffffffff makes process unkillable. The problem is that when CONFIG_PREEMPT is enabled, we never see need_resched() return true. This is due to the fact that preempt_enable() (which we do in bpf_test_run_one on each iteration) now handles resched if it's needed. Let's disable preemption for the whole run, not per test. In this case we can properly see whether resched is needed. Let's also properly return -EINTR to the userspace in case of a signal interrupt. See recent discussion: http://lore.kernel.org/netdev/CAH3MdRWHr4N8jei8jxDppXjmw-Nw=puNDLbu1dQOFQHxfU2onA@mail.gmail.com I'll follow up with the same fix bpf_prog_test_run_flow_dissector in bpf-next. Reported-by: syzbot Signed-off-by: Stanislav Fomichev --- net/bpf/test_run.c | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c index fa2644d276ef..e31e1b20f7f4 100644 --- a/net/bpf/test_run.c +++ b/net/bpf/test_run.c @@ -13,27 +13,13 @@ #include #include -static __always_inline u32 bpf_test_run_one(struct bpf_prog *prog, void *ctx, - struct bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE]) -{ - u32 ret; - - preempt_disable(); - rcu_read_lock(); - bpf_cgroup_storage_set(storage); - ret = BPF_PROG_RUN(prog, ctx); - rcu_read_unlock(); - preempt_enable(); - - return ret; -} - -static int bpf_test_run(struct bpf_prog *prog, void *ctx, u32 repeat, u32 *ret, - u32 *time) +static int bpf_test_run(struct bpf_prog *prog, void *ctx, u32 repeat, + u32 *retval, u32 *time) { struct bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE] = { 0 }; enum bpf_cgroup_storage_type stype; u64 time_start, time_spent = 0; + int ret = 0; u32 i; for_each_cgroup_storage_type(stype) { @@ -48,25 +34,42 @@ static int bpf_test_run(struct bpf_prog *prog, void *ctx, u32 repeat, u32 *ret, if (!repeat) repeat = 1; + + rcu_read_lock(); + preempt_disable(); time_start = ktime_get_ns(); for (i = 0; i < repeat; i++) { - *ret = bpf_test_run_one(prog, ctx, storage); + bpf_cgroup_storage_set(storage); + *retval = BPF_PROG_RUN(prog, ctx); + + if (signal_pending(current)) { + ret = -EINTR; + break; + } + if (need_resched()) { - if (signal_pending(current)) - break; time_spent += ktime_get_ns() - time_start; + preempt_enable(); + rcu_read_unlock(); + cond_resched(); + + rcu_read_lock(); + preempt_disable(); time_start = ktime_get_ns(); } } time_spent += ktime_get_ns() - time_start; + preempt_enable(); + rcu_read_unlock(); + do_div(time_spent, repeat); *time = time_spent > U32_MAX ? U32_MAX : (u32)time_spent; for_each_cgroup_storage_type(stype) bpf_cgroup_storage_free(storage[stype]); - return 0; + return ret; } static int bpf_test_finish(const union bpf_attr *kattr,