[Git][ghc/ghc][wip/T13660] 2 commits: base: Ensure that FilePaths don't contain NULs on POSIX
Ben Gamari (@bgamari)
gitlab at gitlab.haskell.org
Fri Mar 10 16:31:29 UTC 2023
Ben Gamari pushed to branch wip/T13660 at Glasgow Haskell Compiler / GHC
Commits:
9198e7fe by Ben Gamari at 2023-03-10T11:31:25-05:00
base: Ensure that FilePaths don't contain NULs on POSIX
POSIX filepaths may not contain the NUL octet but previously we did not
reject such paths. This could be exploited by untrusted input to cause
discrepancies between various `FilePath` queries and the opened
filename. For instance, `readFile "hello.so\x00.txt"` would open the
file `"hello.so"` yet `takeFileExtension` would return `".txt"`.
Fixes #13660.
- - - - -
f3cc8aa5 by Ben Gamari at 2023-03-10T11:31:25-05:00
base: Add test for #13660
- - - - -
3 changed files:
- libraries/base/System/Posix/Internals.hs
- + libraries/base/tests/T13660.hs
- libraries/base/tests/all.T
Changes:
=====================================
libraries/base/System/Posix/Internals.hs
=====================================
@@ -178,11 +178,43 @@ newFilePath :: FilePath -> IO CString
peekFilePath :: CString -> IO FilePath
peekFilePathLen :: CStringLen -> IO FilePath
-withFilePath fp f = getFileSystemEncoding >>= \enc -> GHC.withCString enc fp f
-newFilePath fp = getFileSystemEncoding >>= \enc -> GHC.newCString enc fp
+withFilePath fp f = do
+ enc <- getFileSystemEncoding
+ GHC.withCStringLen enc fp $ \(str, len) -> do
+ checkForInteriorNuls fp (str, len)
+ f str
+newFilePath fp = do
+ enc <- getFileSystemEncoding
+ (str, len) <- GHC.newCStringLen enc fp
+ checkForInteriorNuls fp (str, len)
+ return str
peekFilePath fp = getFileSystemEncoding >>= \enc -> GHC.peekCString enc fp
peekFilePathLen fp = getFileSystemEncoding >>= \enc -> GHC.peekCStringLen enc fp
+-- | Check an encoded 'FilePath' for internal NUL octets as these are disallowed
+-- in POSIX filepaths. See #13660.
+checkForInteriorNuls :: FilePath -> CStringLen -> IO ()
+checkForInteriorNuls fp (str, len) = go (len-1)
+ where
+ -- here we ensure that the body of the string (that is, excluding the terminal
+ -- NUL) contains no NUL octets.
+ go (-1) = return ()
+ go i = do
+ c <- peekByteOff str i :: IO Word8
+ when (c == 0) $ do
+ ioError err
+ go (i-1)
+
+ err =
+ IOError
+ { ioe_handle = Nothing
+ , ioe_type = InvalidArgument
+ , ioe_location = "checkForInteriorNuls"
+ , ioe_description = "POSIX filepaths must not contain internal NUL octets."
+ , ioe_errno = Nothing
+ , ioe_filename = Just fp
+ }
+
#endif
-- ---------------------------------------------------------------------------
=====================================
libraries/base/tests/T13660.hs
=====================================
@@ -0,0 +1,9 @@
+-- | This should print an InvalidArgument error complaining that
+-- the file path contains a NUL octet.
+module Main where
+
+main :: IO ()
+main = do
+ catchIOError
+ (writeFile "hello\x00world" "hello")
+ print
=====================================
libraries/base/tests/all.T
=====================================
@@ -256,6 +256,7 @@ test('T13191',
['-O'])
test('T13525', [when(opsys('mingw32'), skip), js_broken(22374)], compile_and_run, [''])
test('T13097', normal, compile_and_run, [''])
+test('T13660', when(opsys('mingw32'), skip), compile_and_run, [''])
test('functorOperators', normal, compile_and_run, [''])
test('T3474',
[collect_stats('max_bytes_used',5),
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e4a662ff72d00c28ef9453ed78c9b608ed85d729...f3cc8aa5accf17ea45ca4eba98cf2054330e6edf
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e4a662ff72d00c28ef9453ed78c9b608ed85d729...f3cc8aa5accf17ea45ca4eba98cf2054330e6edf
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/20230310/554e059d/attachment-0001.html>
More information about the ghc-commits
mailing list