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.
This commit is contained in:
		
							parent
							
								
									a846ab054d
								
							
						
					
					
						commit
						7979782676
					
				
					 1 changed files with 10 additions and 4 deletions
				
			
		|  | @ -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 ); | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue