apache / apache/arrow-java

Byte-array elements leak in `FromSchemaByteArray()`

Offen Anfängerfreundlich
#1,205 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
Type: bug
Vorherrschende Sprache
Java
Sterne
94
Forks
152
Ø Merge
3 T. 16 Std.
Gemergte PRs (30 T.)
11

Beschreibung

### Describe the bug, including details regarding any error messages, version, and platform.

I found a possible JNI array leak in `FromSchemaByteArray()` when the serialized schema cannot be parsed.

File: `dataset/src/main/cpp/jni_util.cc`

Function: `FromSchemaByteArray`

Relevant code:

```cpp
jbyte* schemaBytes_data =
env->GetByteArrayElements(schemaBytes, nullptr);
auto serialized_schema = std::make_shared(
reinterpret_cast(schemaBytes_data),
schemaBytes_len);
arrow::io::BufferReader buf_reader(serialized_schema);

ARROW_ASSIGN_OR_RAISE(
std::shared_ptr schema,
arrow::ipc::ReadSchema(&buf_reader, &in_memo))

env->ReleaseByteArrayElements(
schemaBytes, schemaBytes_data, JNI_ABORT);
return schema;
```

`GetByteArrayElements()` returns a pointer that must be paired with
`ReleaseByteArrayElements()`.

`ARROW_ASSIGN_OR_RAISE` returns immediately when `ReadSchema()` returns an
error. On that path, the release below the macro is skipped, so the acquired
array elements remain unreleased:

```text
GetByteArrayElements succeeds
-> ReadSchema returns an error
-> ARROW_ASSIGN_OR_RAISE returns
-> ReleaseByteArrayElements is skipped
```

The function is used by the public native `createDataset()` method:

```cpp
schema = JniGetOrThrow(
FromSchemaByteArray(env, schema_bytes));
```

Malformed, corrupted, or incompatible serialized schema bytes can therefore
reach this path. Repeated failed calls can retain copied array buffers or keep
Java arrays pinned, depending on the JVM implementation.

Suggested fix: release the elements before propagating the parse result, for
example:

```cpp
auto schema_result =
arrow::ipc::ReadSchema(&buf_reader, &in_memo);

env->ReleaseByteArrayElements(
schemaBytes, schemaBytes_data, JNI_ABORT);

return schema_result;
```

An RAII guard for `schemaBytes_data` would also ensure release if additional
early returns are introduced later.

Beitragsleitfaden

Beitragsleitfaden öffnen

Rechercherichtung

Beginne in dataset/src/main/cpp/jni_util.cc bei FromSchemaByteArray() und untersuche den Ablauf von GetByteArrayElements, ReadSchema und ReleaseByteArrayElements. Überprüfe, dass die Freigabe auch erfolgt, wenn das Parsen fehlschlägt, und durchlaufe anschließend den Pfad für ein fehlerhaftes oder inkompatibles Schema über createDataset(); fertig ist die Aufgabe, wenn die erworbenen JNI-Array-Elemente sowohl im Erfolgs- als auch im Fehlerpfad freigegeben werden.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
cpp, java
Bereich
backend
Issue-Typ
Bug
Schwierigkeit
2/5
Geschätzter Aufwand
1-3 Stunden
Aktivitätsstatus
Ruhig
Klarheit
Klar beschrieben
Anfängerfreundlichkeit
85/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.