From patchwork Fri Dec 7 11:44:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?QmrDtnJuIFTDtnBlbA==?= X-Patchwork-Id: 1009384 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=fail (p=none dis=none) header.from=gmail.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43B9d55LgKz9rxp for ; Fri, 7 Dec 2018 22:45:13 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726105AbeLGLpM (ORCPT ); Fri, 7 Dec 2018 06:45:12 -0500 Received: from mga04.intel.com ([192.55.52.120]:49448 "EHLO mga04.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726022AbeLGLpM (ORCPT ); Fri, 7 Dec 2018 06:45:12 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 07 Dec 2018 03:45:12 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,326,1539673200"; d="scan'208";a="96922235" Received: from yhameiri-mobl1.ger.corp.intel.com (HELO btopel-mobl.ger.intel.com) ([10.255.41.173]) by orsmga007.jf.intel.com with ESMTP; 07 Dec 2018 03:45:08 -0800 From: =?utf-8?b?QmrDtnJuIFTDtnBlbA==?= To: bjorn.topel@gmail.com, magnus.karlsson@intel.com, magnus.karlsson@gmail.com, ast@kernel.org, daniel@iogearbox.net, netdev@vger.kernel.org Cc: =?utf-8?b?QmrDtnJuIFTDtnBlbA==?= , brouer@redhat.com, u9012063@gmail.com, qi.z.zhang@intel.com Subject: [PATCH bpf-next 5/7] bpf: add function to load builtin BPF program Date: Fri, 7 Dec 2018 12:44:29 +0100 Message-Id: <20181207114431.18038-6-bjorn.topel@gmail.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181207114431.18038-1-bjorn.topel@gmail.com> References: <20181207114431.18038-1-bjorn.topel@gmail.com> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Björn Töpel The added bpf_prog_load_builtin can be used to load and verify a BPF program that originates from the kernel. We call this a "builtin BPF program". A builtin program can be used for convenience, e.g. it allows for the kernel to use the bpf infrastructure for internal tasks. This functionality will be used by AF_XDP sockets in a later commit. Signed-off-by: Björn Töpel --- include/linux/bpf.h | 2 ++ kernel/bpf/syscall.c | 32 ++++++++++++++++++++++++-------- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/include/linux/bpf.h b/include/linux/bpf.h index e82b7039fc66..e810bfeb6239 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -563,6 +563,8 @@ static inline int bpf_map_attr_numa_node(const union bpf_attr *attr) struct bpf_prog *bpf_prog_get_type_path(const char *name, enum bpf_prog_type type); int array_map_alloc_check(union bpf_attr *attr); +struct bpf_prog *bpf_prog_load_builtin(union bpf_attr *attr); + #else /* !CONFIG_BPF_SYSCALL */ static inline struct bpf_prog *bpf_prog_get(u32 ufd) { diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index ee1328625330..323831e1a1e2 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -1461,10 +1461,16 @@ static struct bpf_prog *__bpf_prog_load(union bpf_attr *attr, !capable(CAP_SYS_ADMIN)) return ERR_PTR(-EPERM); - /* copy eBPF program license from user space */ - if (strncpy_from_user(license, u64_to_user_ptr(attr->license), - sizeof(license) - 1) < 0) - return ERR_PTR(-EFAULT); + /* NB! If uattr is NULL, a builtin BPF is being loaded. */ + if (uattr) { + /* copy eBPF program license from user space */ + if (strncpy_from_user(license, u64_to_user_ptr(attr->license), + sizeof(license) - 1) < 0) + return ERR_PTR(-EFAULT); + } else { + strncpy(license, (const char *)(unsigned long)attr->license, + sizeof(license) - 1); + } license[sizeof(license) - 1] = 0; /* eBPF programs must be GPL compatible to use GPL-ed functions */ @@ -1505,10 +1511,15 @@ static struct bpf_prog *__bpf_prog_load(union bpf_attr *attr, prog->len = attr->insn_cnt; - err = -EFAULT; - if (copy_from_user(prog->insns, u64_to_user_ptr(attr->insns), - bpf_prog_insn_size(prog)) != 0) - goto free_prog; + if (uattr) { + err = -EFAULT; + if (copy_from_user(prog->insns, u64_to_user_ptr(attr->insns), + bpf_prog_insn_size(prog)) != 0) + goto free_prog; + } else { + memcpy(prog->insns, (void *)(unsigned long)attr->insns, + bpf_prog_insn_size(prog)); + } prog->orig_prog = NULL; prog->jited = 0; @@ -1584,6 +1595,11 @@ static int bpf_prog_load(union bpf_attr *attr, union bpf_attr __user *uattr) return fd; } +struct bpf_prog *bpf_prog_load_builtin(union bpf_attr *attr) +{ + return __bpf_prog_load(attr, NULL); +} + #define BPF_OBJ_LAST_FIELD file_flags static int bpf_obj_pin(const union bpf_attr *attr)