Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign uplibstd: Add thread unsafety warnings around setenv() and unsetenv() #24741
Conversation
rust-highfive
assigned
brson
Apr 23, 2015
This comment has been minimized.
This comment has been minimized.
|
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @brson (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. The way Github handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see CONTRIBUTING.md for more information. |
This comment has been minimized.
This comment has been minimized.
|
I read too quickly - Rust has its own mutex, but that doesn't help if there are other non-rust threads in the process. I'll update this PR. |
cgwalters
force-pushed the
cgwalters:note-setenv-and-unsetenv-are-not-threadsafe
branch
from
7668a1e
to
712cef9
Apr 30, 2015
This comment has been minimized.
This comment has been minimized.
|
Reworked to note that |
This comment has been minimized.
This comment has been minimized.
|
Thanks for the PR! I think this isn't quite the message we want to be sending, however, as "possibly unsafe" code is still unsafe and needs to be marked as such with It's possible that one day we will expose the environment variable lock to C to allow it to acquire it, but for now it's unlikely we'll commit to that so soon. |
This comment has been minimized.
This comment has been minimized.
|
Hi @alexcrichton , thanks for the review! I'm excited to make a small contribution to Rust =) On to the topic: It doesn't actually work to just wrap a mutex around See https://sourceware.org/bugzilla/show_bug.cgi?id=15607 (which is linked from https://bugs.freedesktop.org/show_bug.cgi?id=65681 ) So every C library user including glibc itself (for things like It's just not going to happen. Or even if it did happen today, we'd still have many years of people running old glibc/rust/other C libraries (such as glib, which is a project I contribute to and where we saw this bug in the real world). I'm happy to reword, but I don't think we can recommend external synchronization for the above reasons. |
This comment has been minimized.
This comment has been minimized.
|
Another option is to drop |
This comment has been minimized.
This comment has been minimized.
|
BTW, it looks like Also [1] I actually don't know offhand all of the details of Windows threadsafety around this, but https://public.kitware.com/Bug/view.php?id=13156#c29334 is a useful comment in a thread. |
This comment has been minimized.
This comment has been minimized.
True, but this is why the two functions in Rust returned owned buffers, and I think it's still reasonable to require that external users at least synchronize access, even when using external libraries, to have this kind of protection.
Unfortunately I think this may be a non-starter. Not only is it a large breaking change, but it's not cross-platform as Windows environment variables work fairly differently. |
This comment has been minimized.
This comment has been minimized.
Yes, there's no issues if one's program is 100% Rust. This PR is about
I would assert that very few Rust program authors are going to be in a
It'd be painful, yes. Ideally this would have been caught far earlier. It's possible that there are no Rust programs that are broken today - But several GNOME components were burned by this, as well as the Fedora On the plus side, the Rust |
This comment has been minimized.
This comment has been minimized.
Right, but it's not required to patch up existing libraries. This is perhaps just part of the contract of calling an Put another way this is not an inherent unsafety of this method, but rather a contract which needs to be upheld when crossing the FFI boundary on some platforms. |
This comment has been minimized.
This comment has been minimized.
|
Let me state this plainly: I assert that if one's application has both The only reliable thing to do is to call Here's a message from one of the glibc developers implying the above: Here's a link I just found to a POSIX spec bug on this: "I.e., any program that wants to use getenv simply must refrain from
What you're saying is that if I wanted my Rust app to use say Yes...except what if I'm trying to call a C library function which in In this case where the actual Let's take a real world example; say I'm writing Rust bindings for There deep in the bowels of a disk probing function, it happens to call (Ok, in the parted case above, at the most you'd have a read of freed Looks like a better example where the library is actually trying to And if you're still thinking that it's reasonable for the author of Rust There really is no sane solution to this other than banning setenv after |
cgwalters
referenced
this pull request
in rhatdan/atomic
May 12, 2015
This comment has been minimized.
This comment has been minimized.
|
@cgwalters I definitely agree that this is a bug that comes up in practice, and it's definitely something that needs to be warned about, I think the message may just need to be updated slightly. For example, how about this?
|
cgwalters
force-pushed the
cgwalters:note-setenv-and-unsetenv-are-not-threadsafe
branch
from
712cef9
to
79bda49
May 13, 2015
This comment has been minimized.
This comment has been minimized.
|
I feel like that doesn't quite leave the reader with enough information to figure out "how do I do this synchronization" or in general find out more information about the issue. There doesn't seem to be significant precedent for linking to URLs from documentation, but how about something like |
This comment has been minimized.
This comment has been minimized.
|
(That said, I'm fine to just do exactly what you suggest in the interest of moving on from this issue) |
This comment has been minimized.
This comment has been minimized.
|
Linking to an external site is definitely fine by me!
|
brson
assigned
alexcrichton
and unassigned
brson
May 13, 2015
This comment has been minimized.
This comment has been minimized.
|
Assigned to @alexcrichton |
cgwalters
force-pushed the
cgwalters:note-setenv-and-unsetenv-are-not-threadsafe
branch
from
79bda49
to
92598cd
May 13, 2015
This comment has been minimized.
This comment has been minimized.
|
Ok, pushed an update which does both of the above. |
This comment has been minimized.
This comment has been minimized.
|
Thanks @cgwalters! It looks like there's only one piece remaining, the
|
cgwalters
force-pushed the
cgwalters:note-setenv-and-unsetenv-are-not-threadsafe
branch
from
92598cd
to
44a5bf1
May 14, 2015
This comment has been minimized.
This comment has been minimized.
|
Oops, thanks. OK, now I know about |
This comment has been minimized.
This comment has been minimized.
bors
added a commit
that referenced
this pull request
May 14, 2015
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
bors
merged commit 44a5bf1
into
rust-lang:master
May 14, 2015
This comment has been minimized.
This comment has been minimized.
fweimer
commented
Nov 24, 2016
•
|
Even without low-level races, This problem would not go away if we provided thread-safe environment access at the libc layer. Therefore, I'm surprised the function isn't marked |
This was referenced Dec 3, 2016
cgwalters
referenced this pull request
Feb 18, 2017
Closed
roles/lib_openshift: Handle /usr/local/bin/oc with sudo #3413
This comment has been minimized.
This comment has been minimized.
|
@fweimer Can you use that behavior to demonstrate memory-unsafe behavior in a Rust program that does not use the |
cgwalters
referenced this pull request
Jun 2, 2017
Closed
don't use setenv() after process start #1812
This comment has been minimized.
This comment has been minimized.
|
Just for fun: from my previous comment
I just happened to notice my theoretical example exists now: https://github.com/pop-os/libparted |
cgwalters commentedApr 23, 2015
See:
https://sourceware.org/bugzilla/show_bug.cgi?id=4887#c9
https://bugs.freedesktop.org/show_bug.cgi?id=65681
I just noticed this while talking to someone who was using
os.environ['FOO'] = 'BAR'in Python and since I'm learning Rust, Iwas curious if it did anything special here (and the answer appears to
be no).
Java got this right by disallowing
setenv()from the start.