3 ms·
Do you think that e.g. the Rust bindings to libgit2 or OpenSSL or libc also need to prove that the entire C library being bound is 100% thread and memory safe a
by geofft 6y ago
Do you think that e.g. the Rust bindings to libgit2 or OpenSSL or libc also need to prove that the entire C library being bound is 100% thread and memory safe and free of bugs in order to expose safe wrappers?
- masklinn 6y agoKinda? It needs to ensure that whatever preconditions those libraries have which are not reflected in their API because the languages they use don't allow for it are never broken. So let's say a libgit function takes a pointer (for an array) and an index, the rust bindings must ensure that the pointer is valid and the index is within the array. Will there be bugs and things which will be missed? Likely, after all we've seen that in pure-rust unsafe code, including the standard library. But the library "can't" just yolo and expose the entire thing as-is through a safe interface. As in technically it can do that just fine, but that's completely unsound even if it's effectively never called incorrectly.
- geofft 6y agoSo, if you restrict yourself to looking just at the API and not the implementation, it seems to me that if your library operates entirely on non-pointer C++ types (e.g., it takes in a std::string and returns an std::string), a program could automatically determine that and call the binding "safe". Would that be enough? I agree that the program should not automatically generate "safe" bindings that take pointers, because in Rust, creating and passing around raw pointers is safe but actually using them is safe. But if, let's say, you have an API that consists entirely of integers, bools, std::strings, and structs and classes thereof, what additional things would you need to check to be confident calling the binding safe? (Sure, there are weird cases here like "this function takes a long, casts it to a pointer, and dereferences it," but I assume those are uncommon enough that you'll see if you're about to create or use auto-generated bindings to such a function. I suppose there could be "this function takes an std::string and an index, and the index must be less than the length or it's UB" - are those common enough that they make this endeavor questionable?)
- masklinn 6y ago> So, if you restrict yourself to looking just at the API and not the implementation, it seems to me that if your library operates entirely on non-pointer C++ types (e.g., it takes in a std::string and returns an std::string), a program could automatically determine that and call the binding "safe". Would that be enough? My understanding is that this is the idea behind cxx: high-level C++ types are considered "safe", and so functions which use these are assumed to be safe. Whether this is sufficient is the debate you see upthread. > But if, let's say, you have an API that consists entirely of integers, bools, std::strings, and structs and classes thereof, what additional things would you need to check to be confident calling the binding safe? The entire codebase, because even with no parameters at all, C++ can do thing which Rust considers wildly unsafe. Like manipulating global state, possibly across functions (there are entire libraries which work on that principle). Put an other way, a "safe rust" function is reentrant, thread-safe and does not cause UB given any input. By this definition, it is not possible to know that a C(++) function is safe without going through its source with a microscope.
- geofft 6y agoRight, that's what I was getting at - is it inappropriate to publish safe bindings for C libraries that you have not rigorously audited and fuzzed? (I mean, it would be really cool if we rigorously audited and fuzzed all these C libraries, so I'm not completely opposed to this!)