You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
100 lines
3.4 KiB
100 lines
3.4 KiB
From 6aed28b40a0410ec47d40c8c7296d8d10bae7576 Mon Sep 17 00:00:00 2001 |
|
From: Kevin McCarthy <kevin@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) |
|
M_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 |
|
|
|
|