11:59 PM

Gemini Proxy


Home
Reload

thrig.me

Problematic Code

 

    #include <stdio.h>
    void
    escape(char *s, char *t)
    {
        int i, j = 0;
        for (; s[i] != '\0'; i++) {
            switch (s[i]) {
            case '\n':
                t[j++] = '\\';
                t[j++] = 'n';
                break;
            case '\t':
                t[j++] = '\\';
                t[j++] = 't';
                break;
            default:
                t[j++] = s[i];
                break;
            }
        }
        t[j] = '\0';
    }
    int
    main(void)
    {
        char s[]    = "Apples:\t\t5\nBananas:\t7\n";
        char t[100];
        char u[100];
        escape(s, t);
        printf("%s\n%s\n", s, t);
    }

bad.c

 

The main issue may be difficult to see, though if one develops "antibodies" for the bad pattern the problem is more likely to leap out at you. Without this understanding the issue may be complicated by compiler flags and various host differences, which may confuse the various people involved, much like the sensor probes in "Fifth Element" show wildly different values and thus confound analysis. 

 

    $ make bad
    cc -O2 -pipe    -o bad bad.c 
    $ for i in `jot 5`; do ./bad; done
    Segmentation fault (core dumped) 
    Segmentation fault (core dumped) 
    Segmentation fault (core dumped) 
    Segmentation fault (core dumped) 
    Segmentation fault (core dumped) 
    $ rm bad
    $ CFLAGS=-g make bad
    cc -g   -o bad bad.c 
    $ for i in `jot 5`; do ./bad; done
    Apples:         5
    Bananas:        7


    Apples:         5
    Bananas:        7


    Apples:         5
    Bananas:        7


    Apples:         5
    Bananas:        7


    Apples:         5
    Bananas:        7

    {

 

That was a lucky run for the "-g" debug flag compile; sometimes it segfaults, or might randomly leak bits of memory, which could be important clues as to what is going on. Lots of runs may be necessary if the issue is rare, which may make debugging that much more difficult. 

 

Spoilers

 

The main problematic line is that the variable "i" is set to, well, who knows what. Some might think that both "i" and "j" are set to 0 here, but only "j" is. Incorrect initialization of stack variables is a pretty common error in C, a good habit might be to always set them to something so that random stack junk or "this code is bad, kill it now" values do not get set. 

 

        int i, j = 0;

 

Less bad might be: 

 

        int i = 0, j = 0;

 

I would ditch the fiddly for loop for a while, and also use the C99 "{0}" to ensure that the arrays later on are zero'd out. Not all compilers support this. 

 

    #include <stdio.h>
    void
    escape(char *s, char *t)
    {
        int j = 0;
        while (*s) {
            switch (*s) {
            case '\n':
                t[j++] = '\\';
                t[j++] = 'n';
                break;
            case '\t':
                t[j++] = '\\';
                t[j++] = 't';
                break;
            default:
                t[j++] = *s;
                break;
            }
            s++;
        }
        t[j] = '\0';
    }
    int
    main(void)
    {
        char s[]    = "Apples:\t\t5\nBananas:\t7\n";
        char t[100] = {0};
        char u[100] = {0};
        escape(s, t);
        printf("%s\n\n%s\n", s, t);
    }

code.c

 

The "u" variable was probably there due to "failing around at debugging" due to its presence changing the memory layout and thus what the uninitialized "i" was picking up on. Additional problems include that "s" could be longer than "t" and then very bad things could happen, especially if "s" turns out to be supplied by a malicious user or remote system, though that's more complicated to deal with and of course tricky to get right… how hard could it be to allocate a string without creating a segfault or security error? 

 

Document: Done in 0.60s

Open Location

Open Location:

Security Warning

This app is a proxy between your computer and any Geminispace origin server. Although we promise not to do anything shady, you should use a real Gemini client if you want verifiable TLS encryption.

See our privacy policy for more info.

gemini-proxy v1.0.0

Here's Johnny!

gemini-proxy is a project of obsessivefacts.com
Contact: henriquez@protonmail.com

Error

This proxy only supports Gemini Protocol addresses.