[arch-commits] Commit in mutt/trunk (4 files)

Gaëtan Bisson bisson at archlinux.org
Sun Jul 15 19:56:48 UTC 2018


    Date: Sunday, July 15, 2018 @ 19:56:48
  Author: bisson
Revision: 328695

security fixes from upstream

Added:
  mutt/trunk/0001-Properly-quote-IMAP-mailbox-names-when-un-subscribin.patch
  mutt/trunk/0002-Sanitize-POP-bcache-paths.patch
  mutt/trunk/0003-Selectively-cache-headers.patch
Modified:
  mutt/trunk/PKGBUILD

-----------------------------------------------------------------+
 0001-Properly-quote-IMAP-mailbox-names-when-un-subscribin.patch |  127 ++++++++++
 0002-Sanitize-POP-bcache-paths.patch                            |  100 +++++++
 0003-Selectively-cache-headers.patch                            |   39 +++
 PKGBUILD                                                        |   19 +
 4 files changed, 282 insertions(+), 3 deletions(-)

Added: 0001-Properly-quote-IMAP-mailbox-names-when-un-subscribin.patch
===================================================================
--- 0001-Properly-quote-IMAP-mailbox-names-when-un-subscribin.patch	                        (rev 0)
+++ 0001-Properly-quote-IMAP-mailbox-names-when-un-subscribin.patch	2018-07-15 19:56:48 UTC (rev 328695)
@@ -0,0 +1,127 @@
+From 185152818541f5cdc059cbff3f3e8b654fc27c1d Mon Sep 17 00:00:00 2001
+From: Kevin McCarthy <kevin at 8t8.us>
+Date: Sat, 7 Jul 2018 19:03:44 -0700
+Subject: [PATCH] Properly quote IMAP mailbox names when (un)subscribing.
+
+When handling automatic subscription (via $imap_check_subscribed), or
+manual subscribe/unsubscribe commands, mutt generating a "mailboxes"
+command but failed to properly escape backquotes.
+
+Thanks to Jeriko One for the detailed bug report and patch, which this
+commit is based upon.
+---
+ imap/command.c      |  5 +++--
+ imap/imap.c         |  7 +++++--
+ imap/imap_private.h |  3 ++-
+ imap/util.c         | 25 ++++++++++++++++++++-----
+ 4 files changed, 30 insertions(+), 10 deletions(-)
+
+diff --git a/imap/command.c b/imap/command.c
+index c8825981..c79d4f28 100644
+--- a/imap/command.c
++++ b/imap/command.c
+@@ -842,8 +842,9 @@ static void cmd_parse_lsub (IMAP_DATA* idata, char* s)
+ 
+   strfcpy (buf, "mailboxes \"", sizeof (buf));
+   mutt_account_tourl (&idata->conn->account, &url);
+-  /* escape \ and " */
+-  imap_quote_string(errstr, sizeof (errstr), list.name);
++  /* escape \ and ". Also escape ` because the resulting
++   * string will be passed to mutt_parse_rc_line. */
++  imap_quote_string_and_backquotes (errstr, sizeof (errstr), list.name);
+   url.path = errstr + 1;
+   url.path[strlen(url.path) - 1] = '\0';
+   if (!mutt_strcmp (url.user, ImapUser))
+diff --git a/imap/imap.c b/imap/imap.c
+index 668203b8..c3a8ffd0 100644
+--- a/imap/imap.c
++++ b/imap/imap.c
+@@ -1930,6 +1930,7 @@ int imap_subscribe (char *path, int subscribe)
+   char buf[LONG_STRING];
+   char mbox[LONG_STRING];
+   char errstr[STRING];
++  int mblen;
+   BUFFER err, token;
+   IMAP_MBOX mx;
+ 
+@@ -1951,8 +1952,10 @@ int imap_subscribe (char *path, int subscribe)
+     mutt_buffer_init (&err);
+     err.data = errstr;
+     err.dsize = sizeof (errstr);
+-    snprintf (mbox, sizeof (mbox), "%smailboxes \"%s\"",
+-              subscribe ? "" : "un", path);
++    mblen = snprintf (mbox, sizeof (mbox), "%smailboxes ",
++                      subscribe ? "" : "un");
++    imap_quote_string_and_backquotes (mbox + mblen, sizeof(mbox) - mblen,
++                                      path);
+     if (mutt_parse_rc_line (mbox, &token, &err))
+       dprint (1, (debugfile, "Error adding subscribed mailbox: %s\n", errstr));
+     FREE (&token.data);
+diff --git a/imap/imap_private.h b/imap/imap_private.h
+index 312fbfe4..349c5a49 100644
+--- a/imap/imap_private.h
++++ b/imap/imap_private.h
+@@ -301,7 +301,8 @@ char* imap_next_word (char* s);
+ time_t imap_parse_date (char* s);
+ void imap_make_date (char* buf, time_t timestamp);
+ void imap_qualify_path (char *dest, size_t len, IMAP_MBOX *mx, char* path);
+-void imap_quote_string (char* dest, size_t slen, const char* src);
++void imap_quote_string (char* dest, size_t dlen, const char* src);
++void imap_quote_string_and_backquotes (char *dest, size_t dlen, const char *src);
+ void imap_unquote_string (char* s);
+ void imap_munge_mbox_name (IMAP_DATA *idata, char *dest, size_t dlen, const char *src);
+ void imap_unmunge_mbox_name (IMAP_DATA *idata, char *s);
+diff --git a/imap/util.c b/imap/util.c
+index 914c93c3..3274a70c 100644
+--- a/imap/util.c
++++ b/imap/util.c
+@@ -608,11 +608,9 @@ void imap_qualify_path (char *dest, size_t len, IMAP_MBOX *mx, char* path)
+ }
+ 
+ 
+-/* imap_quote_string: quote string according to IMAP rules:
+- *   surround string with quotes, escape " and \ with \ */
+-void imap_quote_string (char *dest, size_t dlen, const char *src)
++static void _imap_quote_string (char *dest, size_t dlen, const char *src,
++                                const char *to_quote)
+ {
+-  static const char quote[] = "\"\\";
+   char *pt;
+   const char *s;
+ 
+@@ -625,7 +623,7 @@ void imap_quote_string (char *dest, size_t dlen, const char *src)
+ 
+   for (; *s && dlen; s++)
+   {
+-    if (strchr (quote, *s))
++    if (strchr (to_quote, *s))
+     {
+       dlen -= 2;
+       if (!dlen)
+@@ -643,6 +641,23 @@ void imap_quote_string (char *dest, size_t dlen, const char *src)
+   *pt = 0;
+ }
+ 
++/* imap_quote_string: quote string according to IMAP rules:
++ *   surround string with quotes, escape " and \ with \ */
++void imap_quote_string (char *dest, size_t dlen, const char *src)
++{
++  _imap_quote_string (dest, dlen, src, "\"\\");
++}
++
++/* imap_quote_string_and_backquotes: quote string according to IMAP rules:
++ *   surround string with quotes, escape " and \ with \.
++ * Additionally, escape backquotes with \ to protect against code injection
++ * when using the resulting string in mutt_parse_rc_line().
++ */
++void imap_quote_string_and_backquotes (char *dest, size_t dlen, const char *src)
++{
++  _imap_quote_string (dest, dlen, src, "\"\\`");
++}
++
+ /* imap_unquote_string: equally stupid unquoting routine */
+ void imap_unquote_string (char *s)
+ {
+-- 
+2.18.0
+

Added: 0002-Sanitize-POP-bcache-paths.patch
===================================================================
--- 0002-Sanitize-POP-bcache-paths.patch	                        (rev 0)
+++ 0002-Sanitize-POP-bcache-paths.patch	2018-07-15 19:56:48 UTC (rev 328695)
@@ -0,0 +1,100 @@
+From 6aed28b40a0410ec47d40c8c7296d8d10bae7576 Mon Sep 17 00:00:00 2001
+From: Kevin McCarthy <kevin at 8t8.us>
+Date: Fri, 13 Jul 2018 11:16:33 -0700
+Subject: [PATCH] Sanitize POP bcache paths.
+
+Protect against bcache directory path traversal for UID values.
+
+Thanks for Jeriko One for the bug report and patch, which this commit
+is based upon.
+---
+ pop.c | 31 +++++++++++++++++++++++++------
+ 1 file changed, 25 insertions(+), 6 deletions(-)
+
+diff --git a/pop.c b/pop.c
+index d9d95fbe..288166de 100644
+--- a/pop.c
++++ b/pop.c
+@@ -40,6 +40,25 @@
+ #define HC_FEXT		"hcache"	/* extension for hcache as POP lacks paths */
+ #endif
+ 
++/**
++ * cache_id - Make a message-cache-compatible id
++ * @param id POP message id
++ * @retval ptr Sanitised string
++ *
++ * The POP message id may contain '/' and other awkward characters.
++ *
++ * @note This function returns a pointer to a static buffer.
++ */
++static const char *cache_id(const char *id)
++{
++  static char clean[SHORT_STRING];
++
++  strfcpy (clean, id, sizeof(clean));
++  mutt_sanitize_filename (clean, 1);
++
++  return clean;
++}
++
+ /* write line to file */
+ static int fetch_message (char *line, void *file)
+ {
+@@ -205,7 +224,7 @@ static int msg_cache_check (const char *id, body_cache_t *bcache, void *data)
+   /* message not found in context -> remove it from cache
+    * return the result of bcache, so we stop upon its first error
+    */
+-  return mutt_bcache_del (bcache, id);
++  return mutt_bcache_del (bcache, cache_id (id));
+ }
+ 
+ #ifdef USE_HCACHE
+@@ -355,7 +374,7 @@ static int pop_fetch_headers (CONTEXT *ctx)
+        *        - if we also have a body: read
+        *        - if we don't have a body: new
+        */
+-      bcached = mutt_bcache_exists (pop_data->bcache, ctx->hdrs[i]->data) == 0;
++      bcached = mutt_bcache_exists (pop_data->bcache, cache_id (ctx->hdrs[i]->data)) == 0;
+       ctx->hdrs[i]->old = 0;
+       ctx->hdrs[i]->read = 0;
+       if (hcached)
+@@ -531,7 +550,7 @@ static int pop_fetch_message (CONTEXT* ctx, MESSAGE* msg, int msgno)
+   unsigned short bcache = 1;
+ 
+   /* see if we already have the message in body cache */
+-  if ((msg->fp = mutt_bcache_get (pop_data->bcache, h->data)))
++  if ((msg->fp = mutt_bcache_get (pop_data->bcache, cache_id (h->data))))
+     return 0;
+ 
+   /*
+@@ -578,7 +597,7 @@ static int pop_fetch_message (CONTEXT* ctx, MESSAGE* msg, int msgno)
+ 			MUTT_PROGRESS_SIZE, NetInc, h->content->length + h->content->offset - 1);
+ 
+     /* see if we can put in body cache; use our cache as fallback */
+-    if (!(msg->fp = mutt_bcache_put (pop_data->bcache, h->data, 1)))
++    if (!(msg->fp = mutt_bcache_put (pop_data->bcache, cache_id (h->data), 1)))
+     {
+       /* no */
+       bcache = 0;
+@@ -624,7 +643,7 @@ static int pop_fetch_message (CONTEXT* ctx, MESSAGE* msg, int msgno)
+    * portion of the headers, those required for the main display.
+    */
+   if (bcache)
+-    mutt_bcache_commit (pop_data->bcache, h->data);
++    mutt_bcache_commit (pop_data->bcache, cache_id (h->data));
+   else
+   {
+     cache->index = h->index;
+@@ -704,7 +723,7 @@ static int pop_sync_mailbox (CONTEXT *ctx, int *index_hint)
+ 	snprintf (buf, sizeof (buf), "DELE %d\r\n", ctx->hdrs[i]->refno);
+ 	if ((ret = pop_query (pop_data, buf, sizeof (buf))) == 0)
+ 	{
+-	  mutt_bcache_del (pop_data->bcache, ctx->hdrs[i]->data);
++	  mutt_bcache_del (pop_data->bcache, cache_id (ctx->hdrs[i]->data));
+ #if USE_HCACHE
+ 	  mutt_hcache_delete (hc, ctx->hdrs[i]->data, strlen);
+ #endif
+-- 
+2.18.0
+

Added: 0003-Selectively-cache-headers.patch
===================================================================
--- 0003-Selectively-cache-headers.patch	                        (rev 0)
+++ 0003-Selectively-cache-headers.patch	2018-07-15 19:56:48 UTC (rev 328695)
@@ -0,0 +1,39 @@
+From 31eef6c766f47df8281942d19f76e35f475c781d Mon Sep 17 00:00:00 2001
+From: Richard Russon <rich at flatcap.org>
+Date: Fri, 13 Jul 2018 11:33:16 -0700
+Subject: [PATCH] Selectively cache headers.
+
+Thanks to NeoMutt and Jeriko One for the patch, which was slightly
+modified to apply to the Mutt code.
+---
+ imap/util.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/imap/util.c b/imap/util.c
+index 27792944..d4cc2742 100644
+--- a/imap/util.c
++++ b/imap/util.c
+@@ -84,6 +84,7 @@ header_cache_t* imap_hcache_open (IMAP_DATA* idata, const char* path)
+   ciss_url_t url;
+   char cachepath[LONG_STRING];
+   char mbox[LONG_STRING];
++  size_t len;
+ 
+   if (path)
+     imap_cachepath (idata, path, mbox, sizeof (mbox));
+@@ -96,6 +97,12 @@ header_cache_t* imap_hcache_open (IMAP_DATA* idata, const char* path)
+     FREE (&mx.mbox);
+   }
+ 
++  if (strstr(mbox, "/../") || (strcmp(mbox, "..") == 0) || (strncmp(mbox, "../", 3) == 0))
++    return NULL;
++  len = strlen(mbox);
++  if ((len > 3) && (strcmp(mbox + len - 3, "/..") == 0))
++    return NULL;
++
+   mutt_account_tourl (&idata->conn->account, &url);
+   url.path = mbox;
+   url_ciss_tostring (&url, cachepath, sizeof (cachepath), U_PATH);
+-- 
+2.18.0
+

Modified: PKGBUILD
===================================================================
--- PKGBUILD	2018-07-15 19:12:20 UTC (rev 328694)
+++ PKGBUILD	2018-07-15 19:56:48 UTC (rev 328695)
@@ -4,7 +4,7 @@
 
 pkgname=mutt
 pkgver=1.10.0
-pkgrel=2
+pkgrel=3
 pkgdesc='Small but very powerful text-based mail client'
 url='http://www.mutt.org/'
 license=('GPL')
@@ -12,11 +12,24 @@
 arch=('x86_64')
 optdepends=('smtp-forwarder: to send mail')
 depends=('gpgme' 'ncurses' 'openssl' 'libsasl' 'gdbm' 'libidn' 'mime-types' 'krb5')
-source=("http://ftp.mutt.org/pub/mutt/${pkgname}-${pkgver}.tar.gz"{,.asc})
+source=("http://ftp.mutt.org/pub/mutt/${pkgname}-${pkgver}.tar.gz"{,.asc}
+        '0001-Properly-quote-IMAP-mailbox-names-when-un-subscribin.patch'
+        '0002-Sanitize-POP-bcache-paths.patch'
+        '0003-Selectively-cache-headers.patch')
 sha256sums=('0215b5f90ef9cc33441a6ca842379b64412ed7f8da83ed68bfaa319179f5535b'
-            'SKIP')
+            'SKIP'
+            '2baf7f86317d2d395a73010e62bf68c9f4bfcb2c60f7ca89a77fd0518ee9c521'
+            '108b43a4f1c9ff4011a37653a48bb1ce4b6863ba7c10d550249a231a22b07472'
+            'e9be583baaf2e23363c180dbea85a64b0b4c9c578953f328bb96a93ad9b4b7a5')
 validpgpkeys=('8975A9B33AA37910385C5308ADEF768480316BDA')
 
+prepare() {
+	cd "${srcdir}/${pkgname}-${pkgver}"
+	patch -p1 -i ../0001-Properly-quote-IMAP-mailbox-names-when-un-subscribin.patch
+	patch -p1 -i ../0002-Sanitize-POP-bcache-paths.patch
+	patch -p1 -i ../0003-Selectively-cache-headers.patch
+}
+
 build() {
 	cd "${srcdir}/${pkgname}-${pkgver}"
 	./configure \



More information about the arch-commits mailing list