From patchwork Tue Jan 8 06:16:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "zhangxiaoxu (A)" X-Patchwork-Id: 1021750 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=huawei.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43Yhln4Lkgz9sLw for ; Tue, 8 Jan 2019 17:13:41 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727768AbfAHGNi (ORCPT ); Tue, 8 Jan 2019 01:13:38 -0500 Received: from szxga06-in.huawei.com ([45.249.212.32]:41050 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727657AbfAHGNi (ORCPT ); Tue, 8 Jan 2019 01:13:38 -0500 Received: from DGGEMS412-HUB.china.huawei.com (unknown [172.30.72.59]) by Forcepoint Email with ESMTP id 3798B6EAF0B582753F0D; Tue, 8 Jan 2019 14:13:33 +0800 (CST) Received: from RH5885H-V3.huawei.com (10.90.53.225) by DGGEMS412-HUB.china.huawei.com (10.3.19.212) with Microsoft SMTP Server id 14.3.408.0; Tue, 8 Jan 2019 14:13:27 +0800 From: ZhangXiaoxu To: , Subject: [PATCH] bpf: fix shift overflow in ___bpf_prog_run Date: Tue, 8 Jan 2019 14:16:59 +0800 Message-ID: <1546928219-120176-1-git-send-email-zhangxiaoxu5@huawei.com> X-Mailer: git-send-email 2.7.4 MIME-Version: 1.0 X-Originating-IP: [10.90.53.225] X-CFilter-Loop: Reflected Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Zhang Xiaoxu There is a UBSAN bug as blew: UBSAN: Undefined behaviour in kernel/bpf/core.c:1055:2 shift exponent 511 is too large for 32-bit type 'unsigned int' Reproduce program: #include #include #include #include #include #include #include #include #include #include int main() { struct sock_filter sock_filter[3] = { BPF_JUMP(BPF_LDX|BPF_IMM, 0x1ff, 0x2, 0xfffffffffffffffd), BPF_JUMP(BPF_ALU|BPF_LSH|BPF_X, 0x0, 0x506, 0x401), BPF_JUMP(BPF_RET|BPF_K, 0x0, 0x0, SECCOMP_RET_KILL) }; struct sock_fprog sock_fprog= { .len = 3, .filter = &sock_filter, }; int ret = syscall(__NR_seccomp, SECCOMP_SET_MODE_FILTER, 0, &sock_fprog); printf("%d\n", ret); return 0; } Make sure the right operand not greater than or equal to the width of the promoted left operand when do shift operation. Signed-off-by: ZhangXiaoxu --- kernel/bpf/core.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index 503d421..7635557 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -683,11 +683,26 @@ static unsigned int __bpf_prog_run(void *ctx, const struct bpf_insn *insn) ALU(SUB, -) ALU(AND, &) ALU(OR, |) - ALU(LSH, <<) - ALU(RSH, >>) ALU(XOR, ^) ALU(MUL, *) #undef ALU +#define ALU_SHIFT(OPCODE, OP) \ + ALU64_##OPCODE##_X: \ + DST = DST OP (SRC & 0x3F); \ + CONT; \ + ALU_##OPCODE##_X: \ + DST = (u32) DST OP (SRC & 0x1F);\ + CONT; \ + ALU64_##OPCODE##_K: \ + DST = DST OP (IMM & 0x3F); \ + CONT; \ + ALU_##OPCODE##_K: \ + DST = (u32) DST OP (IMM & 0x1F);\ + CONT; + + ALU_SHIFT(LSH, <<) + ALU_SHIFT(RSH, >>) +#undef ALU_SHIFT ALU_NEG: DST = (u32) -DST; CONT;