dovecot-2.2: acl: acl_object_list_*() now duplicates rights at i...

dovecot at dovecot.org dovecot at dovecot.org
Thu Oct 29 10:55:38 UTC 2015


details:   http://hg.dovecot.org/dovecot-2.2/rev/8f198b569b01
changeset: 19337:8f198b569b01
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Oct 29 12:55:20 2015 +0200
description:
acl: acl_object_list_*() now duplicates rights at init to avoid them changing during listing.
Depending on the calling code the acl_object could have been refreshed
during the listing and caused bugs/crashes.

This fixes a crash at least in mailbox deletion during attribute deletion
where iter->idx was higher (2) than the number of rights at the time (0).

diffstat:

 src/plugins/acl/acl-api-private.h |   4 +++-
 src/plugins/acl/acl-api.c         |  24 ++++++++++++++++--------
 2 files changed, 19 insertions(+), 9 deletions(-)

diffs (72 lines):

diff -r 9654ab4c337c -r 8f198b569b01 src/plugins/acl/acl-api-private.h
--- a/src/plugins/acl/acl-api-private.h	Wed Oct 28 12:28:12 2015 +0200
+++ b/src/plugins/acl/acl-api-private.h	Thu Oct 29 12:55:20 2015 +0200
@@ -75,8 +75,10 @@
 
 struct acl_object_list_iter {
 	struct acl_object *aclobj;
+	pool_t pool;
 
-	unsigned int idx;
+	struct acl_rights *rights;
+	unsigned int idx, count;
 	unsigned int failed:1;
 };
 
diff -r 9654ab4c337c -r 8f198b569b01 src/plugins/acl/acl-api.c
--- a/src/plugins/acl/acl-api.c	Wed Oct 28 12:28:12 2015 +0200
+++ b/src/plugins/acl/acl-api.c	Thu Oct 29 12:55:20 2015 +0200
@@ -190,8 +190,13 @@
 acl_default_object_list_init(struct acl_object *aclobj)
 {
 	struct acl_object_list_iter *iter;
+	const struct acl_rights *aclobj_rights;
+	unsigned int i;
+	pool_t pool;
 
-	iter = i_new(struct acl_object_list_iter, 1);
+	pool = pool_alloconly_create("acl object list", 512);
+	iter = p_new(pool, struct acl_object_list_iter, 1);
+	iter->pool = pool;
 	iter->aclobj = aclobj;
 
 	if (!array_is_created(&aclobj->rights)) {
@@ -202,28 +207,31 @@
 
 	if (aclobj->backend->v.object_refresh_cache(aclobj) < 0)
 		iter->failed = TRUE;
+
+	aclobj_rights = array_get(&aclobj->rights, &iter->count);
+	if (iter->count > 0) {
+		iter->rights = p_new(pool, struct acl_rights, iter->count);
+		for (i = 0; i < iter->count; i++)
+			acl_rights_dup(&aclobj_rights[i], pool, &iter->rights[i]);
+	}
 	return iter;
 }
 
 int acl_default_object_list_next(struct acl_object_list_iter *iter,
 				 struct acl_rights *rights_r)
 {
-	const struct acl_rights *rights;
-
 	if (iter->failed)
 		return -1;
 
-	if (iter->idx == array_count(&iter->aclobj->rights))
+	if (iter->idx == iter->count)
 		return 0;
-
-	rights = array_idx(&iter->aclobj->rights, iter->idx++);
-	*rights_r = *rights;
+	*rights_r = iter->rights[iter->idx++];
 	return 1;
 }
 
 void acl_default_object_list_deinit(struct acl_object_list_iter *iter)
 {
-	i_free(iter);
+	pool_unref(&iter->pool);
 }
 
 struct acl_mailbox_list_context *


More information about the dovecot-cvs mailing list