Skip to content

HDFS-17879. Premature error handling accesses uninitialized dnInfo.#8281

Open
balodesecurity wants to merge 1 commit intoapache:trunkfrom
balodesecurity:HDFS-17879
Open

HDFS-17879. Premature error handling accesses uninitialized dnInfo.#8281
balodesecurity wants to merge 1 commit intoapache:trunkfrom
balodesecurity:HDFS-17879

Conversation

@balodesecurity
Copy link

Description of PR

JIRA: https://issues.apache.org/jira/browse/HDFS-17879

Problem

In DFSStripedInputStream.createBlockReader(), dnInfo is initialized with all-null fields before the retry loop:

DFSInputStream.DNAddrPair dnInfo =
    new DFSInputStream.DNAddrPair(null, null, null, null);

It is then populated by getBestNodeDNAddrPair() — but only after refreshLocatedBlock() is called first. If refreshLocatedBlock() throws an IOException, the catch block immediately accesses dnInfo.addr (still null), causing a NullPointerException that masks the original error:

NullPointerException at DFSStripedInputStream.java:267  (dnInfo.addr)
  caused by: IOException from refreshLocatedBlock()

Fix

Add a null check on dnInfo.addr at the top of the catch block. If null, the failure occurred before any DataNode was identified, so we rethrow the original IOException directly — preserving the real error for the caller.

if (dnInfo.addr == null) {
  throw e;
}

Testing

Added TestDFSStripedInputStream#testCreateBlockReaderExceptionBeforeDnInfoInit which uses Mockito to make refreshLocatedBlock() throw an IOException, and verifies:

  • Before fix: NullPointerException is thrown (masked error)
  • After fix: original IOException is propagated cleanly

For code changes:

  • Does the title or this PR starts with the corresponding JIRA issue id (e.g. 'HADOOP-17799. Your PR title ...')?
  • Object storage: have the integration tests been executed and the endpoint declared according to the connector-specific documentation?
  • If adding new dependencies to the code, are these dependencies licensed in a way that is compatible for inclusion under ASF 2.0?
  • If applicable, have you updated the LICENSE, LICENSE-binary, NOTICE-binary files?

In DFSStripedInputStream.createBlockReader(), dnInfo is initialized
with all-null fields before the loop, then populated by
getBestNodeDNAddrPair(). If refreshLocatedBlock() throws an IOException
before getBestNodeDNAddrPair() is called, the catch block accessed
dnInfo.addr (still null), causing a NullPointerException that masked
the original error.

Fix: add a null check on dnInfo.addr at the top of the catch block.
If null, the exception occurred before any DataNode was identified,
so we rethrow the original IOException directly.

Added TestDFSStripedInputStream#testCreateBlockReaderExceptionBeforeDnInfoInit
to verify the IOException is propagated cleanly without NPE.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants