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.