Package: mc
Version: 4.6.0-4.6.1-pre1-3
Severity: grave
Tags: sarge sid security patch
I'm awfully sorry but when releasing DSA 639 I was under the impression
that the version of mc was sufficiently new and contained all security
fixes already. However, Gerardo Di Giacomo denied that, so attached
please find the patch he provided for a Debian fork which also applies
to the version in sarge = sid. I'm also attaching the patches I've
used for the update in woody.
CAN-2004-1004
Multiple format string vulnerabilities
CAN-2004-1005
Multiple buffer overflows
Linkname: [SECURITY] [DSA 639-1] New mc packages fix several vulnerabilities
URL:
http://lists.debian.org/debian-security-announce/debian-security-announce-2005/msg00017.html
Please correct the package.
Regards,
Joey
--
Ten years and still binary compatible. -- XFree86
Please always Cc to me when replying to me on the lists.
diff -u mc-4.6.0-4.6.1-pre1/debian/changelog
mc-4.6.0-4.6.1-pre1/debian/changelog
--- mc-4.6.0-4.6.1-pre1/debian/changelog
+++ mc-4.6.0-4.6.1-pre1/debian/changelog
@@ -1,3 +1,16 @@
+mc (1:4.6.0-4.6.1-pre1-3ubuntu0.1) warty-security; urgency=low
+
+ * SECURITY UPDATES: multiple vulnerabilities
+ * src/utilunix.c:
+ - Fixed a potential buffer overflow vulnerability
+ * vfs/fish.c:
+ - Fixed a potential format string vulnerability
+ * References:
+ - CAN-2004-1004
+ - CAN-2004-1005
+
+ -- Gerardo Di Giacomo <[EMAIL PROTECTED]> Mon, 14 Feb 2005 12:37:01 +0000
+
mc (1:4.6.0-4.6.1-pre1-3) unstable; urgency=low
* Polish documentation fix no longer needed.
only in patch2:
unchanged:
--- mc-4.6.0-4.6.1-pre1.orig/debian/patches/11_CAN-2004-1004_CAN-2004-1005.patch
+++ mc-4.6.0-4.6.1-pre1/debian/patches/11_CAN-2004-1004_CAN-2004-1005.patch
@@ -0,0 +1,24 @@
+diff -Nur mc-4.6.0-4.6.1-pre1.orig/src/utilunix.c
mc-4.6.0-4.6.1-pre1/src/utilunix.c
+--- mc-4.6.0-4.6.1-pre1.orig/src/utilunix.c 2005-02-14 12:23:54.358065160
+0000
++++ mc-4.6.0-4.6.1-pre1/src/utilunix.c 2005-02-14 12:30:02.910036744 +0000
+@@ -429,7 +429,7 @@
+ close (2);
+ dup (old_error);
+ close (old_error);
+- len = read (error_pipe[0], msg, MAX_PIPE_SIZE);
++ len = read (error_pipe[0], msg, MAX_PIPE_SIZE -1 );
+
+ if (len >= 0)
+ msg[len] = 0;
+diff -Nur mc-4.6.0-4.6.1-pre1.orig/vfs/fish.c mc-4.6.0-4.6.1-pre1/vfs/fish.c
+--- mc-4.6.0-4.6.1-pre1.orig/vfs/fish.c 2005-02-14 12:23:54.504042968
+0000
++++ mc-4.6.0-4.6.1-pre1/vfs/fish.c 2005-02-14 12:27:39.723804360 +0000
+@@ -232,7 +232,7 @@
+ print_vfs_message (_("fish: Waiting for initial line..."));
+ if (!vfs_s_get_line (me, SUP.sockr, answer, sizeof (answer), ':'))
+ ERRNOR (E_PROTO, -1);
+- print_vfs_message (answer);
++ print_vfs_message ("%s", answer);
+ if (strstr (answer, "assword")) {
+
+ /* Currently, this does not work. ssh reads passwords from
diff -u -p -Nr --exclude CVS mc-4.5.55.orig/vfs/fish.c mc-4.5.55/vfs/fish.c
--- mc-4.5.55.orig/vfs/fish.c 2004-10-31 08:09:30.000000000 +0100
+++ mc-4.5.55/vfs/fish.c 2004-10-31 08:30:02.000000000 +0100
@@ -222,7 +222,7 @@ open_archive_int (vfs *me, vfs_s_super *
print_vfs_message( _("fish: Waiting for initial line...") );
if (!vfs_s_get_line(me, SUP.sockr, answer, sizeof(answer), ':'))
ERRNOR (E_PROTO, -1);
- print_vfs_message( answer );
+ print_vfs_message( "%s", answer );
if (strstr(answer, "assword")) {
/* Currently, this does not work. ssh reads passwords from
--- mc-4.5.55.orig/src/utilunix.c 2001-08-14 02:55:38.000000000 +0200
+++ mc-4.5.55/src/utilunix.c 2004-12-01 12:25:11.000000000 +0100
@@ -408,7 +408,7 @@ close_error_pipe (int error, char *text)
if (len == 0) return 0; /* Nothing to show */
/* Show message from pipe */
- message (error, title, msg);
+ message (error, title, "%s", msg);
} else {
/* Show given text and possible message from pipe */
message (error, title, " %s \n %s ", text, msg);
@@ -442,7 +442,7 @@ void check_error_pipe (void)
close (error_pipe[0]);
}
if (len > 0)
- message (0, _(" Warning "), error);
+ message (0, _(" Warning "), "%s", error);
}
#endif
--- mc-4.5.55.orig/src/utilunix.c 2004-12-01 12:26:20.000000000 +0100
+++ mc-4.5.55/src/utilunix.c 2004-12-01 12:26:27.000000000 +0100
@@ -396,7 +396,7 @@ close_error_pipe (int error, char *text)
close (2);
dup (old_error);
close (old_error);
- len = read (error_pipe[0], msg, MAX_PIPE_SIZE);
+ len = read (error_pipe[0], msg, MAX_PIPE_SIZE - 1);
if (len >= 0)
msg[len] = 0;
@@ -424,7 +424,7 @@ void check_error_pipe (void)
char error[MAX_PIPE_SIZE];
int len = 0;
if (old_error >= 0){
- while (len < MAX_PIPE_SIZE)
+ while (len < MAX_PIPE_SIZE - 1)
{
fd_set select_set;
struct timeval timeout;
diff -u -p -Nr --exclude CVS mc-4.5.55.orig/src/boxes.c mc-4.5.55/src/boxes.c
--- mc-4.5.55.orig/src/boxes.c 2001-08-07 00:22:04.000000000 +0200
+++ mc-4.5.55/src/boxes.c 2004-11-30 18:57:44.000000000 +0100
@@ -584,7 +584,7 @@ static int sel_charset_button( int actio
cpname = (new_display_codepage < 0)
? _("Other 8 bit")
: codepages[ new_display_codepage ].name;
- sprintf( buf, "%-27s", cpname ); /* avoid strange bug with label
repainting */
+ g_snprintf( buf, sizeof (buf), "%-27s", cpname ); /* avoid strange bug
with label repainting */
label_set_text( cplabel, buf );
return 0;
}
diff -u -p -Nr --exclude CVS mc-4.5.55.orig/src/charsets.c
mc-4.5.55/src/charsets.c
--- mc-4.5.55.orig/src/charsets.c 2001-08-16 23:01:12.000000000 +0200
+++ mc-4.5.55/src/charsets.c 2004-11-30 19:00:23.000000000 +0100
@@ -171,7 +171,8 @@ char* init_translation_table( int cpsour
cd = iconv_open( cpdisp, cpsour );
if (cd == (iconv_t) -1) {
- sprintf( errbuf, _("Cannot translate from %s to %s"), cpsour, cpdisp );
+ g_snprintf( errbuf, sizeof (errbuf), _("Cannot translate from %s to
%s"), cpsour, cpdisp );
+
return errbuf;
}
@@ -184,7 +185,7 @@ char* init_translation_table( int cpsour
cd = iconv_open( cpsour, cpdisp );
if (cd == (iconv_t) -1) {
- sprintf( errbuf, _("Cannot translate from %s to %s"), cpdisp, cpsour );
+ g_snprintf( errbuf, sizeof (errbuf), _("Cannot translate from %s to
%s"), cpdisp, cpsour );
return errbuf;
}
diff -u -p -Nr --exclude CVS mc-4.5.55.orig/src/wtools.c mc-4.5.55/src/wtools.c
--- mc-4.5.55.orig/src/wtools.c 2001-06-20 19:12:47.000000000 +0200
+++ mc-4.5.55/src/wtools.c 2004-10-31 08:45:59.000000000 +0100
@@ -315,7 +315,7 @@ Dlg_head *message (int error, char *head
/* Setup the display information */
strcpy (buffer, "\n");
va_start (args, text);
- g_vsnprintf (&buffer [1], sizeof (buffer) - 1, text, args);
+ g_vsnprintf (&buffer [1], sizeof (buffer) - 2, text, args);
strcat (buffer, "\n");
va_end (args);
--- mc-4.5.55.orig/src/key.c 2001-08-18 21:27:31.000000000 +0200
+++ mc-4.5.55/src/key.c 2004-12-01 12:31:37.000000000 +0100
@@ -360,7 +360,8 @@ static key_def *create_sequence (char *s
}
/* The maximum sequence length (32 + null terminator) */
-static int seq_buffer [33];
+#define SEQ_BUFFER_LEN 33
+static int seq_buffer [SEQ_BUFFER_LEN];
static int *seq_append = 0;
static int push_char (int c)
@@ -368,7 +369,7 @@ static int push_char (int c)
if (!seq_append)
seq_append = seq_buffer;
- if (seq_append == &(seq_buffer [sizeof (seq_buffer)-2]))
+ if (seq_append == &(seq_buffer [SEQ_BUFFER_LEN-2]))
return 0;
*(seq_append++) = c;
*seq_append = 0;
@@ -383,7 +384,7 @@ int define_sequence (int code, char *seq
{
key_def *base;
- if (strlen (seq) > sizeof (seq_buffer)-1)
+ if (strlen (seq) > SEQ_BUFFER_LEN-1)
return 0;
for (base = keys; (base != 0) && *seq; ){
--- mc-4.5.55.orig/vfs/sfs.c 2001-08-11 06:57:17.000000000 +0200
+++ mc-4.5.55/vfs/sfs.c 2004-12-08 19:01:06.000000000 +0100
@@ -326,12 +326,13 @@ static int sfs_init (vfs *me)
}
if (!semi){
+ invalid_line:
fprintf (stderr, _("Warning: Invalid line in sfs.ini:\n%s\n"), key);
continue;
}
c = semi + 1;
- while ((*c != ' ') && (*c != '\t')) {
+ while (*c && (*c != ' ') && (*c != '\t')) {
switch (*c) {
case '1': flags |= F_1; break;
case '2': flags |= F_2; break;
@@ -341,6 +342,8 @@ static int sfs_init (vfs *me)
}
c++;
}
+ if (!*c)
+ goto invalid_line;
c++;
*(semi+1) = 0;
if ((semi = strchr (c, '\n')))
--- mc-4.5.55.orig/vfs/cpio.c 2004-10-31 08:09:30.000000000 +0100
+++ mc-4.5.55/vfs/cpio.c 2004-12-08 19:07:21.000000000 +0100
@@ -454,7 +454,8 @@ static int cpio_create_entry(vfs *me, vf
}
}
- while(name[strlen(name)-1] == PATH_SEP) name[strlen(name)-1] = 0;
+ for (tn = name + strlen (name) - 1; tn >= name && *tn == PATH_SEP; tn--)
+ *tn = 0;
if((tn = strrchr(name, PATH_SEP))) {
*tn = 0;
root = vfs_s_find_inode(me, root, name, LINK_FOLLOW, FL_MKDIR); /*
CHECKME! What function here? */
--- mc-4.5.55.orig/vfs/direntry.c 2004-12-11 10:59:05.000000000 +0100
+++ mc-4.5.55/vfs/direntry.c 2004-12-11 11:00:10.000000000 +0100
@@ -372,7 +372,7 @@ vfs_s_resolve_symlink (vfs *me, vfs_s_en
return (MEDATA->find_entry) (me, entry->dir->super->root, linkname,
follow - 1, 0);
else { /* FIXME: this does not work */
char *fullpath = vfs_s_fullpath(me, entry->dir);
- sprintf(buf, "%s/%s", fullpath, linkname);
+ snprintf(buf, sizeof(buf), "%s/%s", fullpath, linkname);
g_free (fullpath);
return (MEDATA->find_entry) (me, entry->dir->super->root, buf,
follow - 1, 0);
}
@@ -1155,7 +1155,7 @@ vfs_s_get_line (vfs *me, int sock, char
int i, status;
char c;
- for (i = 0; i < buf_len; i++, buf++){
+ for (i = 0; i < buf_len-1; i++, buf++){
if (read (sock, buf, sizeof(char)) <= 0)
return 0;
if (logfile){
--- mc-4.5.55.orig/vfs/cpio.c 2004-12-11 11:48:41.000000000 +0100
+++ mc-4.5.55/vfs/cpio.c 2004-12-11 11:49:58.000000000 +0100
@@ -306,7 +306,7 @@ static int cpio_read_oldc_head(vfs *me,
if((len = mc_read(super->u.cpio.fd, (void *)buf, HEAD_LENGTH)) <
HEAD_LENGTH)
return STATUS_EOF;
CPIO_POS(super) += len;
- buf[HEAD_LENGTH + 1] = 0;
+ buf[HEAD_LENGTH] = 0;
if(sscanf((void *)buf, "070707%6lo%6lo%6lo%6lo%6lo%6lo%6lo%11lo%6lo%11lo",
&hd.c_dev, &hd.c_ino, &hd.c_mode, &hd.c_uid, &hd.c_gid,
@@ -323,7 +323,10 @@ static int cpio_read_oldc_head(vfs *me,
name = g_malloc(hd.c_namesize);
if((len = mc_read(super->u.cpio.fd, name, hd.c_namesize)) < hd.c_namesize)
+ {
+ g_free (name);
return STATUS_EOF;
+ }
name[hd.c_namesize - 1] = '\0';
CPIO_POS(super) += len;
--- mc-4.5.55.orig/gtkedit/syntax.c 2004-10-31 08:09:30.000000000 +0100
+++ mc-4.5.55/gtkedit/syntax.c 2004-12-13 21:29:21.000000000 +0100
@@ -484,6 +484,9 @@ static char *strdup_convert (char *s)
case '}':
*p = '\004';
break;
+ case 0:
+ *p = *s;
+ return r;
default:
*p = *s;
break;