From patchwork Thu Mar 16 16:55:47 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Evans X-Patchwork-Id: 739917 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3vkZNx1jxJz9ryZ for ; Fri, 17 Mar 2017 03:56:00 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="jx2MONID"; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:mime-version:from:date:message-id:subject:to :cc:content-type; q=dns; s=default; b=m9W9jjjHtsSuUOQ2cOLnwOfWcy HOJCS1C88Z/B/9qRkJWEMyvKCk/JGIGV3e+tCTx/lfpHuhonpfQKu2ZxxisF4Qa/ fOzNoSQAGimxyCMa9ac9rQ+X9NTAMCHFxbE3/hrqG48d9fCpXAhN2GPhJWWmBdY2 W5kA9Z4kL550E2M4Y= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:mime-version:from:date:message-id:subject:to :cc:content-type; s=default; bh=p58YT/C0phwAFdPlY+Uw1pOUlHQ=; b= jx2MONIDge03JnXB5F5MIgeGMIGt3diou9Tx8Rv0zCVScjvt8KEuwt51NxhUclyq Dh+5CZKFVXF4NOB9cIE0z/EpZ2lNnwQW/gihovSdHxkYHFettIFW+T3P8onZGqqA e4MAhMo3zaK/98g15Pp0uZw3OraP9DqWR3bOnQ8I3uw= Received: (qmail 46166 invoked by alias); 16 Mar 2017 16:55:52 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 46156 invoked by uid 89); 16 Mar 2017 16:55:51 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-11.4 required=5.0 tests=BAYES_00, FREEMAIL_FROM, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, RCVD_IN_SORBS_SPAM, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mail-wm0-f47.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to:cc; bh=BjnXRHMf1GC+QUoAOZtKfRJ5g4KRkGh0h9loGh5pwKo=; b=kIY/F/YCL2oHTd13o5THDIQQGtWB/OP8ufFEUvBaeIhdXA68wsK3VMKbgw1uf5rSuN k/d43GMuawggpOiT+qCuwpg5H0ZfBS+GNEuPvi2ZEjH0LtXcBbGfwpW5qJGLnsbePRVK G1wAyAiXT1Asi1MZX80loPtXtxaW8D5GhS/XQSkkr5lrzdtkXw+5BKjDkiIeuC5NiVGz 9pjH8MCxJ15ie08DYXfINLdaXBJj3xI/+sW0b+GkXepMSkQZR0tsJvd/fRanrdUS0OvR zG70VHHbXkOcVkgu0R2w0Bl8iJIMO10oJmQDnJ/m9uTjch9cFFgELRel4EZ9vE0L2Rji ppuw== X-Gm-Message-State: AFeK/H3zU+VMkc1VZs3h+SbVCu0ZbUClagagshB70L322UKYEVagtWGZkVot1O0nbtiBVkRq+dKRk4spleP25g== X-Received: by 10.28.170.67 with SMTP id t64mr25192969wme.18.1489683348527; Thu, 16 Mar 2017 09:55:48 -0700 (PDT) MIME-Version: 1.0 From: Chris Evans Date: Thu, 16 Mar 2017 09:55:47 -0700 Message-ID: Subject: Patch to further harden glibc malloc metadata against 1-byte overflows To: libc-alpha@sourceware.org Cc: Florian Weimer , DJ Delorie Hi, [This is a resend of a private conversation started with Florian] Back in 2014, we landed a malloc hardening measure against 1-byte overflows. Here is a reference: https://www.sourceware.org/ml/glibc-bugs/2014-09/msg00181.html Since then, there's been this really interesting piece of work that exploited Chrome OS using a 1-byte overflow to attack glibc malloc() metadata in a different way: https://googleprojectzero.blogspot.com/2016/12/chrome-os-exploit-one-byte-overflow-and.html It has been bothering me that there's still a known, generic way to attack 1-byte overflows in glibc malloc(). So I put some thought into whether the situation can be cleanly detected and prevented. It can. I've attached a 2-line patch (malloc.c.diff) that cleanly detects and aborts on the condition. I've also attached an old test case I had for this issue (shrink_free_hole_alloc_overlap_consolidate_backward.c). Without the patch, the program exits normally, having aliased a couple of heap chunks. With the patch, the program exits with something like "*** Error in `./a.out': corrupted size vs. prev_size: 0x00000000022a0400 ***" I would be very excited to see this patch land :) I think it shuts down a known, significant mitigation bypass. I also worry that if there remain any serious bugs in important Linux services, they are likely to bias towards subtle "1-byte overflows" and the like, which can currently be exploited as demonstrated by the blog post above. This patch can't defend against more powerful corruption primitives, such as more arbitrary overflows or multiple overflows, but I think it's a step forward for 1-byte overflows and particularly 1-byte NUL overflows. Cheers Chris --- .pc/test.patch/malloc/malloc.c 2017-03-14 17:50:26.000000000 -0700 +++ malloc/malloc.c 2017-03-14 23:33:27.241466106 -0700 @@ -1409,6 +1409,8 @@ /* Take a chunk off a bin list */ #define unlink(AV, P, BK, FD) { \ + if (__builtin_expect (chunksize(P) != next_chunk(P)->prev_size, 0)) \ + malloc_printerr (check_action, "corrupted size vs. prev_size", P, AV); \ FD = P->fd; \ BK = P->bk; \ if (__builtin_expect (FD->bk != P || BK->fd != P, 0)) \