From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754662AbdCFPji (ORCPT ); Mon, 6 Mar 2017 10:39:38 -0500 Received: from mail.ottolander.nl ([176.9.136.165]:35110 "EHLO mail.ottolander.nl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753493AbdCFPjP (ORCPT ); Mon, 6 Mar 2017 10:39:15 -0500 X-Greylist: delayed 584 seconds by postgrey-1.27 at vger.kernel.org; Mon, 06 Mar 2017 10:39:14 EST Subject: binfmts.h MAX_ARG_STRINGS excessive value allows heap spraying From: Leonard den Ottolander To: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="UTF-8" Date: Mon, 06 Mar 2017 16:29:26 +0100 Message-ID: <1488814166.25747.27.camel@quad> Mime-Version: 1.0 X-Mailer: Evolution 2.32.3 (2.32.3-36.1.lj.el6) Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org In the article https://googleprojectzero.blogspot.nl/2014/08/the-poisoned-nul-byte-2014-edition.html the author describes launching an attack on an off by one NUL byte bug in glibc. He explains that both the memory leak in the option parsing of PolKits pkexec.c and the excessive value of MAX_ARG_STRINGS in the kernels include/uapi/linux/binfmts.h (#define MAX_ARG_STRINGS 0x7FFFFFFF) enabled his attack. The rationale for that excessive value is a bit odd: "MAX_ARG_STRINGS is chosen to fit in a signed 32-bit integer." https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/include/uapi/linux/binfmts.h?id=607ca46e97a1b6594b29647d98a32d545c24bdff The fact that the integer is so large makes that on a 32 bit platform the entire heap can be initialized with values the attacker provides, given the memory leak in the option parsing of pkexec.c, an approach the author calls "heap spraying". (Note that two similar memory leaks exist in the option parsing of pkexecs sibling pkcheck.c, so pkcheck will also allow an attacker to heap spray its entire memory on a 32 bit system.) If you compare http://www.linuxjournal.com/article/6060 you will see that the TOTAL amount of memory reserved for command line arguments used to be 32 pages, i.e. 128KiB (#define MAX_ARG_PAGES 32). The amount of memory reserved for command line arguments in more current kernels is the multiplication of MAX_ARG_STRINGS and MAX_ARG_STRLEN. Both the memory leaks in pkexec.c and pkcheck.c seem very severe, but their impact would be much less if MAX_ARG_STRINGS would hold a sensible value. After some experimentation with $ rpmbuild -ba kernel.spec on CentOS-7 I've come up with values that allow this kernel compilation. As this kind of build is probably one of the most demanding actions in relation to MAX_ARG_STRINGS and MAX_ARG_STRLEN I believe below values to be sensible and much safer defaults: #define MAX_ARG_STRLEN 65536 #define MAX_ARG_STRINGS 4096 Please let me know if this needs to be filed as a bug somewhere. Regards, Leonard. -- mount -t life -o ro /dev/dna /genetic/research