This fixes a reversion caused by
a99a84f3420a1d93e4ecd4b8cf30638b48e2758e,
when git-annex init is run as root on a FAT filesystem mounted with
hdiutil on OSX. Such a mount point has file mode 777 for everything and
it cannot be changed. The existing crippled filesystem test tried to
write to a file after removing write bit, but that test does not run as
root (since root can write to unwritable files). So added a check of the
write permissions of the file, after attempting to remove them.
Sponsored-by: Dartmouth College's Datalad project
-> Maybe (RawFilePath -> m ())
-> m (Bool, [String])
#ifdef mingw32_HOST_OS
-probeCrippledFileSystem' _ _ _ = return (True, [])
+probeCrippledFileSystem' _ _ _ _ = return (True, [])
#else
probeCrippledFileSystem' tmp freezecontent thawcontent = do
let f = tmp P.</> "gaprobe"
liftIO $ createSymbolicLink f f2
liftIO $ removeWhenExistsWith R.removeLink (toRawFilePath f2)
(fromMaybe (liftIO . preventWrite) freezecontent) (toRawFilePath f)
- -- Should be unable to write to the file, unless
- -- running as root, but some crippled
- -- filesystems ignore write bit removals.
- liftIO $ ifM ((== 0) <$> getRealUserID)
- ( return (False, [])
- , do
- r <- catchBoolIO $ do
- writeFile f "2"
- return True
- if r
- then return (True, ["Filesystem allows writing to files whose write bit is not set."])
- else return (False, [])
+ -- Should be unable to write to the file (unless
+ -- running as root). But some crippled
+ -- filesystems ignore write bit removals or ignore
+ -- permissions entirely.
+ ifM ((== Just False) <$> liftIO (checkContentWritePerm' UnShared (toRawFilePath f)))
+ ( return (True, ["Filesystem does not allow removing write bit from files."])
+ , liftIO $ ifM ((== 0) <$> getRealUserID)
+ ( return (False, [])
+ , do
+ r <- catchBoolIO $ do
+ writeFile f "2"
+ return True
+ if r
+ then return (True, ["Filesystem allows writing to files whose write bit is not set."])
+ else return (False, [])
+ )
)
#endif
freezeContent,
freezeContent',
checkContentWritePerm,
+ checkContentWritePerm',
thawContent,
thawContent',
createContentDir,
checkContentWritePerm :: RawFilePath -> Annex (Maybe Bool)
checkContentWritePerm file = ifM crippledFileSystem
( return (Just True)
- , withShared go
+ , withShared (\sr -> liftIO (checkContentWritePerm' sr file))
)
- where
- go GroupShared = want sharedret
- (includemodes [ownerWriteMode, groupWriteMode])
- go AllShared = want sharedret (includemodes writeModes)
- go _ = want Just (excludemodes writeModes)
- want mk f =
- liftIO (catchMaybeIO $ fileMode <$> R.getFileStatus file) >>= return . \case
+checkContentWritePerm' :: SharedRepository -> RawFilePath -> IO (Maybe Bool)
+checkContentWritePerm' sr file = case sr of
+ GroupShared -> want sharedret
+ (includemodes [ownerWriteMode, groupWriteMode])
+ AllShared -> want sharedret (includemodes writeModes)
+ _ -> want Just (excludemodes writeModes)
+ where
+ want mk f = catchMaybeIO (fileMode <$> R.getFileStatus file)
+ >>= return . \case
Just havemode -> mk (f havemode)
Nothing -> mk True
[[!meta author=yoh]]
[[!tag projects/datalad]]
+
+> [[fixed|done]] (provisionally; can't test running git-annex as root on
+> OSX) --[[Joey]]
--- /dev/null
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 1"""
+ date="2021-09-01T13:48:57Z"
+ content="""
+Seems that mounting that way on OSX results in a FS where files are always mode
+777 and the permissions cannot be changed.
+
+When I tried using git-annex on such a FS, I saw:
+
+ datalads-imac:x joey$ git annex init
+ init
+ Detected a filesystem without fifo support.
+
+ Disabling ssh connection caching.
+
+ Filesystem allows writing to files whose write bit is not set.
+
+ Detected a crippled filesystem.
+
+And it skips the new permissions check when on a crippled filesystem.
+
+But in that that test run, it seems it is failing to detect a crippled
+filesystem. Both because of the failure and also the test suite does
+not even run the "v8 unlocked" tests when it detects a crippled filesystem.
+
+Is the test suite running as root? Looks like probably yes. Running as
+root prevents detecting the issue that made it use a crippled FS above. And it
+seems that, when a FAT fs is mounted on OSX that way, symlinks actually work
+(!!!) so the other crippled FS tests also don't notice a problem.
+
+So, the fix should be for init to also test if it can remove the write
+bits from a file, and it should try that test even when root.
+"""]]