Comment by quotemstr

Comment by quotemstr 2 days ago

34 replies

> Only if the program was written in a way that allowed for legitimate access to P1. You’re articulating this as if P1 was out of thin air; it’s not.

My program:

  if (p == P2) return p[attacker_controlled_index];
If the return statement can access P1, disjoint from P2, that's a weird execution for any useful definition of "weird". You can't just define the problem away.

Your central claim is that you can take any old C program, compile it with Fil-C, and get a memory-safe C program. Turns out you get memory safety only if you write that C program with Fil-C's memory model and its limits in mind. If someone's going to do that, why not write instead with Rust's memory model in mind and not pay a 4x performance penalty?

pizlonator 2 days ago

> that's a weird execution for any useful definition of "weird".

Weird execution is a term of art in the security biz. This is not that.

Weird execution happens when the attacker can control all of memory, not just objects the victim program rightly loaded from the heap.

> Your central claim is that you can take any old C program, compile it with Fil-C, and get a memory-safe C program.

Yes. Your program is memory safe. You get to access P1 if p pointed at P1.

You don’t get to define what memory safety means in Fil-C. I have defined it here: https://fil-c.org/gimso

Not every memory safe language defines it the same way. Python and JavaScript have a weaker definition since they both have powerful reflection including eval and similar superpowers. Rust has a weaker definition if you consider that you can use `unsafe`. Go has a weaker definition if you consider that tearing in Go leads to actual weird execution (attacker gets to pop the entire Go type system). Java’s definition is most similar to Fil-C’s, but even there you could argue both ways (Java has more unsafe code in its implementation while Fil-C doesn’t have the strict aliasing of Java’s type system).

You can always argue that someone else’s language isn’t memory safe if you allow yourself to define memory safety in a different way. That’s not a super useful line of argumentation, though it is amusing and fun

  • quotemstr 2 days ago

    You may define "memory safety" as you like. I will define "trustworthy system" as one in which the author acknowledges and owns limitations instead of iteratively refining private definitions until the limitations disappear. You can define a mathematical notation in which 2+3=9, but I'm under no obligation to accept it, and I'll take the attempt into consideration when evaluating the credibility of proofs in this strange notation.

    Nobody is trying to hide the existence of "eval" or "unsafe". You're making a categorical claim of safety that's true only under a tendentious reading of common English words. Users reading your claims will come away with a mistaken faith in your system's guarantees.

    Let us each invest according to our definitions.

    • pizlonator 2 days ago

      > I will define "trustworthy system" as one in which the author acknowledges and owns limitations instead of iteratively refining private definitions until the limitations disappear.

      You know about this limitation that you keep going on about because it’s extremely well documented on fil-c.org

      • quotemstr 2 days ago

        [Woman walking on beach at sunset, holding hands with husband]

        Voiceover: "Miracurol cures cancer."

        [Couple now laughing over dinner with friends]

        "Ask your doctor if Miracurol is right for you."

        [Same footage continues, voice accelerates]

        "In clinical trials, five mice with lymphoma received Miracurol. All five were cured. One exploded. Not tested in humans. Side effects include headache, itchiness, impotence, explosion, and death. Miracurol's cancer-free guarantee applies only to cancers covered under Miracurol's definition of cancer, available at miracurol.org. Manufacturer not responsible for outcomes following improper use. Consult your doctor."

        [Couple walking golden retriever, sun flare]

        Voiceover: "Miracurol. Because you deserve to live cancer-free."

        Patient: "I exploded."

        Miracurol: "That's extremely well documented on miracurol.org."

  • torginus 2 days ago

    Sorry to intrude on the discussion, but I have a hard time grasping how to produce the behavior mentioned by quotemstr. From what I understand the following program would do it:

        int arr1[] = {1, 2, 3, 4, 5};
        int arr2[] = {10, 20, 30, 40, 50};
        int *p1 = &arr1[1];  
        int *p2 = &arr2[2];  
        int *p = choose_between(p1,p2);
    
        //then sometime later, a function gets passed p
        // and this snippet runs
        if (p == p2) {
         //p gets torn by another thread
         return p; // this allows an illegal index/pointer combo, possibly returning p1[1]
        }
    
    Is this program demonstrating the issue? Does this execute under Fil-C's rules without a memory fault? If not, could you provide some pseudocode that causes the described behavior?
    • pizlonator 2 days ago

      No, this program doesn’t demonstrate the issue.

      You can’t access out of bounds of whatever capability you loaded.

      • quotemstr 2 days ago

        Fil-C lets programs access objects through the wrong pointer under data race. All over the Internet, you've responded to the tearing critique (and I'm not the only one making it) by alternatively 1) asserting that racing code will panic safely on tear, which is factually incorrect, and 2) asserting that a program can access memory only through its loaded capabilities, which is factually correct but a non sequitur for the subject at hand.

        You're shredding your credibility for nothing. You can instead just acknowledge Fil-C provides memory safety only for code correctly synchronized under the C memory model. That's still plenty useful and nobody will think less of you for it. They'll think more, honestly.

  • tialaramex 2 days ago

    > Rust has a weaker definition if you consider that you can use `unsafe`

    I don't see it. Rust makes the same guarantees regardless of the unsafe keyword. The difference is only that with the unsafe keyword you the programmer are responsible for upholding those guarantees whereas the compiler can check safe Rust.

    • foldr 2 days ago

      C is safe by the same logic, then? You can write safe code in anything if you don’t make mistakes.

      • tialaramex 2 days ago

        But the definition is what we're talking about, not whether you make mistakes. Of course it's important that safe Rust is checked by the compiler, but that's crucially not part of how safety is defined.

        I would guess that somebody more on the pulse of C's safety efforts could tell you whether they have a definition of memory safety for C or whether they're comfortable with an existing definition from somebody else.

dnr 2 days ago

I'm not an expert here but I have to say this feels like a very weak objection.

p points to P1. One thread reads through p. Another thread races with that and mutates p to point to P2. The result is the first thread reads from either P1 or P2 (but no other object).

This seems totally fine and expected to me? If there's a data race on a pointer, you might read one or the other values, but not garbage and not out of bounds. I mean, if it could guarantee a panic that's nice, but that's a bonus, not required for safety.