|
|
Log in / Subscribe / Register

DeVault: Announcing the Hare programming language

DeVault: Announcing the Hare programming language

Posted May 2, 2022 17:25 UTC (Mon) by wtarreau (subscriber, #51152)
In reply to: DeVault: Announcing the Hare programming language by stephanlachnit
Parent article: DeVault: Announcing the Hare programming language

Static linking is sufficient when you don't care about the security of your dependencies, which, sadly, tends to become a tradition nowadays, for the profit of attackers :-(

Sure it's convenient to only scp an executable and see it working. But when it ships with a massively outdated version of openssl, libpng, zlib and what not, this is a serious concern.

As much as I hate the breakage caused by poorly managed shared libraries, and for having hated them for years, I now do prefer to use them in programs that I distribute so that users are autonomous when it comes to applying important updates.


to post comments

DeVault: Announcing the Hare programming language

Posted May 4, 2022 0:40 UTC (Wed) by ilammy (subscriber, #145312) [Link] (12 responses)

Arguably, only OpenSSL is a “serious” concern for static linking here. Things like libpng and zlib are security liabilities only due to C legacy. Most of the application dependencies can be statically linked, provided they are written in memory-safe languages.

DeVault: Announcing the Hare programming language

Posted May 4, 2022 9:05 UTC (Wed) by wtarreau (subscriber, #51152) [Link] (8 responses)

> Most of the application dependencies can be statically linked, provided they are written in memory-safe languages.

It's impressive to see how many people actually believe that memory-safe==secure and non-memory-safe==insecure, in particular when you consider that optimizing compilers can *remove* some of your security checks that are "proven" to be useless. It's fortunate that the world of secure microcontrollers is not run by people thinking like this or we'd be doomed with secure devices giving off their secrets at the first voltage hickup!

There must have been some strongly directed brainwashing somewhere, because quite frankly, a huge part of security issues that are met every day are not just memory-safety issues, and spreading the belief that you can ignore library updates for components that are written using "memory-safe" languages is dangerous.

For example I remember discussing with people who told me they were storing credit card numbers in "numbers" in their language, without knowing what the language limits were. Just do that in JS and you only have 53 bits of mantissa. It turns out that 2^53 is too short to store all those possible numbers, it will only accurately represent numbers up to 9007 1992 5475 0991 and above this odd and even numbers will be represented as the same even one. So in such applications if your credit card number is below that value it will be accurately represented, but above this, if it's odd, the next number will be used, and if it's even, you may be charged for the previous number's orders, or be accusated in a court of having been present in a shop or leaving a parking because that number was seen there. Such bugs can have huge impacts (and are hard to fix later) and never involve anything related to memory safety.

This is just a simple example showing how programmer's deliberate ignorance about computing can have important security impacts that the compiler may not always solve. Most of the time the trouble is much more limited, such as being trivially sensitive to DoS attacks by not having any idea what amount of resource a given operation will require (such as the fun sites that propose you to test some regex and that are often found down after some jerk sent complex ones that can take hours or days to evaluate).

DeVault: Announcing the Hare programming language

Posted May 4, 2022 10:23 UTC (Wed) by ilammy (subscriber, #145312) [Link] (5 responses)

I never said one should ignore updates in the dependencies, or that there can never be security vulnerabilities in libraries written in memory-safe languages. Please stop dealing in absolutes.

Of course, vulnerabilities are not limited to RCE caused by undefined behavior due to memory safety issues. Just about any library parsing anything might have an implementation bug which can causes a DoS, which is a vulnerability too. Just about any “big” library might be having some obscure feature that indirectly calls into shell. But that’s hardly on the same scale of impact as, say, heartbleed – not of the “drop everything and patch your software yesterday” scale. Nor it has the same occurrence and memory-safety-related bugs in non-memory-safe libraries.

Look at zlib, for example. Here are some stats for zlib-related CVEs published since 2019:

in zlib:
  3 missing bounds check (CVE-2018-25032, CVE-2021-26025, CVE-2018-20819)
  1 double free (CVE-2019-12874)
  1 unbounded memory allocation (CVE-2020-11612)

in zlib usage:
  2 DLL hijack (CVE-2021-26807, CVE-2020-11081)

(Speaking of which, shared libraries themselves open up possibilities for attacks, like DLL hijacking.)

Using shared libraries does not magically free you from keeping track of your dependencies that might wreck havoc, or from maintaining your systems. The purported argument for shared libraries is that “distro maintainers” (= people who are not us) are going to take care of the updates, so that we don’t have to rebuild and update our applications. But who’s going to install these updates to shared libraries? Who is going to restart affected services? Who is going to figure out which systems need an update? When all these details are considered, the static/shared choice is so minuscule that it’s hardly important.

I believe the main benefit of shared libraries currently is that you don’t have to deal with whatever obscure build system is used by the dependency. Because chances are, if it’s distributed as a shared library – not in source-only form, already integrated in your application – then the library does need a “build system” in the first place.

DeVault: Announcing the Hare programming language

Posted May 4, 2022 12:16 UTC (Wed) by LtWorf (subscriber, #124958) [Link] (2 responses)

> who’s going to install these updates to shared libraries? Who is going to restart affected services? Who is going to figure out which systems need an update?

There is an amazing tool called "apt-get" that does all of those things.

DeVault: Announcing the Hare programming language

Posted May 4, 2022 12:41 UTC (Wed) by ilammy (subscriber, #145312) [Link] (1 responses)

That’s the point. Replacing binaries is only a part of the problem.

APT is not going to get my system have up-to-date repositories that I trust configured all by itself, someone has to administer that configuration.

APT is not going to package my software all by itself, someone has to write all that Debian packaging, telling dpkg that ”my-app.service” is from “my-app” package which depends on “libssl” and needs to be restarted when its dependencies are updated.

APT is not going to decide for me which instance need an update, which instances are safe to update and in what sequence. Someone has to define that, then orchestrate actual update, juggle the load, etc.

APT is not going to test the update for me before it’s deployed. Someone has to try it out first in a safe environment.

Sure, there are automated tools for switching over one binary for another, sending signals, waiting on pipes, etc. But that specific part is just a small fraction of what “update” entails. And those tools do not really care whether they have to replace “libvulnerable.so” or statically linked “vulnerable-executable”.

DeVault: Announcing the Hare programming language

Posted May 5, 2022 9:33 UTC (Thu) by pabs (subscriber, #43278) [Link]

There is needrestart (and needrestart-session) for automatically restarting services after shared library upgrades (and Perl/Python/etc modules). It works fairly well, the main issue right now is cgroupsv2 breaks things a little bit.

https://github.com/liske/needrestart
https://github.com/liske/needrestart-session
https://github.com/liske/needrestart/issues/235

DeVault: Announcing the Hare programming language

Posted May 4, 2022 13:31 UTC (Wed) by wtarreau (subscriber, #51152) [Link] (1 responses)

> The purported argument for shared libraries is that “distro maintainers” (= people who are not us) are going to take care of the updates, so that we don’t have to rebuild and update our applications. But who’s going to install these updates to shared libraries?

No that's not the main point. The main point is that you can limit the amount of stuff you have to replace. When you upgrade your libc to get rid of the ghost vulnerability, all your executables are fixed at once. When they're all static, you have to replace all your executables with the ones the distro vendor had nicely rebuilt for you. And that can take quite some time when there are lots of packages, up to several days for mainstream distros, which will significantly delay the deployment of the fix in field. In addition it means that when there are multiple vendors (local builts counting as a "vendor" as well), it then becomes extremely difficult to make sure the system is fixed.

But fixes deployment is an entire class of problems on its own, there's no single nor excellent solution, there are pros and cons everywhere. Shared libs come with a number of cons but none of them is dramatic, and a number of pros that can keep you out of the mud. Static libs tend to navigate between much worse and much better, and will occasionally leave you a bad feeling.

DeVault: Announcing the Hare programming language

Posted May 4, 2022 15:11 UTC (Wed) by farnz (subscriber, #17727) [Link]

It's a trade-off. Shared linking forces you to consider backwards and forwards compatibility in your ABI, where static linking permits you to get away with only caring about API.

Static linking also enables library consumers to simply test for the behaviour they expect; with shared linking, you need to be confident that the set of library behaviour you depend upon is by design, and not a happy accident. If you don't take the ABI contracts seriously (on either side of the ABI), then you get broken by mistake as an implementation detail you happened to care about changes.

Tooling to help get this right sort-of exists (abidiff for example), but it's more than just the things that can be checked by tooling that matter - for example, if I change a library so that you now need to call mylib_free on a pointer I returned, where previously free worked, you're going to be surprised.

DeVault: Announcing the Hare programming language

Posted May 4, 2022 10:46 UTC (Wed) by excors (subscriber, #95769) [Link] (1 responses)

> It's fortunate that the world of secure microcontrollers is not run by people thinking like this or we'd be doomed with secure devices giving off their secrets at the first voltage hickup!

Obviously code that's claiming to provide security features needs to be very careful about all types of bug, because any bug might undermine its security guarantees. But the previous comment mentioned libpng and zlib, which (like the vast majority of libraries) don't claim to provide any security guarantees beyond the API's implicit promise that you can provide them with untrusted input and they'll return either an error code or some valid image/buffer. Memory safety isn't the whole of that, e.g. if libpng supported a "read from local filesystem" chunk type then that'd be a security vulnerability when decoding untrusted images - but unsafe features like that are usually pretty obvious from the documentation or from superficial code review, whereas memory safety errors are ubiquitous in C and very hard to find, so they deserve a lot of attention.

(And even competent people writing critically-important secure firmware would benefit from tools that help with memory safety, to avoid e.g. the use-after-free bug in Apple's SecureROM which broke the secure boot process (https://habr.com/en/company/dsec/blog/472762/).)

> It turns out that 2^53 is too short to store all those possible numbers, it will only accurately represent numbers up to 9007 1992 5475 0991 and above this odd and even numbers will be represented as the same even one. So in such applications if your credit card number is below that value it will be accurately represented, but above this, if it's odd, the next number will be used, and if it's even, you may be charged for the previous number's orders, or be accusated in a court of having been present in a shop or leaving a parking because that number was seen there.

Credit card numbers have a check digit (e.g. https://en.wikipedia.org/wiki/Luhn_algorithm), so an off-by-one error will just result in an invalid card number - it won't be mistaken for someone else's valid card. Still a serious bug that should be fixed, of course, but not really a security bug.

DeVault: Announcing the Hare programming language

Posted May 6, 2022 0:49 UTC (Fri) by khim (subscriber, #9252) [Link]

<font class="QuotedText">&gt; Still a serious bug that should be fixed, of course, but not really a security bug.</font>

<p>I think you are mistaken. Lots of cards use <a href="https://en.wikipedia.org/wiki/Payment_card_number#Issuer_...(IIN)">more than 16 digits</a>. What and how JS would do to these numbers is quite a question.</p>

DeVault: Announcing the Hare programming language

Posted May 6, 2022 6:39 UTC (Fri) by flussence (guest, #85566) [Link] (2 responses)

The safest way to handle OpenSSL with static linking is to keep all TLS stuff in a separate process, but that goes for dynamic linking too.

DeVault: Announcing the Hare programming language

Posted May 6, 2022 18:46 UTC (Fri) by wtarreau (subscriber, #51152) [Link] (1 responses)

> The safest way to handle OpenSSL with static linking is to keep all TLS stuff in a separate process, but that goes for dynamic linking too.

That only moves the problem one point away, since it's that program that has to be rebuilt and upgraded all the time instead. Plus for plenty of situations, you're doing extra work due to this. Double-copy of the data between the processes, and extra latency if the process is used as a side-car instead of a proxy. This can only work when TLS is not at all the business of your program and you'd rather defer watching the library updates to another specialized process. That's what plenty of application servers do by deferring that work to a reverse-proxy. It just turns out that my main activity is to develop that reverse-proxy ;-)

DeVault: Announcing the Hare programming language

Posted May 13, 2022 23:56 UTC (Fri) by flussence (guest, #85566) [Link]

Alright, I'll give you the rest of that, but I don't think copying data between processes has been a hard problem for something like a decade now? (or else Linux would be absolutely awful for s/openssl/opengl/)


Copyright © 2026, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds