1 |
commit: 0ddee9b7d2b8dea810e252ca6a95c457876df120 |
2 |
Author: Sergei Trofimovich <slyfox <AT> gentoo <DOT> org> |
3 |
AuthorDate: Tue May 30 20:58:32 2017 +0000 |
4 |
Commit: William Hubbs <williamh <AT> gentoo <DOT> org> |
5 |
CommitDate: Tue May 30 21:21:23 2017 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/openrc.git/commit/?id=0ddee9b7 |
7 |
|
8 |
openrc-init: fix buffer overflow in init.ctl |
9 |
|
10 |
How to reproduce 1-byte overflow: |
11 |
|
12 |
``` |
13 |
$ FEATURES=-test CFLAGS="-fsanitize=address -O0 -ggdb3" emerge -1 openrc |
14 |
|
15 |
================================================================= |
16 |
==1==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fff0efd8710 |
17 |
at pc 0x000000402076 bp 0x7fff0efd7d50 sp 0x7fff0efd7d40 |
18 |
WRITE of size 1 at 0x7fff0efd8710 thread T0 |
19 |
#0 0x402075 (/sbin/openrc-init+0x402075) |
20 |
#1 0x3cf6e2070f in __libc_start_main (/lib64/libc.so.6+0x3cf6e2070f) |
21 |
#2 0x4013b8 (/sbin/openrc-init+0x4013b8) |
22 |
|
23 |
Address 0x7fff0efd8710 is located in stack of thread T0 at offset 2432 in frame |
24 |
#0 0x401cfb (/sbin/openrc-init+0x401cfb) |
25 |
|
26 |
This frame has 3 object(s): |
27 |
[32, 160) 'signals' |
28 |
[192, 344) 'sa' |
29 |
[384, 2432) 'buf' <== Memory access at offset 2432 overflows this variable |
30 |
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext |
31 |
(longjmp and C++ exceptions *are* supported) |
32 |
SUMMARY: AddressSanitizer: stack-buffer-overflow ??:0 ?? |
33 |
``` |
34 |
|
35 |
The problem here is in the code handling reads from 'init.ctl': |
36 |
|
37 |
``` |
38 |
int main(int argc, char **argv) { |
39 |
... |
40 |
char buf[2048]; |
41 |
for (;;) { |
42 |
/* This will block until a command is sent down the pipe... */ |
43 |
fifo = fopen(RC_INIT_FIFO, "r"); |
44 |
count = fread(buf, 1, 2048, fifo); |
45 |
buf[count] = 0; |
46 |
... |
47 |
} |
48 |
``` |
49 |
|
50 |
`buf[count] = 0;` writes outside the buffer when `fread()` returns non-truncated read. |
51 |
|
52 |
This fixes #138. |
53 |
|
54 |
src/rc/openrc-init.c | 2 +- |
55 |
1 file changed, 1 insertion(+), 1 deletion(-) |
56 |
|
57 |
diff --git a/src/rc/openrc-init.c b/src/rc/openrc-init.c |
58 |
index 398259cc..003ce31f 100644 |
59 |
--- a/src/rc/openrc-init.c |
60 |
+++ b/src/rc/openrc-init.c |
61 |
@@ -195,7 +195,7 @@ int main(int argc, char **argv) |
62 |
perror("fopen"); |
63 |
continue; |
64 |
} |
65 |
- count = fread(buf, 1, 2048, fifo); |
66 |
+ count = fread(buf, 1, sizeof(buf) - 1, fifo); |
67 |
buf[count] = 0; |
68 |
fclose(fifo); |
69 |
printf("PID1: Received \"%s\" from FIFO...\n", buf); |