Skip to content

Check ignored error status of I/O calls (CodeQL java/ignored-error-status-of-call)#233

Open
vharseko wants to merge 2 commits into
OpenIdentityPlatform:masterfrom
vharseko:features/codeql-ignored-return
Open

Check ignored error status of I/O calls (CodeQL java/ignored-error-status-of-call)#233
vharseko wants to merge 2 commits into
OpenIdentityPlatform:masterfrom
vharseko:features/codeql-ignored-return

Conversation

@vharseko

@vharseko vharseko commented Jul 8, 2026

Copy link
Copy Markdown
Member

Summary

Resolves all nine open java/ignored-error-status-of-call CodeQL alerts. Each
site threw away the result of a stream read/skip or of File.renameTo, so a
short read, an incomplete skip, or a failed rename went unnoticed.

File Call Fix
StreamLoader.java (139, 141) DataInputStream.read(buf, off, len) for record key/value switch to readFully
Value.java (4894, 4899) read inside readFully overrides check the count, throw EOFException on a short read
IOMeter.java (455) InputStream.skip in the dump main loop until fully skipped
BackupTask.java (263) File.renameTo throw IOException when it returns false
WDSSO.java (288, 326) ByteArrayInputStream.read for SPNEGO / Kerberos OID require a full read before matching the OID
DerValue.java (91) ByteArrayInputStream.read for DER content truncate to the bytes actually read

Why it is safe

For every well-formed input these calls already transferred the full amount:

  • StreamLoader reads from a DataInputStream; readFully reads exactly the
    requested bytes or throws EOFException — for a complete stream the byte
    count is identical to before, but a short read (buffered / socket source) can
    no longer deliver a half-filled key or value.
  • Value.ValueObjectInputStream.read already transfers exactly length bytes
    or throws IOException, so the added != length guard only documents and
    enforces the existing DataInput.readFully contract.
  • IOMeter.main is a diagnostic dumper; the skip loop reaches the same offset,
    just correctly when skip returns fewer bytes than requested.
  • BackupTask.rename only reaches the new throw when renameTo actually
    fails — previously that failure was reported as success.
  • In WDSSO/DerValue a valid token fills the OID / DER buffers completely, so
    the guard is true and the comparison result is unchanged; a truncated
    token now fails closed instead of being compared against zero-filled trailing
    bytes.

So the change is behaviour-preserving for all existing (valid) inputs and only
surfaces genuinely truncated or failed I/O.

Copyright

Adds the missing Portions Copyrighted 2026 3A Systems, LLC header line to
StreamLoader.java, BackupTask.java, WDSSO.java and DerValue.java
(Value.java and IOMeter.java already carry it). The @Checkstyle:ignoreFor
count in the two ForgeRock CDDL headers is bumped by one to keep covering the
extended header.

Testing

mvn -o -pl persistit/core,commons/auth-filters/authn-filter/jaspi-modules/iwa-module -am compile — BUILD SUCCESS.

…atus-of-call)

Nine call sites discarded the return value of a stream read/skip or of
File.renameTo, so a short read, an incomplete skip, or a failed rename passed
silently. Consume and act on each result:

  - StreamLoader.next: read the record key/value with DataInputStream.readFully
    instead of read(), so a short read on a buffered/socket stream can no longer
    hand a partially filled key or value to the import handler (latent
    corruption bug).
  - Value.ValueObjectInputStream.readFully: honour the DataInput.readFully
    contract - the local read() transfers exactly the requested length or
    throws, so a short count now raises EOFException.
  - IOMeter.main: loop until the requested byte count is fully skipped, since
    InputStream.skip may skip fewer bytes than asked.
  - BackupTask.rename: throw IOException when File.renameTo returns false rather
    than reporting success for a rename that did not happen.
  - WDSSO.parseToken and DerValue.init: use the byte count returned by
    ByteArrayInputStream.read so a truncated SPNEGO/Kerberos token or DER value
    fails closed instead of being compared against uninitialised trailing bytes.

For every well-formed input the reads/skips/renames already completed fully, so
behaviour is unchanged for existing callers; only truncated or failing I/O is
now surfaced.

Also add the missing 3A Systems Portions header line to StreamLoader.java,
BackupTask.java, WDSSO.java and DerValue.java (Value.java and IOMeter.java
already carry it).
@vharseko vharseko added bug java codeql CodeQL static-analysis findings security Security fixes and CVE remediation labels Jul 8, 2026
@vharseko vharseko requested a review from maximthomas July 8, 2026 13:05
@vharseko vharseko removed the java label Jul 8, 2026
@vharseko vharseko force-pushed the features/codeql-ignored-return branch from b4d9254 to 15ae03a Compare July 10, 2026 18:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug codeql CodeQL static-analysis findings security Security fixes and CVE remediation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants