1. 14
  1. 2

    We already have a few security-relevant clippy lints, and there’s work to increase their numbers. Personally I feel that this approach is severly undervalued, because while it may not find all issues, it finds a lot of them at very modest cost.

    1. 2

      Why the focus on “language memory safety”? That’s a solution and not a problem. I think the real problem is securing legacy codebases.

      Here’s another line of research which I think has more promise, in the sense that it is an extension of techniques that are already deployed and work, and is significantly less effort than migrating code:

      Clean application compartmentalization with SOAAP

      It’s basically decomposing your application into separate processes, which the DJB paper I quoted also talks about:

      Some thoughts on security after ten years of qmail 1.0

      So instead of rewriting code, you break it up and reason explicitly about communication between mutually untrusting processes. This is difficult in general, but the SOAAP paper shows that tools can help. (Just like migration tools could help with Rust, which also has its place.)

      IMO rewriting or translating working code line-by-line to a different language should be a last resort. Re-architecting applications has all sorts of other benefits too besides security, e.g. now there are interfaces you can test against!

      https://dl.acm.org/citation.cfm?id=2813611

      Application compartmentalization, a vulnerability mitigation technique employed in programs such as OpenSSH and the Chromium web browser, decomposes software into isolated components to limit privileges leaked or otherwise available to attackers. … We present a new conceptual framework embodied in an LLVM-based tool: the Security-Oriented Analysis of Application Programs (SOAAP) that allows programmers to reason about compartmentalization using source-code annotations (compartmentalization hypotheses). We demonstrate considerable benefit when creating new compartmentalizations for complex applications, and analyze existing compartmentalized applications to discover design faults and maintenance issues arising from application evolution.

      Some more papers that cite the SOAAP one:

      https://scholar.google.com/scholar?cites=3191133289210944167&as_sdt=2005&sciodt=0,5&hl=en


      Also, as far as I understand, C2Rust/Corrode basically do some mechanical grunt work for you, which is good. They make it so you don’t have to use two different build tools, and you can gradually but manually migrate code from the unsafe to the safe dialect.

      But they have no insight to the structure of your application or problem, which is pretty much impsosible via static analysis of C code.

      C code is not very well typed which I imagine puts some pretty strict limits on this. I ran into a similar problem when translating OSH to Oil. Without reliable types, you can only do some basic syntactic translation. And if you’re not changing the semantics of the program, then it’s not a very useful translation. It’s leaving all the hard work for you to do manually !

      So that is why Oil is now a “mode” on top of OSH. It’s not an exact analogy but I think there are similar problems there. Changing legacy from code from one language to another is hard! It could be easy to convince yourself that you did something because the syntax looks different, but that is superficial.

      http://www.oilshell.org/blog/2019/08/22.html#toc_1

      1. 2

        I wonder if there’s a place for a language that is much closer to C++ but with Rust’s approach to memory management, to make porting easier.

        1. 5

          /wave

          I’m skeptical there is a better arrangement of these things, but I invite anyone who wants to help to expirement with finding a better way! Just know the road has been paved with a lot of failed attempts.

          I became a Rust booster not because it’s the perfect language, or even the one I love the most, but because I believe it does the best job balancing safety and practicality.

          Or for the Stargate fans: “many have said that, but you are the first I’ve believes could actually do it”.

          1. 4

            There are many things Rust could do to ease porting from C++. For example, C++ has function overloading and Rust doesn’t. Entirely trivial (just use different names for different overloads), but also annoying when you are trying to do 1:1 port.

            1. 1

              Unfortunately, overloading and type inference make an explosive combination. Rust at best could allow overloading by number of arguments (equivalent to optional arguments).

            2. 2

              And the community which went viral or something like it. Rare to achieve that kind of momentum in a language. Especially sustained momentum. The new language probably won’t re-create it just based on the odds. Better to build on what has momentum.

              1. 2

                hi!

                I keep trying to use Rust for random projects and hitting walls. I’ll keep trying to find something I like it for. Chances are I’ll end up doing some of it as work since more and more of the components of the day job are moving to it.

              2. 4

                Yeah I wonder about this too. It seems like ownership is here to stay, with:

                It seems like D and Nim have closer C interop than Swift or Rust, although I don’t have direct experience with them.

                One thing I like about Zig is it integrates with C almost as well as C++ does (by including libclang in the compiler):

                https://ziglang.org/#Zig-is-also-a-C-compiler

                So maybe someone can think of a way to bolt it on to Zig (optionally?), although it seems pretty far from its philosophy.

                The problem I see is that ownership is a global property like other kinds of type safety. I think you need a language that also easily supports isolated processes and message passing to have a migration path (and i agree that the migration path in Rust is asking a lot).

                That is, basically follow the approach in:

                Some thoughts on security after ten years of qmail 1.0

                with some parts of the codebase in legacy languages and some in a safe language like Rust.

                1. 3

                  Safety is on my radar. I’m on board with the “safer unsafe” thing, for example.

                  I’m also planning on doing some research into making Zig safer. I have a plan for the following kinds of unsafety:

                  • Use-after-free
                  • Invalid pointer cast

                  Some stuff is already solved (has safety protections), such as:

                  • Wrong union field access
                  • Double await / invalid resume
                  • Integer arithmetic overflow
                  • more

                  The goal is to end up with a short list of undefined behavior that is not safety-protected.

                  All that said, the caveat is that safety protections can be entirely disabled in any given scope. I would expect most projects to keep the safety on, identify bottlenecks, and then disable safety in the bottlenecks only.

                  Applications that could ship with all safety off would be:

                  • Shrink-wrapped video games
                  • Well-tested & fuzzed embedded device code, that needs to have small binary size & needs to max out the hardware performance
                  • Software that is going to run in a sandbox anyway, for example the WebAssembly target
                2. 3

                  I would love to have slices in C! Just this one thing alone would improve C safety, and help automatic porting of C to Rust.

                  But given that C99 tried to specify array sizes (with very awkward syntax int size, arr[static size]), and after 20 years nobody uses it, compilers don’t do anything useful with it, I don’t have any hope for anything like this catching on and making a dent.

                  But there’s a proposal for lifetime annotations in C++: https://herbsutter.com/2018/09/20/lifetime-profile-v1-0-posted/

                  1. 2

                    Check out D. One of its main developers wrote C++ compilers, knew its pain points all too well, and wanted C++‘s power without all its problems. It’s GC by default with no-GC allowed for performance. It compiles really fast. They’re recently looking at how to merge Rust-like safety into it.

                    Edit: I don’t know if they’re close enough for porting or anything. It’s just one of best C++ alternatives I know.