[ 
https://issues.apache.org/jira/browse/IMPALA-15422?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Zoltán Borók-Nagy resolved IMPALA-15422.
----------------------------------------
    Fix Version/s: Impala 5.0.0
       Resolution: Fixed

> WriteDecimalSlot in system-table-scanner.cc falls through its switch and 
> writes 16 bytes into 8-byte DECIMAL slots
> ------------------------------------------------------------------------------------------------------------------
>
>                 Key: IMPALA-15422
>                 URL: https://issues.apache.org/jira/browse/IMPALA-15422
>             Project: IMPALA
>          Issue Type: Bug
>          Components: Backend
>            Reporter: Zoltán Borók-Nagy
>            Assignee: Zoltán Borók-Nagy
>            Priority: Major
>             Fix For: Impala 5.0.0
>
>
> The switch in WriteDecimalSlot() has no break statements:
> {code:cpp}
> // be/src/exec/system-table-scanner.cc:101
> static void WriteDecimalSlot(
>     const ColumnType& type, double value, void* slot) {
>   bool overflow = false;
>   switch (type.GetByteSize()) {
>     case 4:
>       *reinterpret_cast<Decimal4Value*>(slot) =
>           Decimal4Value::FromDouble(type, value, false, &overflow);
>     case 8:
>       *reinterpret_cast<Decimal8Value*>(slot) =
>           Decimal8Value::FromDouble(type, value, false, &overflow);
>     case 16:
>       *reinterpret_cast<Decimal16Value*>(slot) =
>           Decimal16Value::FromDouble(type, value, false, &overflow);
>   }
>   DCHECK(!overflow);
> }
> {code}
> All DECIMAL columns of sys.impala_query_live are DECIMAL(18,3) 
> (DURATION_DECIMAL_PRECISION
> / SCALE in workload-management.h), so GetByteSize() is 8. The 8-byte value is 
> written,
> then execution falls through and a Decimal16Value is written at the same 
> address. The 8
> bytes after the slot are overwritten: zeros for non-negative values, 0xFF 
> bytes for
> negative ones.
> Affected columns: TOTAL_TIME_MS, ROW_MATERIALIZATION_TIME_MS, 
> READ_IO_WAIT_TOTAL_MS,
> READ_IO_WAIT_MEAN_MS, and all EVENT_* timeline columns (written through 
> WriteEvent()).
> Depending on the tuple layout of the projected columns, the extra bytes 
> overwrite one of:
> * a neighbouring slot that was already written, which then reads as 0;
> * null-indicator bytes, so a NULL value can read as non-NULL;
> * memory past the end of the tuple, if the decimal is the last slot.
> h3. Repro
> Start the cluster with --enable_workload_mgmt=true (impalad and catalogd) and 
> run a few
> queries. Then:
> {code:sql}
> select query_id, backends_count from sys.impala_query_live order by query_id;
> {code}
> {noformat}
> 2c4087f2a5bfa360:b53e19f800000000     3
> d341c86929ab53f0:ad99a3f700000000     3
> {noformat}
> {code:sql}
> select query_id, backends_count, total_time_ms from sys.impala_query_live 
> order by query_id;
> {code}
> {noformat}
> 2c4087f2a5bfa360:b53e19f800000000     0       466.204
> 6e4b4ced99079f15:268d851900000000     0       181.613
> d341c86929ab53f0:ad99a3f700000000     0       193.144
> {noformat}
> backends_count (INT) is written first and laid out right after the 8-byte 
> decimal slot.
> The 16-byte decimal write then zeroes it. Queries on a debug build don't hit 
> the DCHECK.
> h3. Proposed fix
> Add the missing break statements. Add a test that selects all columns of
> sys.impala_query_live, preferably run under ASAN, or a BE unit test for
> WriteDecimalSlot with a guard value next to the slot.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to