[commit: ghc] ghc-8.6: Fix Ar crashing on odd-sized object files (Trac #15396) (0480507)

git at git.haskell.org git at git.haskell.org
Tue Jul 31 20:34:30 UTC 2018


Repository : ssh://git@git.haskell.org/ghc

On branch  : ghc-8.6
Link       : http://ghc.haskell.org/trac/ghc/changeset/04805078763d6c7347d4cecf33d7e14099790793/ghc

>---------------------------------------------------------------

commit 04805078763d6c7347d4cecf33d7e14099790793
Author: Krzysztof Gogolewski <krz.gogolewski at gmail.com>
Date:   Fri Jul 27 22:10:52 2018 +0200

    Fix Ar crashing on odd-sized object files (Trac #15396)
    
    Summary: All the work was done by Moritz Angermann.
    
    Test Plan: validate
    
    Reviewers: angerman, RyanGlScott, bgamari
    
    Reviewed By: angerman
    
    Subscribers: rwbarton, thomie, carter
    
    GHC Trac Issues: #15396
    
    Differential Revision: https://phabricator.haskell.org/D5013
    
    (cherry picked from commit 754c3a55a603b155fa5d9a282de73d41a4694ffc)


>---------------------------------------------------------------

04805078763d6c7347d4cecf33d7e14099790793
 compiler/main/Ar.hs                  | 13 +++++++++++--
 testsuite/tests/driver/T15396.hs     |  8 ++++++++
 testsuite/tests/driver/T15396.stdout |  1 +
 testsuite/tests/driver/all.T         |  2 ++
 4 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/compiler/main/Ar.hs b/compiler/main/Ar.hs
index 51655c0..9ead053 100644
--- a/compiler/main/Ar.hs
+++ b/compiler/main/Ar.hs
@@ -95,7 +95,8 @@ getBSDArchEntries = do
         st_size <- getPaddedInt <$> getByteString 10
         end     <- getByteString 2
         when (end /= "\x60\x0a") $
-          fail "Invalid archive header end marker"
+          fail ("[BSD Archive] Invalid archive header end marker for name: " ++
+                C.unpack name)
         off1    <- liftM fromIntegral bytesRead :: Get Int
         -- BSD stores extended filenames, by writing #1/<length> into the
         -- name field, the first @length@ bytes then represent the file name
@@ -106,6 +107,10 @@ getBSDArchEntries = do
                         return $ C.unpack $ C.takeWhile (/= ' ') name
         off2    <- liftM fromIntegral bytesRead :: Get Int
         file    <- getByteString (st_size - (off2 - off1))
+        -- data sections are two byte aligned (see Trac #15396)
+        when (odd st_size) $
+          void (getByteString 1)
+
         rest    <- getBSDArchEntries
         return $ (ArchiveEntry name time own grp mode (st_size - (off2 - off1)) file) : rest
 
@@ -128,8 +133,12 @@ getGNUArchEntries extInfo = do
       st_size <- getPaddedInt <$> getByteString 10
       end     <- getByteString 2
       when (end /= "\x60\x0a") $
-        fail "Invalid archive header end marker"
+        fail ("[BSD Archive] Invalid archive header end marker for name: " ++
+              C.unpack name)
       file <- getByteString st_size
+      -- data sections are two byte aligned (see Trac #15396)
+      when (odd st_size) $
+        void (getByteString 1)
       name <- return . C.unpack $
         if C.unpack (C.take 1 name) == "/"
         then case C.takeWhile (/= ' ') name of
diff --git a/testsuite/tests/driver/T15396.hs b/testsuite/tests/driver/T15396.hs
new file mode 100644
index 0000000..9ab9f6e
--- /dev/null
+++ b/testsuite/tests/driver/T15396.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE OverloadedStrings #-}
+import Ar
+
+-- obtained from echo -n \0 > x.o && ar -q b.a x.o && cat b.a
+archive = "!<arch>\nx.o/            0           0     0     644     1         \
+\`\n0\nx.o/            0           0     0     644     1         `\n0\n"
+
+main = print (parseAr archive)
diff --git a/testsuite/tests/driver/T15396.stdout b/testsuite/tests/driver/T15396.stdout
new file mode 100644
index 0000000..65edafa
--- /dev/null
+++ b/testsuite/tests/driver/T15396.stdout
@@ -0,0 +1 @@
+Archive [ArchiveEntry {filename = "x.o", filetime = 0, fileown = 0, filegrp = 0, filemode = 644, filesize = 1, filedata = "0"},ArchiveEntry {filename = "x.o", filetime = 0, fileown = 0, filegrp = 0, filemode = 644, filesize = 1, filedata = "0"}]
diff --git a/testsuite/tests/driver/all.T b/testsuite/tests/driver/all.T
index 714b6c4..6397598 100644
--- a/testsuite/tests/driver/all.T
+++ b/testsuite/tests/driver/all.T
@@ -278,3 +278,5 @@ test('T13604a', [], run_command, ['$MAKE -s --no-print-directory T13604a'])
 test('inline-check', omit_ways(['hpc', 'profasm'])
                    , compile
 		   , ['-dinline-check foo -O -ddebug-output'])
+
+test('T15396', normal, compile_and_run, ['-package ghc'])



More information about the ghc-commits mailing list