• JPJ (unregistered)

    If you intentionally weaken a cryptographic system so that some people can bypass it, you've created a system which anyone can bypass.

    This is all too easy. Simply analyze traffic according to RFC 3514, and only apply proper cryptography to all legit usecases. Problem solved.

  • no (unregistered) in reply to JPJ

    RFC 3514 is just about the stupidest idea I've ever read. It is a utopian pipe dream which may never be accomplished because of its fundamental incompatibility with how the world works. The document has no basis in anything even approaching reality, for one simple reason: There are simply too many preexisting devices which do not implement it and will never be realistically updated to conform to RFC 3514. Bolting it on after the fact in the form of an extension is impossible, the evil bit should have been in IPv4 from the very start.

  • Hans (unregistered)

    Do note the publication date of that RFC 3514

  • (nodebb) in reply to no

    RFC 3514 is just about the stupidest idea I've ever read.

    Before saying things like this, please read the RFC very carefully, especially the date of publication. Geeeeeezussss.

  • (nodebb)

    Everybody gotta be a noob sometime. Today is no's day.

  • Vera (unregistered) in reply to Steve_The_Cynic

    I think No may be joking, given the comment about the Evil Bit at the very end.

  • (nodebb) in reply to WTFGuy

    Such a shame there's no "like" button on these "forums"...

  • Sauron (unregistered)

    JUST NERD EVEN HARDER!

  • Officer Johnny Holzkopf (unregistered)

    In the beginning, there was FILE *f1 = 0;, which should have been FILE *f1 = NULL; to illustrate that FILE * is a pointer. If you do it, do it consistently (even if it's not needed, dangerous, or plain wrong). Later on, regrding MY_FREE: Checking a pointer for not being NULL before calling free() isn't actually required. Current malloc implementations simply do nothing if you call free(NULL);, as seen in the manual, so no problem. Additionally, it seems like someone believes that calling p = NULL; will magically erase from memory whatever p has been pointing to, violating the rule that thou shalt nott touch ay pointre after free()ing... but hey, don't worry, next week they're going to build secure online banking software!

  • Pabz (unregistered) in reply to Steve_The_Cynic

    I suspect that "no" understands all this and was trying to joke just as much as "JPJ". It does beg the question though - should the evil bit have been added to IPv6 from the start? :)

  • (nodebb)

    Wait, nobody has pointed out Remy's mistake yet? The function does not always return 0!

  • RLB (unregistered)

    Actually, there is something wrong with checking a pointer for NULL before freeing it: as anyone who knows C knows, free(NULL) is guaranteed to be a safe no-op.

  • JPJ (unregistered) in reply to no

    It could still be basis for a campaign for a safer internet by some not-so-tech-savvy politician. I wish to see that some day :)

  • (nodebb)

    I always thought that the genius idea of RFC 3514 (though it's not really explicit in the document) was that it meant any evil packets without the evil bit set were malformed and should be dropped. That is, it made your firewall's job easier, in that it could just look at the evil bit, since if the evil bit wasn't set correctly (and the packet was actually evil even though the bit wasn't set), it could be treated just like any other malformed packet.

    (Just to be clear, this is written with tongue firmly in cheek)

  • (nodebb) in reply to Planar

    True enough. One time in 256 it returns 1...

  • (nodebb) in reply to RLB

    I think the guarantee about free(NULL) was a later add-on, not in the original C, so many old-timers used their own checks, and the habit persists to this day.

  • Argle (unregistered)

    For security reasons, this comment has been double ROT13 encrypted.

  • (nodebb) in reply to Barry Margolin

    I hope not, seeing as how free(NULL) is a no-op at least as long ago as C89...

  • Duston (unregistered) in reply to Steve_The_Cynic

    There are some of us who were born well before 1989.

  • Robin (unregistered)

    The code may be horrible, but these guys get extra geek points for naming their "random number" function after the Latin word for "dice". (Although yeah, I know, dice don't tend to have a "0" face...)

  • (nodebb) in reply to Robin

    No it's actually correct, it's just "alea" since it always returns the same value. If it returned a varying value they'd have had to call it alea_jacta_est().

  • (nodebb) in reply to Argle

    That's the answer! Change the law so civilians can only use ROT13, up to 1024 cycles. Government and military are permitted to use up to 2048 cycles of ROT26 to reflect their stronger security needs. If civilians use ROT26, it's clearly criminal behaviour so should be punished with prison terms up to life or longer.

  • houstonprogram (unregistered)

    "This is a crucial topic in today’s digital age! Secure cryptography is essential for protecting our data and maintaining privacy. What are some of the latest advancements in cryptography that you think everyone should be aware of?"

    https://graciejiujitsuwesthouston.com/programs/

  • Guessed (unregistered)

    it's almost a guarantee that this program has undefined behavior in there, someplace

    Nothing "almost" about it. The UB is in the code you've shown:

        MY_FREE(v);
        return(v);
    

    MY_FREE() is semantically equivalent to free(), and while a function cannot modify its argument (the bits in v are unchanged), it can modify its interpretation: After free(v), the pointer value becomes "indeterminate" (formally the same as an uninitialized local variable), and reading an indeterminate value (e.g. to return it, as in this case) has undefined behavior.

  • (nodebb) in reply to Duston

    Yes. I know. I'm one of them. But >35 years is a long time to hold a bad habit.

  • (nodebb) in reply to zomgwtf

    Actually, no, it doesn't. If the byte read from /dev/random happens to equal UCHAR_MAX, the function returns 1 instead of zero.

  • Naomi (unregistered) in reply to Guessed

    That's not true at all. It's UB to dereference a free'd pointer, but you can still read the pointer itself - it just isn't very useful. (Maybe you want to assert that something was properly nulled out, or remove a pointer from a memoization table...?)

  • (nodebb)

    Since MY_FREE is in all caps, it was clearly originally written as a macro. It probably used something ugly like do { ... } while(0) and somebody changed it because it looked ugly and they had heard that functions are better than macros and so they converted it, but not properly.

  • (nodebb)

    Regardless of whether free() contains it's own null check, the example shown in this code of null check followed by calling free() only on non-nulls still fails the multi-threaded atomicity requirement. Another thread could sneak in and free the pointer between your check and your free().

    Which is probably why free() itself does the null check for you. I'm hoping those implementations have been atomic since Ye Olden Dayes but I can't be arsed to check for real.

  • Wildstar (unregistered)

    How about we just don't let fascists run the country.

  • Duke of New York (unregistered)

    Neither Research Unix nor Bell 32V Unix had a null check in free, but the standard does mandate it, so it is entirely correct to rely on it in new code.

    I recall the NetBSD crew doing legacy cleanup on the SSL code and, when they noticed code to work around the absence of memmove in SunOS, they said "too bad for SunOS" and deleted it. Life's too short to spend it coding around laggards.

  • Duke of New York (unregistered)

    And yes, I meant OpenBSD.

  • Guessed (unregistered) in reply to Naomi

    That's not true at all.

    Except it is. The relevant part of the C standard is 6.2.4 Storage durations of objects. In clause 2 it first says

    If an object is referred to outside of its lifetime, the behavior is undefined.

    ... which is the (hopefully common-sense) part you mentioned (you can't dereference a pointer to a freed object). But then it goes on to say:

    The value of a pointer becomes indeterminate when the object it points to reaches the end of its lifetime.

    That's the pointer value itself, not the object it refers to. "Indeterminate" is defined in 3.17.2/1 as:

    indeterminate value - either an unspecified value or a trap representation

    And 6.2.6.1/5 explains that reading a value that corresponds to a trap representation has UB:

    Certain object representations need not represent a value of the object type. If the stored value of an object has such a representation and is read by an lvalue expression that does not have character type, the behavior is undefined. [...] Such a representation is called a trap representation.

    Which means this code has potentially undefined behavior:

    char *p = malloc(42);
    free(p);
    if (p) {  // UB!
        ...
    }
    

    If the malloc succeeds, then p is initialized to point to an object whose lifetime ends at free(p). This in turn makes the bits stored in p an "indeterminate value", which is allowed to be a trap representation. The check in the first line reads from p as a pointer (i.e. not a character type), so if p is a trap representation at this point, the program has undefined behavior.

  • ismo (unregistered) in reply to Guessed

    How the free call could modify value of p ? the free is called by value ( as in C always) , not by reference like in C++. Sthe p can not be changed to trap value. Or has C really call by ref in this case ? Its been almost 40 years since I seriouslu wrote any C, C++ more than 30 years.

  • (nodebb) in reply to ismo

    If MY_FREE was originally a macro (which would be following a common naming convention), then it would be absolutely able to modify the variable. Which is why you can't always convert macros to functions, no matter how much it would increase type safety.

Leave a comment on “Secure Cryptography”

Log In or post as a guest

Replying to comment #:

« Return to Article