Cyl created ZOOKEEPER-5008:
------------------------------
Summary: Critical Uninitialized Variable Usage in zoo_amulti
Key: ZOOKEEPER-5008
URL: https://issues.apache.org/jira/browse/ZOOKEEPER-5008
Project: ZooKeeper
Issue Type: Bug
Components: c client
Affects Versions: 3.9.4
Reporter: Cyl
Attachments: repro_multi_user_view.c
{*}Description{*}: In
{{{}zookeeper-client/zookeeper-client-c/src/zookeeper.c{}}}, the function
{{zoo_amulti}} declares request structures (e.g., {{{}struct CreateRequest
req{}}}) without initialization.
If an error occurs during the processing of a multi-op (e.g., a previous
operation fails, or initialization of the current operation fails), the code
might skip the initialization helper function (like
{{{}CreateRequest_init{}}}). However, the cleanup code at the end of the switch
case unconditionally calls {{{}free_duplicate_path(req.path, ...){}}}.
Since {{req}} was not initialized, {{req.path}} contains garbage stack data.
Calling {{free()}} on this garbage pointer leads to a crash (Segmentation
Fault) or heap corruption.
This vulnerability affects both the asynchronous API {{zoo_amulti}} and the
synchronous API {{zoo_multi}} (which calls {{zoo_amulti}} internally).
{code:java}
// Vulnerable pattern
case ZOO_CREATE_OP: {
struct CreateRequest req; // Uninitialized
// ...
rc = CreateRequest_init(...); // Might be skipped if rc < 0
// ...
free_duplicate_path(req.path, ...); // Crash if req.path is garbage
break;
} {code}
*Impact* Calling {{free()}} on a garbage pointer leads to a crash (Segmentation
Fault) or heap corruption, causing a Denial of Service (DoS) for the client
application.
*Reproduction* We provide a Proof of Concept (PoC) that simulates a realistic
user scenario: a client application attempting to execute a transaction
(multi-op) where one of the operations contains a common error (e.g., a typo in
the path).
*Compile the PoC:* Navigate to the root of the workspace and run:
{code:java}
gcc -g -DTHREADED \
-I zookeeper-client/zookeeper-client-c/include \
-I zookeeper-client/zookeeper-client-c/generated \
cve-finding/zoo_amulti-none-initial/repro_multi_user_view.c \
-o cve-finding/zoo_amulti-none-initial/repro_multi_user_view \
-L zookeeper-client/zookeeper-client-c/.libs -lzookeeper_mt \
-Wl,-rpath,$(pwd)/zookeeper-client/zookeeper-client-c/.libs {code}
*Run the PoC:*
{code:java}
./cve-finding/zoo_amulti-none-initial/repro_multi_user_view {code}
*Expected Result:* The program will crash due to an invalid pointer free. This
happens because the first operation fails validation (invalid path), causing
the second operation's initialization to be skipped. However, the cleanup code
still attempts to free the uninitialized path pointer of the second operation,
which points to garbage stack data (simulated by {{{}simulate_app_activity{}}}).
{code:java}
User application attempting a transaction...
munmap_chunk(): invalid pointer
Aborted (core dumped) {code}
*Fix* Zero-initialize the request structures to ensure pointers are NULL if not
explicitly set. {{free_duplicate_path}} handles NULL pointers safely.
{{struct CreateRequest req = {0};}}
--
This message was sent by Atlassian Jira
(v8.20.10#820010)