[Git][ghc/ghc][wip/backports-8.8] FastString: fix eager reading of string ptr in hashStr

Ben Gamari gitlab at gitlab.haskell.org
Sat May 30 14:24:51 UTC 2020



Ben Gamari pushed to branch wip/backports-8.8 at Glasgow Haskell Compiler / GHC


Commits:
bc05d359 by Ömer Sinan Ağacan at 2020-05-30T10:20:52-04:00
FastString: fix eager reading of string ptr in hashStr

This read causes NULL dereferencing when len is 0.

Fixes #17909

In the reproducer in #17909 this bug is triggered as follows:

- SimplOpt.dealWithStringLiteral is called with a single-char string
  ("=" in #17909)

- tailFS gets called on the FastString of the single-char string.

- tailFS checks the length of the string, which is 1, and calls
  mkFastStringByteString on the tail of the ByteString, which is an
  empty ByteString as the original ByteString has only one char.

- ByteString's unsafeUseAsCStringLen returns (NULL, 0) for the empty
  ByteString, which is passed to mkFastStringWith.

- mkFastStringWith gets hash of the NULL pointer via hashStr, which
  fails on empty strings because of this bug.

(cherry picked from commit cb1785d9f839e34a3a4892f354f0c51cc6553c0e)

- - - - -


1 changed file:

- compiler/utils/FastString.hs


Changes:

=====================================
compiler/utils/FastString.hs
=====================================
@@ -519,16 +519,22 @@ cmpStringPrefix ptr1 ptr2 len =
  do r <- memcmp ptr1 ptr2 len
     return (r == 0)
 
-
 hashStr  :: Ptr Word8 -> Int -> Int
  -- use the Addr to produce a hash value between 0 & m (inclusive)
 hashStr (Ptr a#) (I# len#) = loop 0# 0#
-   where
-    loop h n | isTrue# (n ==# len#) = I# h
-             | otherwise  = loop h2 (n +# 1#)
-          where
-            !c = ord# (indexCharOffAddr# a# n)
-            !h2 = (h *# 16777619#) `xorI#` c
+  where
+    loop h n =
+      if isTrue# (n ==# len#) then
+        I# h
+      else
+        let
+          -- DO NOT move this let binding! indexCharOffAddr# reads from the
+          -- pointer so we need to evaluate this based on the length check
+          -- above. Not doing this right caused #17909.
+          !c = ord# (indexCharOffAddr# a# n)
+          !h2 = (h *# 16777619#) `xorI#` c
+        in
+          loop h2 (n +# 1#)
 
 -- -----------------------------------------------------------------------------
 -- Operations



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bc05d3599545ddca50dbd8a557fd71785f6cb6fd

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bc05d3599545ddca50dbd8a557fd71785f6cb6fd
You're receiving this email because of your account on gitlab.haskell.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20200530/1010728d/attachment-0001.html>


More information about the ghc-commits mailing list