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);
     }

Reply via email to