News for hackers. Stuff that matters.
Re:Glibc getaddrinfo stack-based buffer overflow by rtpg on Tuesday February 16, 2016 @10:20AM (#11110358)
Are there any big efforts to rewrite glibc in something like rust? ... Is that a thing that is even possible? An in-place replacement library for dynamic or static linking.

I'm really worried that I still hear about buffer overflows in this day and age. Of all the libraries in the world, glibc should probably be written in some subset of Idris that compiles into 100% safe C. We have the technology to move to this now

Re:Glibc getaddrinfo stack-based buffer overflow by 102030485868 on Tuesday February 16, 2016 @11:12AM (#11110802)
I'm not sure how likely that'll be. It's definitely possible, but I think there are going to be a few hurdles. The main one being, symbol versioning.

This is important if you export multiple symbols for a function, that is, have a program that depends on a specific implementation of a function. That could mean you depend on different versions of the same library ("functionname@@VERSION_1, functionname@@VERSION_2"), or completely different implementations of a function ("functionname@@IMPL_X_VER_1", "functionname@@IMPL_Y_VER_2").

Wait a second. That seems like a strange feature to want, right? Well. It's particularly useful for runtime library fun stuff. LD_PRELOAD in a library that magically changes the implementation of function. A cool example of this is of preeny[1], a collection of libraries to help with debugging.

Additionally, it's useful for replacing libraries that would depend on C implementations without having to recompile them, though some preloading magic at runtime may be required.

This is only the thing, for me at least, that's blocking for making Rust system libraries. Now, any sane person may say, "Cargo will take care of versions and stuff", and that's true. Sadly, that's not the case if you ever want to use those nice and safe Rust libraries from C though.

Though, I may be completely wrong about the state of symbol versioning in Rust. I simply ran 'nm -g libopenssl.so' on sfackler's rust-openssl project and failed to see any @@<version> in the output -- that is specifically being exported, and not re-exported, by libopenssl. There may be better libraries to use, but eh.

I could be completely wrong on this though. I've been mainly going off of what I read here[2], and here[3] (alternatively, for a more in-depth version, try here[4]).

TL;DR: symbol versioning may not be a thing.

Disclaimer: I've had to use symbol versioning pretty heavily, so it's important to me. I could also be completely wrong about Rust not having it.

[1]: https://github.com/zardus/preeny [2]: https://gcc.gnu.org/wiki/SymbolVersioning [3]: https://www.akkadia.org/drepper/symbol-versioning [4]: https://www.akkadia.org/drepper/dsohowto.pdf

Re:Glibc getaddrinfo stack-based buffer overflow by kimundi on Wednesday February 17, 2016 @04:16AM (#11116453)
The default name mangling of Rust library symbols is already kinda versioned because it includes a hash of the library, so two different versions of a library can coexist at the same time.

As far explicitly using the symbol versioning scheme you mentioned, you can do it with an attribute today:

https://play.rust-lang.org/?gist=92be155702d53c6411b2&versio...

(Disclaimer: I haven't actually compiled this as a dynamic library and checked, but its what that attribute is for, and the names seem to be used verbatim in the ASM output)

Re:Glibc getaddrinfo stack-based buffer overflow by 102030485868 on Wednesday February 17, 2016 @12:46PM (#11119643)
Woah, I didn't know that is a thing. Thank you!

It seems as if symbol versioning in Rust is nicer than in C. I'll have to play around with that a little bit.

I'm hoping I never to have to deal with writing version scripts or inline assembly again -- or at least having to write less.

Re:Glibc getaddrinfo stack-based buffer overflow by kimundi on Wednesday February 17, 2016 @05:46PM (#11122166)
Note that I'm not really familiar enough with versioned symbols to know whether there is much more to it than just a specially formatted name.
Re:Glibc getaddrinfo stack-based buffer overflow by autoreleasepool on Tuesday February 16, 2016 @11:21AM (#11110876)
I'm not trying to be rude, but I'm sorry...

Are you seriously suggesting that rewriting an implementation of the C standard library in a language that isn't C is something that makes any bit of sense?

I think you have a fundemental understanding of the roll the C-standard library plays in the C language. Not to mention UNIX in general.

Maybe you're suggesting we need an OS based in Rust instead of C (which is more reasonable), but in that case why wouldn't you use Rust's standard library as the backbone of that system?

Let me put it this way, if the GNU/Linux C standard library gets rewritten in Rust or Idris (sigh... seriously?) I will switch to Windows 10 with default settings for the rest of my life. I would rather have the NSA log my every key stroke than participate in a community where that is considered a good idea.

Re:Glibc getaddrinfo stack-based buffer overflow by umanwizard on Tuesday February 16, 2016 @11:33AM (#11110984)
Your post is just a bunch of pathos and doesn't explain why you actually think it's a bad idea.

There's no technical reason why the C standard library can't be written in a language other than C. Lots of language libraries are written in languages other than the one they're primarily used with and work fine.

Re:Glibc getaddrinfo stack-based buffer overflow by autoreleasepool on Tuesday February 16, 2016 @11:59AM (#11111246)
I mean, what problem is this solving?

There's no technical reason why it can't be done, true. It's still a hilariously bad idea that would never succeed. That's aside from the fact that's a completely pointless wheel-reinventing endeavor. Rewrites in general are pretty difficult to justify.

Sorry, I guess my aggressively pragmatic side is showing today. The idea is really dumb.

To be honest, "Let's rewrite the C standard library in Rust" is one of the worst pieces of bikeshedding drivel I've ever read. And I like Rust 100 times more than I like C.

Re:Glibc getaddrinfo stack-based buffer overflow by zebra1287 on Tuesday February 16, 2016 @05:34PM (#11113665)
It will be finished together with GNU HURD.
Re:Glibc getaddrinfo stack-based buffer overflow by theseoafs on Wednesday February 17, 2016 @03:55AM (#11116344)
The problem that it's solving is security vulnerabilities like this one.
Re:Glibc getaddrinfo stack-based buffer overflow by arielb1 on Tuesday February 16, 2016 @11:28AM (#11110941)
Rust can have the same ABI as C - rewriting NSS in Rust should not pose ABI problems.
Re:Glibc getaddrinfo stack-based buffer overflow by autoreleasepool on Tuesday February 16, 2016 @12:06PM (#11111299)
It's still completely pointless. How would mmap be any different if it was implemented in Rust rather than in C? You need unsafe to implement it! The safety mechanisms are practically useless at such a low level.

Wrap existing C with safe Rust, not the other way around! We don't rewrite unsafe C code in Unsafe Rust so that it can be called from all the unsafe C code in UNIX. Such a translation is so pointless and error prone.

I can't even believe I'm the one being called backwards here.

Re:Glibc getaddrinfo stack-based buffer overflow by dbaupp on Tuesday February 16, 2016 @01:53PM (#11112195)
> How would mmap be any different if it was implemented in Rust rather than in C? You need unsafe to implement it! The safety mechanisms are practically useless at such a low level.

They're definitely not. The power of Rust is not avoiding all `unsafe` ever, but wrapping that unsafe into finite-scope, safe wrappers. Something like mmap would presumably interface with the OS's internal memory management routines, which would definitely have to have `unsafe` somewhere since they're hitting the hardware, but it seems very reasonable for the amount of unsafe exposed to much reduced (possibly even to zero). See, for instance, http://os.phil-opp.com/modifying-page-tables.html . Basically, as soon as you're above the absolute raw hardware level, you can start introducing extra help to reduce unsafety/catch bugs.

In any case, code inside `unsafe` still benefits from all the conventional Rust checks, e.g. iterating over a slice won't go out of bounds due to a typo in the loop even inside `unsafe`, nor will references accidentally become dangling. (Of course, the `unsafe` block may do something explicitly that causes either of these problems, but this exact same risk is pervasive in all C code, rather than just around explicitly marked areas.)

> Wrap existing C with safe Rust, not the other way around! We don't rewrite unsafe C code in Unsafe Rust so that it can be called from all the unsafe C code in UNIX. Such a translation is so pointless and error prone.

Note that this is exactly what is done now, the features of Rust for making safe interfaces makes Rust often a far nicer way to use C interfaces than C itself, without overhead (IMO, of course). See http://blog.rust-lang.org/2015/04/24/Rust-Once-Run-Everywher... , for example. Of course, zero-overhead Rust is only as safe as the C code it wraps, it can't (in general) protect against the C code not correctly implementing its stated contract(s).

Re:Glibc getaddrinfo stack-based buffer overflow by tomjakubowski on Tuesday February 16, 2016 @02:41PM (#11112559)
It seems hard (impossible?) to write a safe, full-featured mmap wrapper in Rust, because of the potential for multiple processes sharing mutable access to the memory and defeating Rust's aliasing checks.

Maybe you could separately map shared RefCells to guard the pages returned by the mmap wrapper? If the region is backed by a file, you'd need to check those RefCells on every IO access too, though.

Re:Glibc getaddrinfo stack-based buffer overflow by eddyb on Tuesday February 16, 2016 @03:21PM (#11112856)
What you can do for mmap is have several abstractions (or one using generics and phantom types), one for each different set of usecases, with different access modes.

Examples would be:

* read-only: &ROMemMap -> &[u8]

* read-write: &mut RWMemMap -> &mut [u8]

* write-only: fn set(self: &mut WOMemMap, i: usize, b: u8),

or more generally: &mut WOMemMap -> &mut [WriteOnly<u8>] where WriteOnly<T> has fn set(&mut self, T)

Now for the shared case, consider this: aliasing rules can be avoided with atomic operations, i.e. Arc<AtomicUsize> is shared and can be safely (atomically) read/written by multiple threads.

In the multi-process case, you could provide an atomic API, although we don't currently seem to expose byte-level atomics (likely not present on some platforms) so if you wanted to write a demo you'd need to use the unstable intrinsics atm.

FWIW restricted to single-threaded code, this results in the Cell get/set API which is not hardware-atomic but cannot overlap with other accesses to the same memory, as Cell doesn't implement Share so any threading abstraction will block you from doing any kind of sharing of Cells.

That is, you can share &[Cell<u8>] pointing to any bag of bytes that sits in read-write memory, and anything in the same thread can read or write to it, safely.

Re:Glibc getaddrinfo stack-based buffer overflow by dbaupp on Tuesday February 16, 2016 @08:45PM (#11114565)
I was more focusing on implementing the internals of mmap, since that's what I assumed the question was. For that task, the actual memory/pointer returned is essentially a black-box (i.e. it's never read nor written by mmap itself), mmap is just interacting with the operating system.

However, as you say, exposing a safe mmap version for libraries to call is a different problem with different difficulties. eddyb's sibling suggestion of teasing out the multiple entangled uses of mmap sounds like a good one, although someone would have to experiment with it to be sure.

Re:Glibc getaddrinfo stack-based buffer overflow by autoreleasepool on Tuesday February 16, 2016 @02:42PM (#11112572)
Practically useless was a bit of a stretch. Unsafe rust is definitely safer than plain C or Assembly. I admit I was a bit riled up after reading the "compile to asm.js" comment.

Cool stuff though, I really hope rust catches fire soon. I love that it has revitalized the appeal of implementing operating system level projects like text editors and shells. I never would have wanted to try and write a windowing system before Rust. Now that's something I'm actively investigating for fun.

Re:Glibc getaddrinfo stack-based buffer overflow by umanwizard on Tuesday February 16, 2016 @04:42PM (#11113337)
To add to what others have said: mmap is a system call; it's not something provided by libc.
Re:Glibc getaddrinfo stack-based buffer overflow by arielb1 on Tuesday February 16, 2016 @01:35PM (#11112054)
You need unsafe to implement the C API part of a DNS resolver, but the API can be given a safe wrapper without much effort. Then parsing and buffer management bugs would occur only in safe code and only affect it.
Re:Glibc getaddrinfo stack-based buffer overflow by pjmlp on Tuesday February 16, 2016 @11:45AM (#11111118)
Are you are that Visual Studio C library is written in C++ with extern "C" and for Microsoft C is legacy, with .NET Native and C++ with compiler static analysis being the way forward?
Re:Glibc getaddrinfo stack-based buffer overflow by autoreleasepool on Tuesday February 16, 2016 @11:54AM (#11111191)
IIRC, that's because it's a C++ library, not a real C library. Aside from a few exceptions, it only includes the parts of the C standard that are required by the C++ standard. Hence the dismal C99 support on that platform.
Re:Glibc getaddrinfo stack-based buffer overflow by pjmlp on Tuesday February 16, 2016 @03:54PM (#11113047)
As I mentioned, C is legacy for Microsoft.

The way forward for C on Windows from Microsoft own SDK is to use the clang frontend + Visual C++ backend, or another C compiler from someone else.

Re:Glibc getaddrinfo stack-based buffer overflow by autoreleasepool on Tuesday February 16, 2016 @04:04PM (#11113114)
I definitely support that initiative. The more C++ programmers we can get to stop writing C the better.
Re:Glibc getaddrinfo stack-based buffer overflow by pjmlp on Tuesday February 16, 2016 @05:12PM (#11113533)
Me too.

Yes, C++ is as unsafe as C, given its copy-paste compatibility, but at least it provides the tools to program safely (if one chooses to) and the C++ community cares much more about safety than the C one.

Re:Glibc getaddrinfo stack-based buffer overflow by lmm on Tuesday February 16, 2016 @10:39AM (#11110522)
It would be a wasted effort. Anything that's using glibc (directly) is written in C and therefore inherently unsafe. There are only two kinds of programs written in C: those that need to do unsafe things and those whose developers don't care about safety. Better to look to building systems that don't need to run any C code (see the recent fuss around unikernels).
Re:Glibc getaddrinfo stack-based buffer overflow by qb45 on Tuesday February 16, 2016 @11:39AM (#11111047)
> Anything that's using glibc (directly) is written in C

... and together with stuff using glibc (indirectly) constitutes 99.99% of your software.

How much software/languages implement their own DNS resolver instead of just calling libc? How about syscall wrappers?

Re:Glibc getaddrinfo stack-based buffer overflow by lmm on Tuesday February 16, 2016 @12:03PM (#11111266)
The JVM looks to have its own implementation. I imagine .net would be the same. There's ocaml-dns for unikernel-deployed OCaml.

A managed language generally doesn't give you direct access to syscalls at all. In rust you can perform them without having to go via C.

Re:Glibc getaddrinfo stack-based buffer overflow by zwetan on Tuesday February 16, 2016 @01:50PM (#11112163)
With Redtamarin (based on AVM2), there is a native library which sole purpose is to give direct access to C and other syscalls.

For ex with getaddrinfo: https://gist.github.com/zwetan/0c047d36542cc6979652

I know because I did it on purpose, even if it managed code written in AS3 you don't want to reinvent getaddrinfo, you want to reuse it "as is" as much as possible.

Re:Glibc getaddrinfo stack-based buffer overflow by gpderetta on Tuesday February 16, 2016 @12:45PM (#11111660)
Note that DNS lookup doesn't require any syscall other than normal socket i/o, which is available on any non toy language.

One possible reason why java might implements its own name resolution is because it wants to do async name resolution which is not possible (at least portably) via getaddrinfo and friends.

Re:Glibc getaddrinfo stack-based buffer overflow by spc476 on Wednesday February 17, 2016 @12:48AM (#11115623)
Yes, but you still need to encode the questions and decode the answers. Existing libraries that do this are pretty dismal.

(Dismal enough that I ended up writing my own DNS encoding/decoding library (https://github.com/spc476/SPCDNS) with the aim of being easy to use as well as safe. It assumes nothing about the incoming packet and does extensive validation (enough that it found bugs in other DNS libraries). It also avoids dynamic memory allocations. It's used at work in two projects that get heavy use (millions of DNS queries a day) and so far has performed without incident, so well written C code is possible.)

Re:Glibc getaddrinfo stack-based buffer overflow by fpoling on Tuesday February 16, 2016 @12:03PM (#11111267)
The problem is not C as one can compile C into NaCl or asm.js and get memory safe code. One can also use a number of static checkers. The real problem is that even this is not done in cases when using C is a must due to project nature.
Re:Glibc getaddrinfo stack-based buffer overflow by gpderetta on Wednesday February 17, 2016 @05:09AM (#11116751)
Compiling to NaCl or asm.js doesn't make an arbitrary C program memory safe. It "merely" prevents any memory safety failure to affect anything outside the container.

This is different from, for example, java bytecode which is verified and guaranteed to be memory safe.

This is not a mere technicality: an heartbleed vulnerable version of openssl compiled on top of asm.js or NaCl would still leak secret information.

edit: typo

Re:Glibc getaddrinfo stack-based buffer overflow by fpoling on Wednesday February 17, 2016 @01:41PM (#11120146)
Both asm.js and NaCl guarantee execution stack integrity and allow jumps only at predefined targets in code making exploiting bugs like this highly problematic. Data-only exploits are hard and in asm.js case they are father limited as access outside of the memory leads to program termination.

On the other hand memory safety does not prevent bugs like Heartbleed or resent OpenSSH key leak. As the underling issue is related to broken reuse of a cached buffer, such code can be written in Java or even Rust just as well.

Re:Glibc getaddrinfo stack-based buffer overflow by gpderetta on Thursday February 18, 2016 @03:18AM (#11124411)
Sure, but these are (very effective) mitigation techniques, but still do not guarantee memory safety.

You are right that Heartbleed is not a memory safety issue, I should have been more careful. I just wanted an example of an exploit that doesn't need to escape the process boundary to cause damage.