Julian Chandra Sutadi created ZOOKEEPER-5112:
------------------------------------------------

             Summary: A malformed createTTL request can crash a server
                 Key: ZOOKEEPER-5112
                 URL: https://issues.apache.org/jira/browse/ZOOKEEPER-5112
             Project: ZooKeeper
          Issue Type: Bug
            Reporter: Julian Chandra Sutadi


A client can send a {{createTTL}} request with an inconsistent request body 
containing the ({{PERSISTENT}}) flag, with {{ttl = -1}}.

Such malformed request is prevented in the official ZooKeeper Java client. 
Nevertheless, currently the server does a defensive sanity check just in case a 
malformed request arrives, as added by ZOOKEEPER-2797.

However, the validation added in ZOOKEEPER-2797 didn't cover the above case, 
since the {{createMode}} passed to 
{{PrepRequestProcessor#validateCreateRequest}} will have {{createMode.isTTL()}} 
evaluate to {{false}} (due to the PERSISTENT flag), allowing the request to get 
pass the validation. Eventually, it will throw an error when trying to apply 
the transaction to the data tree

{code:java}
// DataTree.java
public ProcessTxnResult processTxn(...) {
    ...
    case OpCode.createTTL:
        CreateTTLTxn createTtlTxn = (CreateTTLTxn) txn;
        rc.path = createTtlTxn.getPath();
        stat = new Stat();
        createNode(
            createTtlTxn.getPath(),
            createTtlTxn.getData(),
            createTtlTxn.getAcl(),
            EphemeralType.TTL.toEphemeralOwner(createTtlTxn.getTtl()),    // 
throws when ttl = -1
            createTtlTxn.getParentCVersion(),
            header.getZxid(),
            header.getTime(),
            stat);
        rc.stat = stat;
        break;
    ...
}
{code}
{code:java}
// EphemeralType.java
public enum EphemeralType {
    ...
    TTL() {
        ...
        @Override
        public long toEphemeralOwner(long ttl) {
            if ((ttl > TTL.maxValue()) || (ttl <= 0)) {
                throw new IllegalArgumentException("ttl must be positive and 
cannot be larger than: " + TTL.maxValue());
            }
            ...
        }
    ...
}
{code}

The exception is thrown in the {{SyncRequestProcessor}} thread, which then 
dies, followed by the server shutting down. Moreover, because the bad txn is 
already in the log, the server crashes again on restart while replaying it. 
Sending this request needs only {{CREATE}} permission on a parent znode, and it 
works even with the TTL feature disabled (the default).



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to