Source: netcdf
Version: 1:4.10.1-1
Severity: important
Tags: security upstream patch
X-Debbugs-Cc: [email protected]

Hi,

The security tracker lists CVE-2026-86095 as unfixed for netcdf, but
there is no Debian bug for it yet, so here is one.

CVE-2026-86095: "Unidata netcdf-c through 4.10.1 contains an
out-of-bounds write vulnerability in NC4_HDF5_inq_attname() that copies
HDF5 attribute names into a fixed 256-byte buffer without length
validation."

Upstream issue (open, no fix on main yet):
https://www.google.com/url?q=https://github.com/Unidata/netcdf-c/issues/3463&source=gmail&ust=1793796591657000&sa=E

Root cause: NC4_HDF5_inq_attname() (libhdf5/hdf5attr.c) does
strcpy(name, att->
https://www.google.com/url?q=http://hdr.name&source=gmail&ust=1793796591657000&sa=E),
and callers size "name" as
NC_MAX_NAME + 1. When netCDF writes attributes, it checks the length
against NC_MAX_NAME (hdf5attr.c, "strlen(name) > NC_MAX_NAME"). But when
it opens an HDF5 file, att_read_callbk() in libhdf5/hdf5open.c adds
every attribute name from the file without a length check. So an HDF5
file that netCDF did not write can carry longer names.

There are two possible fixes:

a) Other distributions truncate at the copy site. SUSE's
"Fix-a-potential-write-past-end-of-a-fixed-size-buffer.patch" and
OSGeo4W's patch (referenced from the upstream issue) replace the
strcpy with strncpy(name, att->
https://www.google.com/url?q=http://hdr.name&source=gmail&ust=1793796591657000&sa=E,
NC_MAX_NAME - 1) plus a
terminator.

b) The attached patch rejects such names at read time instead: in
att_read_callbk() it skips attributes whose names are longer than
NC_MAX_NAME, in the same way the function already skips reserved
attribute names. That way a name netCDF could never have written is
never stored, so no other path that copies attribute names into an
NC_MAX_NAME+1 buffer can overflow either. The trade-off is that such
attributes are not visible through the netCDF API. With (a) they are
visible, but under a truncated name that may not round-trip through
nc_get_att by name. The only other caller of nc4_att_list_add() in
libhdf5 is the write path, which already enforces NC_MAX_NAME.

Either is fine with me; please pick whichever you prefer, or follow
upstream once they decide.

Testing of (b), on upstream netcdf-c 4.10.1 (amd64, sid, HDF5 from
libhdf5-dev, --disable-shared --disable-dap --disable-byterange
--disable-nczarr --disable-plugins; built and tested as an unprivileged
user):
- both trees build; no warnings in hdf5open.c
- make check, unpatched 4.10.1: 201 tests, PASS 201, FAIL 0
- make check, patched 4.10.1: 201 tests, PASS 201, FAIL 0
I did not construct an HDF5 file with an oversized attribute name, so
the overflow itself was not reproduced here. The test-suite result only
shows that the patch causes no regressions.

The patch applies to 4.10.1 as is; att_read_callbk() is identical on
current upstream main.

Regards
--- a/libhdf5/hdf5open.c
+++ b/libhdf5/hdf5open.c
@@ -2336,6 +2336,17 @@
     if (NC_findreserved(att_name))
         return NC_NOERR;
 
+    /* netCDF names are limited to NC_MAX_NAME bytes, and callers of
+     * nc_inq_attname() provide an NC_MAX_NAME + 1 byte buffer. An HDF5
+     * file not written by netCDF may contain longer attribute names;
+     * skip them rather than storing a name that would overflow those
+     * buffers later (CVE-2026-86095). */
+    if (strlen(att_name) > NC_MAX_NAME)
+    {
+        LOG((2, "%s: skipping attribute with name longer than NC_MAX_NAME", __func__));
+        return NC_NOERR;
+    }
+
     /* Add to the end of the list of atts for this var. */
     if ((retval = nc4_att_list_add(list, att_name, &att)))
         BAIL(-1);

Reply via email to