From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4A516C43387 for ; Thu, 17 Jan 2019 00:21:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 21C0A206C2 for ; Thu, 17 Jan 2019 00:21:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728434AbfAQAVj (ORCPT ); Wed, 16 Jan 2019 19:21:39 -0500 Received: from www62.your-server.de ([213.133.104.62]:50244 "EHLO www62.your-server.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728247AbfAQAVj (ORCPT ); Wed, 16 Jan 2019 19:21:39 -0500 Received: from [78.46.172.2] (helo=sslproxy05.your-server.de) by www62.your-server.de with esmtpsa (TLSv1.2:DHE-RSA-AES256-GCM-SHA384:256) (Exim 4.89_1) (envelope-from ) id 1gjvR7-0007Ur-Kx; Thu, 17 Jan 2019 01:21:33 +0100 Received: from [178.197.248.17] (helo=linux.home) by sslproxy05.your-server.de with esmtpsa (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.89) (envelope-from ) id 1gjvR7-0007wq-Ex; Thu, 17 Jan 2019 01:21:33 +0100 Subject: Re: [PATCH bpf-next 1/9] bpf: introduce bpf_spin_lock To: Alexei Starovoitov Cc: Alexei Starovoitov , davem@davemloft.net, jakub.kicinski@netronome.com, netdev@vger.kernel.org, kernel-team@fb.com References: <20190116050830.1881316-1-ast@kernel.org> <20190116050830.1881316-2-ast@kernel.org> <20190116233029.xdaddrfehfjk4hrx@ast-mbp> From: Daniel Borkmann Message-ID: <3367abf6-c6a3-2c2e-9fde-7de923f898d2@iogearbox.net> Date: Thu, 17 Jan 2019 01:21:32 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.3.0 MIME-Version: 1.0 In-Reply-To: <20190116233029.xdaddrfehfjk4hrx@ast-mbp> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit X-Authenticated-Sender: daniel@iogearbox.net X-Virus-Scanned: Clear (ClamAV 0.100.2/25304/Wed Jan 16 19:46:07 2019) Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org On 01/17/2019 12:30 AM, Alexei Starovoitov wrote: > On Thu, Jan 17, 2019 at 12:16:44AM +0100, Daniel Borkmann wrote: >> On 01/16/2019 11:48 PM, Daniel Borkmann wrote: >>> On 01/16/2019 06:08 AM, Alexei Starovoitov wrote: >> [...] >>>> @@ -6096,6 +6226,11 @@ static int do_check(struct bpf_verifier_env *env) >>>> return -EINVAL; >>>> } >>>> >>>> + if (env->cur_state->active_spin_lock) { >>>> + verbose(env, "bpf_spin_unlock is missing\n"); >>>> + return -EINVAL; >>>> + } >>>> + >>>> if (state->curframe) { >>>> /* exit from nested function */ >>>> env->prev_insn_idx = env->insn_idx; >>> >>> I think if I'm not mistaken there should still be a possibility for causing a >>> deadlock, namely if in the middle of the critical section I'm using an LD_ABS >>> or LD_IND instruction with oob index such that I cause an implicit return 0 >>> while lock is held. At least I don't see this being caught, probably also for >>> such case a test_verifier snippet would be good. >>> >>> Wouldn't we also need to mark queued spinlock functions as notrace such that >>> e.g. from kprobe one cannot attach to these causing a deadlock? >> >> I think there may be another problem: haven't verified, but it might be possible >> at least from reading the code that I have two programs which share a common >> array/hash with spin_lock in BTF provided. Program A is properly using spin_lock >> as in one of your examples. Program B is using map in map with inner map being >> that same map using spin_lock. When we return that fake inner_map_meta as >> reg->map_ptr then we can bypass any read/write restrictions into spin_lock area >> which is normally prevented by verifier. Meaning, map in map needs to be made >> aware of spin_lock case as well. > > 2nd great catch. thanks! > Indeed inner_map_meta doesn't preserve all the fields from struct bpf_map. > It seems long term we'll be able to support spin_lock in inner map too, > but for now I'll disable it. There's also one more potential issue in pruning I _think_. In regsafe() we make the basic assumption that for PTR_TO_MAP_VALUE id has been zeroed which is true up to here, and as such we prune state not taking id into account. The only other case we have is PTR_TO_SOCKET{,_OR_NULL} which only allows for exact matches. Potentially there could be a case where you have two map pointers from different branches but with same basic map properties read/ writing map data, and in first run for PTR_TO_MAP_VALUE w/o spin_lock path it was considered safe such that we would get a match in regsafe() as well and could potentially prune the access? I guess definitely worth adding such test case to test_verifier to make sure.