isync

mailbox synchronization program
git clone https://git.code.sf.net/p/isync/isync
Log | Files | Refs | README | LICENSE

commit 7979782676cfeb3e631271ce3d2f44f6566e2615
parent a846ab054d1ff6a48c7424aed701ee14431f00bc
Author: Oswald Buddenhagen <ossi@users.sf.net>
Date:   Mon, 21 Jun 2021 11:35:24 +0200

limit maildir nesting depth

this is a cheap way to catch symlink loops. 10 seems like a reasonable
limit, as it's unlikely that anyone would be able to actually work with
such a deeply nested mailbox tree.

fixes debian bug #990117.

Diffstat:
Msrc/drv_maildir.c | 14++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/src/drv_maildir.c b/src/drv_maildir.c @@ -395,7 +395,7 @@ static int maildir_list_inbox( maildir_store_t *ctx, int flags, const char *base static int maildir_list_path( maildir_store_t *ctx, int flags, const char *inbox ); static int -maildir_list_recurse( maildir_store_t *ctx, int isBox, int flags, +maildir_list_recurse( maildir_store_t *ctx, int isBox, int flags, int depth, const char *inbox, uint inboxLen, const char *basePath, uint basePathLen, char *path, int pathLen, char *name, int nameLen ) { @@ -417,6 +417,12 @@ maildir_list_recurse( maildir_store_t *ctx, int isBox, int flags, closedir( dir ); return -1; } + if (++depth > 10) { + // We do the other checks first to avoid confusing error messages for files. + error( "Maildir error: path %s is too deeply nested. Symlink loop?\n", path ); + closedir( dir ); + return -1; + } while ((de = readdir( dir ))) { const char *ent = de->d_name; if (ent[0] == '.' && (!ent[1] || (ent[1] == '.' && !ent[2]))) @@ -464,7 +470,7 @@ maildir_list_recurse( maildir_store_t *ctx, int isBox, int flags, add_string_list( &ctx->boxes, name ); path[pl] = 0; name[nl++] = '/'; - if (maildir_list_recurse( ctx, isBox + 1, flags, inbox, inboxLen, basePath, basePathLen, path, pl, name, nl ) < 0) { + if (maildir_list_recurse( ctx, isBox + 1, flags, depth, inbox, inboxLen, basePath, basePathLen, path, pl, name, nl ) < 0) { closedir( dir ); return -1; } @@ -485,7 +491,7 @@ maildir_list_inbox( maildir_store_t *ctx, int flags, const char *basePath ) add_string_list( &ctx->boxes, "INBOX" ); return maildir_list_recurse( - ctx, 1, flags, NULL, 0, basePath, basePath ? strlen( basePath ) - 1 : 0, + ctx, 1, flags, 0, NULL, 0, basePath, basePath ? strlen( basePath ) - 1 : 0, path, nfsnprintf( path, _POSIX_PATH_MAX, "%s/", ctx->conf->inbox ), name, nfsnprintf( name, _POSIX_PATH_MAX, "INBOX/" ) ); } @@ -502,7 +508,7 @@ maildir_list_path( maildir_store_t *ctx, int flags, const char *inbox ) if (maildir_ensure_path( ctx->conf ) < 0) return -1; return maildir_list_recurse( - ctx, 0, flags, inbox, inbox ? strlen( inbox ) : 0, NULL, 0, + ctx, 0, flags, 0, inbox, inbox ? strlen( inbox ) : 0, NULL, 0, path, nfsnprintf( path, _POSIX_PATH_MAX, "%s", ctx->conf->path ), name, 0 ); }