Skip to content
Advertisement

Is the sscanf function in the Linux kernel susceptible to buffer overflow attacks?

From what I understand, a typical buffer overflow attack occurs when an attack overflows a buffer of memory on the stack, thus allowing the attacker to inject malicious code and rewrite the return address on the stack to point to that code.

This is a common concern when using functions (such as sscanf) that blindly copy data from one area to another, checking one for a termination byte:

char str[8];                               /* holds up to 8 bytes of data */
char *buf = "lots and lots of foobars";    /* way more than 8 bytes of data */
sscanf(buf, "%s", str);                    /* buffer overflow occurs here! */

I noticed some sysfs_ops store functions in the Linux kernel are implemented with the Linux kernel’s version of the sscanf function:

static char str[8];    /* global string */
static ssize_t my_store(struct device *dev,
                        struct device_attribute *attr,
                        const char *buf, size_t size)
{
        sscanf(buf, "%s", str);    /* buf holds more than 8 bytes! */
        return size;
}

Suppose this store callback function is set to a writable sysfs attribute. Would a malicious user be able to intentionally overflow the buffer via a write call?

Normally, I would expect guards against buffer overflow attacks — such as limiting the number of bytes read — but I see none in a good number of functions (for example in drivers/scsi/scsi_sysfs.c).

Does the implementation of the Linux kernel version of sscanf protect against buffer overflow attacks; or is there another reason — perhaps buffer overflow attacks are impossible given how the Linux kernel works under the hood?

Advertisement

Answer

The Linux sscanf() is vulnerable to buffer overflows; inspection of the source shows this. You can use width specifiers to limit the amount a %s is allowed to write. At some point your str must have had copy_from_user() run on it as well. It is possible the user space to pass some garbage pointer to the kernel.

In the version of Linux you cited, the scsi_sysfs.c does have a buffer overflow. The latest version does not. The committed fix should fix the issue you see.

Advertisement