Data.ByteString.Unsafe.unsafeWipe

David Feuer david.feuer at gmail.com
Mon Jan 12 04:16:14 UTC 2015


I think this is a good idea too. I don't think a scrubbing finalizer
can give Erik the timing guarantees he wants (at least not without
forcing a major collection by hand, and worrying about stray
references), but it does seem likely to be a good thing to have around
anyway. Note that for something like a password, you also have to be
careful about things like input buffers. I imagine a hypothetical
SecureByteString and/or SecureText would have to offer special IO as
well.

On Sun, Jan 11, 2015 at 11:08 PM, Carter Schonwald
<carter.schonwald at gmail.com> wrote:
> David's idea is pretty cool!
>
> wrt Erik's suggestion, I'd rather suggest instead
> something like what Vincent's secure memory does,
> which provides finalization support to a bytestring interface
>
> https://hackage.haskell.org/package/securemem-0.1.4/docs/src/Data-SecureMem.html
>
>
>
> -- | Allocate a foreign ptr which will be scrubed before memory free.
> -- the memory is allocated on the haskell heap
> allocateScrubedForeignPtr :: Int -> IO (ForeignPtr a)
> allocateScrubedForeignPtr sz = do
> #if MIN_VERSION_base(4,6,0)
>     fptr@(ForeignPtr addr _) <- mallocForeignPtrBytes sz
>     addForeignPtrConcFinalizer fptr (scruber (Ptr addr))
>     return fptr
>   where !scruber = szToScruber sz
> #else
>     mallocForeignPtrBytes sz
> #endif
>
>
> this code can totally be adapted to provide a scrubing finalizer to any
> foreign pointer of interest, and indeed, it could be done as a helper
> function for bytestrings a la
>
> addFinalizer :: ByteString -> IO () -> IO ()
>
> or something
>
>
> On Sun, Jan 11, 2015 at 10:48 PM, David Feuer <david.feuer at gmail.com> wrote:
>>
>> -1. Breaking referential transparency is completely unnecessary here.
>> The correct way to accomplish this, I believe, is to add a mutable
>> ByteString interface, and then a SecureByteString module wrapping it
>> and actually making the promises you want.
>>
>> On Sun, Jan 11, 2015 at 10:42 PM, Erik de Castro Lopo
>> <mle+hs at mega-nerd.com> wrote:
>> > Discussion period: one month
>> >
>> > When handling sensitive information (like a user's password) it is
>> > desirable to only keep the data around for as short a time as possible.
>> > Specifically, relying on the garbage collector to clean it up is simply
>> > not good enough.
>> >
>> > I therefore propose that the following function to be added to the
>> > Data.ByteString.Unsafe module:
>> >
>> >     -- | Overwrites the contents of a ByteString with \0 bytes.
>> >     unsafeWipe :: ByteString -> IO ()
>> >     unsafeWipe bs =
>> >         BS.unsafeUseAsCStringLen bs $ \(ptr, len) ->
>> >             let go i
>> >                     | i < 0 = return ()
>> >                     | otherwise = pokeElemOff ptr i 0 >> go (i - 1)
>> >             in go (len - 1)
>> >
>> > It is added to the Unsafe module because it break referential
>> > transparency
>> > but since ByteStrings are always kept in pinned memory, it should not
>> > otherwise be considered unsafe.
>> >
>> > It could be used as follows:
>> >
>> >     main = do
>> >         passwd <- getPassword
>> >         doSomethingWith passwd
>> >         unsafeWipe passwd
>> >         restOfProgram
>> >
>> >
>> > Cheers,
>> > Erik
>> > --
>> > ----------------------------------------------------------------------
>> > Erik de Castro Lopo
>> > http://www.mega-nerd.com/
>> > _______________________________________________
>> > Libraries mailing list
>> > Libraries at haskell.org
>> > http://www.haskell.org/mailman/listinfo/libraries
>> _______________________________________________
>> Libraries mailing list
>> Libraries at haskell.org
>> http://www.haskell.org/mailman/listinfo/libraries
>
>


More information about the Libraries mailing list