commit: 0ddee9b7d2b8dea810e252ca6a95c457876df120
Author: Sergei Trofimovich <slyfox <AT> gentoo <DOT> org>
AuthorDate: Tue May 30 20:58:32 2017 +0000
Commit: William Hubbs <williamh <AT> gentoo <DOT> org>
CommitDate: Tue May 30 21:21:23 2017 +0000
URL: https://gitweb.gentoo.org/proj/openrc.git/commit/?id=0ddee9b7
openrc-init: fix buffer overflow in init.ctl
How to reproduce 1-byte overflow:
```
$ FEATURES=-test CFLAGS="-fsanitize=address -O0 -ggdb3" emerge -1 openrc
=================================================================
==1==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fff0efd8710
at pc 0x000000402076 bp 0x7fff0efd7d50 sp 0x7fff0efd7d40
WRITE of size 1 at 0x7fff0efd8710 thread T0
#0 0x402075 (/sbin/openrc-init+0x402075)
#1 0x3cf6e2070f in __libc_start_main (/lib64/libc.so.6+0x3cf6e2070f)
#2 0x4013b8 (/sbin/openrc-init+0x4013b8)
Address 0x7fff0efd8710 is located in stack of thread T0 at offset 2432 in frame
#0 0x401cfb (/sbin/openrc-init+0x401cfb)
This frame has 3 object(s):
[32, 160) 'signals'
[192, 344) 'sa'
[384, 2432) 'buf' <== Memory access at offset 2432 overflows this variable
HINT: this may be a false positive if your program uses some custom stack
unwind mechanism or swapcontext
(longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow ??:0 ??
```
The problem here is in the code handling reads from 'init.ctl':
```
int main(int argc, char **argv) {
...
char buf[2048];
for (;;) {
/* This will block until a command is sent down the pipe... */
fifo = fopen(RC_INIT_FIFO, "r");
count = fread(buf, 1, 2048, fifo);
buf[count] = 0;
...
}
```
`buf[count] = 0;` writes outside the buffer when `fread()` returns
non-truncated read.
This fixes #138.
src/rc/openrc-init.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/rc/openrc-init.c b/src/rc/openrc-init.c
index 398259cc..003ce31f 100644
--- a/src/rc/openrc-init.c
+++ b/src/rc/openrc-init.c
@@ -195,7 +195,7 @@ int main(int argc, char **argv)
perror("fopen");
continue;
}
- count = fread(buf, 1, 2048, fifo);
+ count = fread(buf, 1, sizeof(buf) - 1, fifo);
buf[count] = 0;
fclose(fifo);
printf("PID1: Received \"%s\" from FIFO...\n", buf);