commit 7979782676cfeb3e631271ce3d2f44f6566e2615
Author: Oswald Buddenhagen <o...@users.sf.net>
Date:   Mon Jun 21 11:35:24 2021 +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.

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

diff --git a/src/drv_maildir.c b/src/drv_maildir.c
index 5ba83f7..ea4195d 100644
--- 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 );
 }


_______________________________________________
isync-devel mailing list
isync-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/isync-devel

Reply via email to