Skip to content

Casepath buffer overflow #2

@minerscale

Description

@minerscale

The restriction that "r must have strlen(path) + 2 bytes" is incorrect as it fails to account for the null terminator. This is easiest way to see this is to walk through casepath on "a", which would have been alloca'd 3 bytes:

// r must have strlen(path) + 2 bytes
static int casepath(char const *path, char *r) // In the case that path is "a", the length of r is 3 bytes.
{
    size_t l = strlen(path);
    char *p = alloca(l + 1);
    strcpy(p, path);
    size_t rl = 0;
    
    DIR *d;
    if (p[0] == '/')
    {
        d = opendir("/");
        p = p + 1;
    }
    else
    {
        d = opendir(".");
        r[0] = '.'; // we take this path an initialise the first two bytes to 'a' and a null.
        r[1] = 0;
        rl = 1;
    }
    
    int last = 0;
    char *c = strsep(&p, "/"); // strsep doesn't find a '/' and sets c to the entire string. In this case "a"
    while (c)
    {
        if (!d) // We successfully opened "."
        {
            return 0;
        }
        
        if (last) // last is still 0
        {
            closedir(d);
            return 0;
        }
        
        r[rl] = '/'; // rl is 1, r is now "./" (no null terminator)
        rl += 1;
        r[rl] = 0; // r is "./" (null terminated)
        
        struct dirent *e = readdir(d); // reading the current directory "."
        while (e)
        {
            if (strcasecmp(c, e->d_name) == 0)
            { // found file 'a'
                // copy 'a' to where the null terminator was (the last byte in our buffer)
                // AND a null terminator in the next byte of the buffer!?!
                strcpy(r + rl, e->d_name);
                ...

This means that the requirement for casepath's buffer size is actually three bytes more than path's strlen(), since strcpy writes a null to the next byte.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions