elast0ny / shared_memory

A Rust wrapper around native shared memory for Linux and Windows
382 stars 51 forks source link

+ file lock #23

Closed bopohaa closed 5 years ago

bopohaa commented 5 years ago

Сhanges

This fork has a feature rs2 that allows you to safely create shared memory through file locks. Example of common to all processes code:

SharedMem::open_linked(file_name)
    .or_else(|_|SharedMem::create_linked(file_name, LockType::RwLock, 4096))
    .or_else(|_|SharedMem::open_linked(file_name))
    .ok()
elast0ny commented 5 years ago

Hi, sorry for the delay.

This PR points our a TOCTOU issue in the creation of the link file with https://github.com/elast0ny/shared_memory-rs/blob/9285b278c7490f1bc2258c67859a70c18fbb0826/src/conf.rs#L211 and https://github.com/elast0ny/shared_memory-rs/blob/9285b278c7490f1bc2258c67859a70c18fbb0826/src/conf.rs#L214 but I believe the issue can be resolved without the use of external crates with OpenOptions' create_new(true) :

use std::fs::OpenOptions;

let file = OpenOptions::new().write(true)
                             .create_new(true)
                             .open("foo.txt");

I will add create_new() for the next release.

Let me know if you had other reasons behind bringing in the rs2 crate and think the PR should still be merged.

Thanks !

bopohaa commented 5 years ago

In my test environment (centos 7), two processes try to create the same file at the same time and both of them succeed. I could not find a solution without locking the file into exclusive access. Therefore, I took a third-party dependency that works both under Linux and under Windows and connected it as an optional feature

bopohaa commented 5 years ago

The current solution is working in our production environment for over a month (data synchronization between multiple nginx worker processes).

elast0ny commented 5 years ago

Alright, I will do some testing with create_new() to ensure it fixes your problem. According to the documentation, it seems like it was created exactly for this scenario :

This option indicates whether a new file will be created. No file is allowed to exist at the target location, also no (dangling) symlink. This option is useful because it is atomic. Otherwise between checking whether a file exists and creating a new one, the file may have been created by another process (a TOCTOU race condition / attack).

I'd rather use whats in the standard library instead of depending on a crate

elast0ny commented 5 years ago

This PR will be fixed with the merge of PR #30

Thanks for highlighting the TOCTOU bug !