[
https://issues.apache.org/jira/browse/ZOOKEEPER-2414?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15255901#comment-15255901
]
Tianyi Zhang commented on ZOOKEEPER-2414:
-----------------------------------------
[~fpj] sorry for my poor English.
The free_duplicate_path() will free the path when the 'chroot' of zh is not
null. Because the CreateRequest_init() will strcat the chroot and the
create_op.path to be req.path, after that the req.path isn't equal to
create_op.path, then the free_duplicate_path() will free the req.path.
However, in this line:
{code}
rc = rc < 0 ? rc : CreateRequest_init(zh, &req,
op->create_op.path, op->create_op.data,
op->create_op.datalen,
op->create_op.acl,
op->create_op.flags);
{code}
if the rc less than 0, CreateRequest_init will not be execute, and the req.path
is still the last op's create_op.path. The free_duplicate_path() will free the
last op's create_op.path, if it is different from the current op's
create_op.path.That result in double free.
> c-client aborted when operate's path is invalid in zoo_amulti
> --------------------------------------------------------------
>
> Key: ZOOKEEPER-2414
> URL: https://issues.apache.org/jira/browse/ZOOKEEPER-2414
> Project: ZooKeeper
> Issue Type: Bug
> Components: c client
> Affects Versions: 3.4.8
> Reporter: Tianyi Zhang
> Priority: Critical
>
> code like this:
> {code}
> zoo_op_t ops[2];
> zoo_op_result_t results[2];
> zoo_create_op_init(ops, "test", "1", 1, &ZOO_OPEN_ACL_UNSAFE, 0, NULL, 0);
> zoo_create_op_init(ops+1, "/test/1", "2", 1, &ZOO_OPEN_ACL_UNSAFE, 0, NULL,
> 0);
> zoo_multi(zkhandle, 2, ops, results);
> {code}
> The ops->path is invalid, and it will cause double free in the line 3136 of
> zookeeper.c.
> {code}
> for (index=0; index < count; index++) {
> const zoo_op_t *op = ops+index;
> zoo_op_result_t *result = results+index;
> completion_list_t *entry = NULL;
> struct MultiHeader mh = { STRUCT_INITIALIZER(type, op->type),
> STRUCT_INITIALIZER(done, 0), STRUCT_INITIALIZER(err, -1) };
> rc = rc < 0 ? rc : serialize_MultiHeader(oa, "multiheader", &mh);
> switch(op->type) {
> case ZOO_CREATE_OP: {
> struct CreateRequest req;
> rc = rc < 0 ? rc : CreateRequest_init(zh, &req,
> op->create_op.path,
> op->create_op.data,
> op->create_op.datalen,
> op->create_op.acl,
> op->create_op.flags);
> rc = rc < 0 ? rc : serialize_CreateRequest(oa, "req", &req);
> result->value = op->create_op.buf;
> result->valuelen = op->create_op.buflen;
> enter_critical(zh);
> entry = create_completion_entry(h.xid, COMPLETION_STRING,
> op_result_string_completion, result, 0, 0);
> leave_critical(zh);
> --> free_duplicate_path(req.path, op->create_op.path);
> break;
> }
> {code}
> This problem will happen when the 'rc' of last op is less than 0(maybe
> ZBADARGUMENTS or ZINVALIDSTATE).
> In my case, rc of op[0] is ZBADARGUMENTS, and the req.path of the
> ‘free_duplicate_path’ is still 'test' when execute op[1].
> I‘m confused about why not break the for-loop when the 'rc' is less than 0?
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)