From patchwork Wed May 9 21:07:03 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joe Stringer X-Patchwork-Id: 911187 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="NFqqOm7n"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40h87p1Vwdz9s37 for ; Thu, 10 May 2018 07:07:34 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965615AbeEIVHb (ORCPT ); Wed, 9 May 2018 17:07:31 -0400 Received: from mail-oi0-f66.google.com ([209.85.218.66]:40965 "EHLO mail-oi0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S964849AbeEIVH3 (ORCPT ); Wed, 9 May 2018 17:07:29 -0400 Received: by mail-oi0-f66.google.com with SMTP id 11-v6so32774241ois.8 for ; Wed, 09 May 2018 14:07:28 -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=KDrin75lf3+mGs/iYEynz2+1qgYhsimtCYxdf6eNRtE=; b=NFqqOm7naGhz+3Fk26E/93dfwz+Efurzxsrn23xyS0X3/rA699A85sGwRfIYNWdzpc 1cv7EHibPBmxlWFH8RjlOcGDL0frlg6+8Cukhvue4490X2ra5rGQ3qhKJMnv7hqcWKxt dczBHA/e/PRxkmT6U9qASjelfTOipEe6vgc2teBYXsKfUIW6SHcKxNtoSiXTFBh9iOGk oW+o1idaIlFvK02okmONzyrE+XKDWbbrNeLoqTWkcxwwZliyIdhnGeRV2qGoOnbRCQys my39PnhRy1gbCFdwhIzELDR9F7Mr2xR9mVPOTtpyYB5Bef+OYmKU988iw9qpL1q7cdyX 41ig== 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=KDrin75lf3+mGs/iYEynz2+1qgYhsimtCYxdf6eNRtE=; b=E7KxpL5J/3QndsABUJwReG5TG2SA7QsUrIcJE76KO6XVB8RnyJMRQrWFrQz3pKuv3a ICKyD0nKozJcquw9mJmKzuZVI/HnkffxG5zU4qKswVuv8/VSZYxxSrlU9PhGm19Q34hp nfSSmZro7YYiv8wLJP95HiDmec7aQgSc0SfQbLMHEuCIZbW62/zdzUKUtxL3eK1gKQE4 AEaWeluj7gAXMGb8pAwEZoMiTHCNCqNhzGIOSZn09BMOvnIrghMVE6L3+Xe2NdI0CamI gq03+VCanJlvXFpFW75+yywRUS7UDSF7mIENDKh89XZpVzpOeKNMzrmqBPYJhjh2aXdM j4DQ== X-Gm-Message-State: ALQs6tAhakQhSz7oEpymyJYEMcUuu9r1B4GZmO5EhOIiN7me6oH/MOpT yR/dy91Jk7fm15qcx0Dz2NA= X-Google-Smtp-Source: AB8JxZrPYBpHS/n4k+0dVZ/jZVsFUHD7akLguGA3NOogHx+ETX58X3Na75EJ9ha/vPhy2UdAIHt2/Q== X-Received: by 2002:aca:681:: with SMTP id 123-v6mr20598816oig.358.1525900048315; Wed, 09 May 2018 14:07:28 -0700 (PDT) Received: from allosaurus.lan ([99.0.85.34]) by smtp.gmail.com with ESMTPSA id h125-v6sm13612921oic.54.2018.05.09.14.07.27 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 09 May 2018 14:07:27 -0700 (PDT) From: Joe Stringer To: daniel@iogearbox.net Cc: netdev@vger.kernel.org, ast@kernel.org, john.fastabend@gmail.com, kafai@fb.com Subject: [RFC bpf-next 05/11] bpf: Macrofy stack state copy Date: Wed, 9 May 2018 14:07:03 -0700 Message-Id: <20180509210709.7201-6-joe@wand.net.nz> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180509210709.7201-1-joe@wand.net.nz> References: <20180509210709.7201-1-joe@wand.net.nz> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org An upcoming commit will need very similar copy/realloc boilerplate, so refactor the existing stack copy/realloc functions into macros to simplify it. Signed-off-by: Joe Stringer --- kernel/bpf/verifier.c | 104 ++++++++++++++++++++++++++++---------------------- 1 file changed, 59 insertions(+), 45 deletions(-) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index d38c7c1e9da6..f426ebf2b6bf 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -347,60 +347,74 @@ static void print_verifier_state(struct bpf_verifier_env *env, verbose(env, "\n"); } -static int copy_stack_state(struct bpf_func_state *dst, - const struct bpf_func_state *src) -{ - if (!src->stack) - return 0; - if (WARN_ON_ONCE(dst->allocated_stack < src->allocated_stack)) { - /* internal bug, make state invalid to reject the program */ - memset(dst, 0, sizeof(*dst)); - return -EFAULT; - } - memcpy(dst->stack, src->stack, - sizeof(*src->stack) * (src->allocated_stack / BPF_REG_SIZE)); - return 0; -} +#define COPY_STATE_FN(NAME, COUNT, FIELD, SIZE) \ +static int copy_##NAME##_state(struct bpf_func_state *dst, \ + const struct bpf_func_state *src) \ +{ \ + if (!src->FIELD) \ + return 0; \ + if (WARN_ON_ONCE(dst->COUNT < src->COUNT)) { \ + /* internal bug, make state invalid to reject the program */ \ + memset(dst, 0, sizeof(*dst)); \ + return -EFAULT; \ + } \ + memcpy(dst->FIELD, src->FIELD, \ + sizeof(*src->FIELD) * (src->COUNT / SIZE)); \ + return 0; \ +} +/* copy_stack_state() */ +COPY_STATE_FN(stack, allocated_stack, stack, BPF_REG_SIZE) +#undef COPY_STATE_FN + +#define REALLOC_STATE_FN(NAME, COUNT, FIELD, SIZE) \ +static int realloc_##NAME##_state(struct bpf_func_state *state, int size, \ + bool copy_old) \ +{ \ + u32 old_size = state->COUNT; \ + struct bpf_##NAME##_state *new_##FIELD; \ + int slot = size / SIZE; \ + \ + if (size <= old_size || !size) { \ + if (copy_old) \ + return 0; \ + state->COUNT = slot * SIZE; \ + if (!size && old_size) { \ + kfree(state->FIELD); \ + state->FIELD = NULL; \ + } \ + return 0; \ + } \ + new_##FIELD = kmalloc_array(slot, sizeof(struct bpf_##NAME##_state), \ + GFP_KERNEL); \ + if (!new_##FIELD) \ + return -ENOMEM; \ + if (copy_old) { \ + if (state->FIELD) \ + memcpy(new_##FIELD, state->FIELD, \ + sizeof(*new_##FIELD) * (old_size / SIZE)); \ + memset(new_##FIELD + old_size / SIZE, 0, \ + sizeof(*new_##FIELD) * (size - old_size) / SIZE); \ + } \ + state->COUNT = slot * SIZE; \ + kfree(state->FIELD); \ + state->FIELD = new_##FIELD; \ + return 0; \ +} +/* realloc_stack_state() */ +REALLOC_STATE_FN(stack, allocated_stack, stack, BPF_REG_SIZE) +#undef REALLOC_STATE_FN /* do_check() starts with zero-sized stack in struct bpf_verifier_state to * make it consume minimal amount of memory. check_stack_write() access from * the program calls into realloc_func_state() to grow the stack size. * Note there is a non-zero 'parent' pointer inside bpf_verifier_state - * which this function copies over. It points to previous bpf_verifier_state - * which is never reallocated + * which realloc_stack_state() copies over. It points to previous + * bpf_verifier_state which is never reallocated. */ static int realloc_func_state(struct bpf_func_state *state, int size, bool copy_old) { - u32 old_size = state->allocated_stack; - struct bpf_stack_state *new_stack; - int slot = size / BPF_REG_SIZE; - - if (size <= old_size || !size) { - if (copy_old) - return 0; - state->allocated_stack = slot * BPF_REG_SIZE; - if (!size && old_size) { - kfree(state->stack); - state->stack = NULL; - } - return 0; - } - new_stack = kmalloc_array(slot, sizeof(struct bpf_stack_state), - GFP_KERNEL); - if (!new_stack) - return -ENOMEM; - if (copy_old) { - if (state->stack) - memcpy(new_stack, state->stack, - sizeof(*new_stack) * (old_size / BPF_REG_SIZE)); - memset(new_stack + old_size / BPF_REG_SIZE, 0, - sizeof(*new_stack) * (size - old_size) / BPF_REG_SIZE); - } - state->allocated_stack = slot * BPF_REG_SIZE; - kfree(state->stack); - state->stack = new_stack; - return 0; + return realloc_stack_state(state, size, copy_old); } static void free_func_state(struct bpf_func_state *state)