Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751741AbdLGHML (ORCPT ); Thu, 7 Dec 2017 02:12:11 -0500 Received: from mail-pf0-f194.google.com ([209.85.192.194]:39942 "EHLO mail-pf0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750744AbdLGHMK (ORCPT ); Thu, 7 Dec 2017 02:12:10 -0500 X-Google-Smtp-Source: AGs4zMY1CWNKxXlqSYqTLr+Js1h59rhxgaLd9rcap1SYH+6fg5XXghK+lwYBEtD+Kb6EB5sIZsVLZg== Subject: Re: Use-after-free with deferred driver probing and __initconst To: Dan Aloni , kernel-hardening@lists.openwall.com, linux-kernel@vger.kernel.org Cc: Thomas Garnier , Sam Ravnborg , Andrew Morton , Grant Likely , Rob Herring , Greg Kroah-Hartman , Frank Rowand References: <20171203171953.GB17575@gmail.com> From: Frank Rowand Message-ID: Date: Thu, 7 Dec 2017 02:11:26 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.4.0 MIME-Version: 1.0 In-Reply-To: <20171203171953.GB17575@gmail.com> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3625 Lines: 81 adding /me On 12/03/17 12:19, Dan Aloni wrote: > Hi all, > > [[ CC'ed: folks relating to the original __*_refok family of attributes, > deferred probing, Open Firmware maintainer, drivers/base/ maintainer, > kernel harderning, LKML ]] > > It seems that it is possible to cause a use-after-free in the base driver > platform code using a set of combined circumstances which I describe below. > The instance of the issue happens on a patched 4.4 kernel at a client of > mine. > > [ 6.173692] Process kworker/u12:3 (pid: 173, stack limit = 0xfffffc3ea92b8000) > [ 6.180902] Call trace: > [ 6.183345] [] __of_match_node+0x48/0x8c > [ 6.188820] [] of_match_node+0x44/0x68 > [ 6.194125] [] of_match_device+0x34/0x48 > [ 6.199603] [] platform_match+0x34/0xa8 > [ 6.204991] [] __device_attach_driver+0x60/0xc8 > [ 6.211077] [] bus_for_each_drv+0x60/0xac > [ 6.216640] [] __device_attach+0x98/0x124 > [ 6.222203] [] device_initial_probe+0x24/0x30 > [ 6.228111] [] bus_probe_device+0x38/0xa0 > [ 6.233677] [] deferred_probe_work_func+0x108/0x128 > [ 6.240111] [] process_one_work+0x268/0x444 > [ 6.245849] [] worker_thread+0x274/0x404 > [ 6.251329] [] kthread+0xe0/0xe8 > [ 6.256114] [] ret_from_fork+0x10/0x50 > [ 6.261415] ---[ end trace fccad0f7d2c2142a ]--- > [ 6.271293] note: kworker/u12:3[173] exited with preempt_count 1 > [ 6.277342] Unable to handle kernel paging request at virtual address ffffffffffffffd8 > > It happens while booting, and among other things it requires having platform > OF drivers marking their `of_driver_id` arrays as `__initconst`, e.g: > > static const struct of_device_id some_driver_of[] __initconst = { > ... > {}, > }; > > Given a platform driver that uses deferred probing, these arrays marked as > `__initconst` could be accessed from a deferred probe path after the init > section of the kernel has been freed. I have not seen anything in the API > related deferred probing that can guard from this scenario. > > On kernels prior to KASLR the access is not detected, but it can still happen, > potentially accessing memory that was returned to the page allocator. > > On 4.15-rc1, the following shows the ratio between instances of `of_device_id` > arrays and the number of them which are declared`__initconst`: > > $ git grep 'struct of_device_id.*\[\]' | wc -l > 3089 > > $ git grep 'struct of_device_id.*\[\]' | grep __initconst | wc -l > 117 > > Not all of these instances are platform drivers, but perhaps deferred > probing with other types of drivers may cause similar issues. > > Perhaps it is worthwhile patching stable kernels for the removal of > `__initconst` on these arrays? > > > And for the larger question - > > Freeing of init sections poses an exploitable vulnerability if that memory > is not unmapped, _and_ if there are still accesses taking place due to bugs > of this kind. Linux's build process is supposed to detect references from > non-freed sections to the freed sections, but clearly this instance has > not been detected during build, particularly because we have the `__ref`, > `__refdata`, and `__refconst` attributes which suppress those checks. > > Perhaps as a harderning measure, older kernels should be patched with a > config option for not freeing init sections? > > -- > Dan Aloni >