--- Begin Message ---
Package: moria
Version: 5.6-2
Severity: important
Tags: patch
Dear Maintainer,
Hi.
There is a buffer overflow problem about moria which causes abort in
some cases. Unfortunatly, this abort is not happend on Debian 7.4 but
be happend on Ubuntu 12.04. But I think that there is a buffer
overflow problem about moria on Debian 7.4 too.
A difference is that Ubuntu's EGLIBC uses /usr/include/string3.h but
Debian not. In string3.h, strcpy is defined as inline function and
calls __strcpy_chk which will check destination buffer length.
When running gcc command with -O2 option, string3.h will be included.
There are extern strcpy in string.h and inline strcpy in string3.h, and
GCC will try to use inline strcpy.
When running moria on Ubuntu 12.04, __strcpy_chk will detect buffer
overflow problem.
$ moria # which has debug symbol
Aborted (core dumped)
$ sudo chown <me>:<me> core
$ gdb moria core
<snip>
Program terminated with signal 6, Aborted.
#0 0xb7723416 in __kernel_vsyscall ()
(gdb) bt
#0 0xb7723416 in __kernel_vsyscall ()
#1 0xb7553526 in kill () from /lib/i386-linux-gnu/libc.so.6
#2 0x08071592 in signal_handler ()
#3 <signal handler called>
#4 0xb7723416 in __kernel_vsyscall ()
#5 0xb75531df in raise () from /lib/i386-linux-gnu/libc.so.6
#6 0xb7556825 in abort () from /lib/i386-linux-gnu/libc.so.6
#7 0xb759039a in ?? () from /lib/i386-linux-gnu/libc.so.6
#8 0xb7629eb5 in __fortify_fail () from /lib/i386-linux-gnu/libc.so.6
#9 0xb7628c8a in __chk_fail () from /lib/i386-linux-gnu/libc.so.6
#10 0xb7627fbd in __strcpy_chk () from /lib/i386-linux-gnu/libc.so.6
#11 0x08052a6f in read_times ()
#12 0x08049795 in main ()
abort() is called from below strcpy in read_times. This strcpy calls
__strcpy_chk(days[6], in_line, __builtin_object_size(days[6])).
(void) strcpy(days[6], in_line);
in_line, which is read from /etc/moria-hours, has 30 byte string with
in_line[28] being '\n' and in_line[29] being '\0'. But days[n] has
only 29 byte buffer which's days[n][28] is initialized as '\0'. Before
copying in_line[29] to days[n][29], __strcpy_chk detects day's buffer
be overflowed and moria is aborted.
BTW, moria uses days[n] from days[n][0] to days[n][27] and not use
days[28].
int check_time()
{
<snip>
register struct tm *tp;
<snip>
tp = localtime(&clock_var);
if (days[tp->tm_wday][tp->tm_hour+4] == 'X')
return TRUE;
<snip>
}
So, replacing strcpy to strncpy with 'sizeof(days[n]) - 1' argument
is one way to resolve this problem.
diff -uprN moria-5.6.org/source/files.c moria-5.6/source/files.c
--- moria-5.6.org/source/files.c 2008-10-14 08:44:36.000000000 +0900
+++ moria-5.6/source/files.c 2014-02-13 21:41:28.929041000 +0900
@@ -126,19 +126,19 @@ void read_times()
if (strlen(in_line) > 3)
{
if (!strncmp(in_line, "SUN:", 4))
- (void) strcpy(days[0], in_line);
+ (void) strncpy(days[0], in_line, sizeof(days[0]) - 1);
else if (!strncmp(in_line, "MON:", 4))
- (void) strcpy(days[1], in_line);
+ (void) strncpy(days[1], in_line, sizeof(days[1]) - 1);
else if (!strncmp(in_line, "TUE:", 4))
- (void) strcpy(days[2], in_line);
+ (void) strncpy(days[2], in_line, sizeof(days[2]) - 1);
else if (!strncmp(in_line, "WED:", 4))
- (void) strcpy(days[3], in_line);
+ (void) strncpy(days[3], in_line, sizeof(days[3]) - 1);
else if (!strncmp(in_line, "THU:", 4))
- (void) strcpy(days[4], in_line);
+ (void) strncpy(days[4], in_line, sizeof(days[4]) - 1);
else if (!strncmp(in_line, "FRI:", 4))
- (void) strcpy(days[5], in_line);
+ (void) strncpy(days[5], in_line, sizeof(days[5]) - 1);
else if (!strncmp(in_line, "SAT:", 4))
- (void) strcpy(days[6], in_line);
+ (void) strncpy(days[6], in_line, sizeof(days[6]) - 1);
}
(void) fclose(file1);
}
Regards.
-- System Information:
Debian Release: 7.4
APT prefers stable-updates
APT policy: (500, 'stable-updates'), (500, 'stable')
Architecture: i386 (i686)
Kernel: Linux 3.2.0-4-686-pae (SMP w/4 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Versions of packages moria depends on:
ii libc6 2.13-38+deb7u1
ii libncurses5 5.9-10
moria recommends no packages.
moria suggests no packages.
-- no debconf information
diff -uprN moria-5.6.org/source/files.c moria-5.6/source/files.c
--- moria-5.6.org/source/files.c 2008-10-14 08:44:36.000000000 +0900
+++ moria-5.6/source/files.c 2014-02-13 21:41:28.929041000 +0900
@@ -126,19 +126,19 @@ void read_times()
if (strlen(in_line) > 3)
{
if (!strncmp(in_line, "SUN:", 4))
- (void) strcpy(days[0], in_line);
+ (void) strncpy(days[0], in_line, sizeof(days[0]) - 1);
else if (!strncmp(in_line, "MON:", 4))
- (void) strcpy(days[1], in_line);
+ (void) strncpy(days[1], in_line, sizeof(days[1]) - 1);
else if (!strncmp(in_line, "TUE:", 4))
- (void) strcpy(days[2], in_line);
+ (void) strncpy(days[2], in_line, sizeof(days[2]) - 1);
else if (!strncmp(in_line, "WED:", 4))
- (void) strcpy(days[3], in_line);
+ (void) strncpy(days[3], in_line, sizeof(days[3]) - 1);
else if (!strncmp(in_line, "THU:", 4))
- (void) strcpy(days[4], in_line);
+ (void) strncpy(days[4], in_line, sizeof(days[4]) - 1);
else if (!strncmp(in_line, "FRI:", 4))
- (void) strcpy(days[5], in_line);
+ (void) strncpy(days[5], in_line, sizeof(days[5]) - 1);
else if (!strncmp(in_line, "SAT:", 4))
- (void) strcpy(days[6], in_line);
+ (void) strncpy(days[6], in_line, sizeof(days[6]) - 1);
}
(void) fclose(file1);
}
diff -uprN moria-5.6.org/source/files.c moria-5.6/source/files.c
--- moria-5.6.org/source/files.c 2008-10-14 08:44:36.000000000 +0900
+++ moria-5.6/source/files.c 2014-02-13 21:41:28.929041000 +0900
@@ -126,19 +126,19 @@ void read_times()
if (strlen(in_line) > 3)
{
if (!strncmp(in_line, "SUN:", 4))
- (void) strcpy(days[0], in_line);
+ (void) strncpy(days[0], in_line, sizeof(days[0]) - 1);
else if (!strncmp(in_line, "MON:", 4))
- (void) strcpy(days[1], in_line);
+ (void) strncpy(days[1], in_line, sizeof(days[1]) - 1);
else if (!strncmp(in_line, "TUE:", 4))
- (void) strcpy(days[2], in_line);
+ (void) strncpy(days[2], in_line, sizeof(days[2]) - 1);
else if (!strncmp(in_line, "WED:", 4))
- (void) strcpy(days[3], in_line);
+ (void) strncpy(days[3], in_line, sizeof(days[3]) - 1);
else if (!strncmp(in_line, "THU:", 4))
- (void) strcpy(days[4], in_line);
+ (void) strncpy(days[4], in_line, sizeof(days[4]) - 1);
else if (!strncmp(in_line, "FRI:", 4))
- (void) strcpy(days[5], in_line);
+ (void) strncpy(days[5], in_line, sizeof(days[5]) - 1);
else if (!strncmp(in_line, "SAT:", 4))
- (void) strcpy(days[6], in_line);
+ (void) strncpy(days[6], in_line, sizeof(days[6]) - 1);
}
(void) fclose(file1);
}
--- End Message ---