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