
On Tue, 29 Jul 2003, Sven Panne wrote:
Ben Rudiak-Gould wrote:
I don't think this is fatal. The important part of File identity is that two File values which compare equal necessarily denote the same file, not the converse. [...]
Huh? I thought it was the other way round. What is this your identity good for?
What I wrote above doesn't make much sense. Here's what I was trying to say. The keystone of this whole model is that File values are not file handles: they are files. It's essential that the library implementation maintain the link from the File value to the file by something more reliable than a pathname. For example, in the following code: do f1 <- lookupFileByPathname "/mydir/myfile" fRead f1 ... f2 <- lookupFileByPathname "/mydir/myfile" putStrLn (if f1 == f2 then "equal" else "inequal") fRead f2 ... f1 and f2 may compare equal or they may compare inequal (the latter being the case if someone has renamed the original file and put a new one in its place, for example), but if they compare equal then it *must* be the case that they refer to the same actual file. This would not hold true if File values were implemented internally as pathnames. Why does this matter? Because people use the File abstraction in their code whether the system provides it or not, and if the system doesn't provide it, the way they implement it is as, you guessed it, pathnames. This opens them up to various security exploits that involve renaming files or directories in between successive opens of the same pathname. In Haskell, I thought we could avoid this by implementing the File abstraction correctly once and for all. People would have to use the system-supplied abstraction rather than their own, but that would just be among the things you'd learn when learning Haskell programming, along with strong typing, side-effect isolation, pattern matching, and so on. Like those features, the File abstraction not only prevents a certain class of bugs, it's also conceptually more elegant than the alternatives. But the upshot of the discussion here is that there's no way to implement a well-behaved File abstraction on Win32 or Posix, so people are just going to have to continue writing insecure programs on a less-elegant API. Stop me if I start to sound bitter. :-) -- Ben (All of this also applies to the Directory abstraction, of course. Another example from the proposal: dCreateFileEntry must fail if an entry by that name already exists, and it must return IO File and not IO (). Anything else is exploitable. Even this can't be implemented on some systems, I think.)