From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20584 invoked by alias); 24 Jul 2014 10:50:31 -0000 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org Received: (qmail 20573 invoked by uid 48); 24 Jul 2014 10:50:27 -0000 From: "vogt at linux dot vnet.ibm.com" To: gcc-bugs@gcc.gnu.org Subject: [Bug other/61895] New: libbacktrace crashes with bus error with empty file argv[0] Date: Thu, 24 Jul 2014 10:50:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: other X-Bugzilla-Version: 4.10.0 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: vogt at linux dot vnet.ibm.com X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter Message-ID: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-SW-Source: 2014-07/txt/msg01602.txt.bz2 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61895 Bug ID: 61895 Summary: libbacktrace crashes with bus error with empty file argv[0] Product: gcc Version: 4.10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: other Assignee: unassigned at gcc dot gnu.org Reporter: vogt at linux dot vnet.ibm.com Docker uses a call of the exec family to start a new process with a bogus argv[0] argument, i.e. argv[0] points to an empty file, not a real executable. libbacktrace opens the empty file, mmaps it and uses it without ever checking the size of the file. Eventually, libbacktrace causes a bus error (on s390x, may be a different fault on other architectures) in elf.c:564: memcpy (&ehdr, ehdr_view.data, sizeof ehdr); ----- The problem can be reproduced like this (it's probably possible to reproduce this with a C program): -- BEGIN exec.c -- #include int main(int argc, char *argv[]) { execv(argv[0], &argv[1]); return 1; } -- END exec.c -- -- BEGIN hello.go -- package main import "fmt" func main() { fmt.Println("Hello!") } -- END hello.go -- $ gcc -o exec exec.c $ gccgo -g -o hello hello.go $ touch empty $ ./exec ./hello $PWD/empty Bus error (core dumped) ----- Fix: libbacktrace needs to sanitize its input, i.e. the files it tries to open in fileline_initialize(). Such a file must be at least as long as sizeof ehdr, but there may be more places in the code that don't do size checking. The right approach might be something like this: descriptor = backtrace_open(...) if (descriptor >= 0) { if (!is_executable_valid(descriptor)) { /* close descriptor */ /* maybe emit an error message */ /* try other files */ } } int is_executable_valid(int descriptor) { ... }