Skip to content

BUG: File descriptor leak in npy_PyFile_Dup2 when fdopen fails #32373

Description

@GregorioFornetti

Describe the issue:

In numpy/_core/include/numpy/npy_3kcompat.h, the function npy_PyFile_Dup2 (used by numpy.fromfile and ndarray.tofile) has a file descriptor leak on an error path.

When os.dup() succeeds but the subsequent fdopen() call fails, the duplicated file descriptor fd2 is never closed. The code sets a Python error and returns NULL without calling close(fd2):

// npy_3kcompat.h, around line 113-127
#ifdef _WIN32
    NPY_BEGIN_SUPPRESS_IPH
    handle = _fdopen(fd2, mode);
    NPY_END_SUPPRESS_IPH
#else
    handle = fdopen(fd2, mode);
#endif
    if (handle == NULL) {
        PyErr_SetString(PyExc_IOError,
                        "Getting a FILE* from a Python file object via "
                        "_fdopen failed. If you built NumPy, you probably "
                        "linked with the wrong debug/release runtime");
        return NULL;  // <-- fd2 is leaked here
    }

All other error paths after fdopen succeeds properly call fclose(handle), so this is the only leak.

Reproduce the code example:

Add a platform-appropriate raw fd close before returning `NULL`:


    if (handle == NULL) {
+#ifdef _WIN32
+       _close(fd2);
+#else
+       close(fd2);
+#endif
        PyErr_SetString(PyExc_IOError,
                        "Getting a FILE* from a Python file object via "
                        "_fdopen failed. If you built NumPy, you probably "
                        "linked with the wrong debug/release runtime");
        return NULL;
    }


Note: `fclose` cannot be used here because `fdopen` failed, so there is no valid `FILE*` handleonly the raw file descriptor `fd2` needs to be cleaned up.

Error message:

Python and NumPy Versions:

2.6.0.dev0
3.14.4 (main, Apr 8 2026, 04:02:31) [GCC 15.2.0]

Runtime Environment:

No response

How does this issue affect you or how did you find it:

This issue was found by Claude Code while analyzing the fromfile implementation for potential resource handling problems.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions