---------- Forwarded message ---------
From: Lars Knipschild <laknipschild@uni-osnabrueck.de>
Date: Mon, Jan 5, 2026 at 10:34 AM
Subject: Memory-Leak in nfs-ganesha
To: <nfs-ganesha-maintainers@fedoraproject.org>


Dear libntirpc-maintainers,

thanks a lot for maintaining this package!

We use CEPH+Ganesha (5.9-1 from CentOS Storage Sig)+HAProxy
(Proxy-Protocol).

With this setup we observed unusual growth of memory usage in ganesha.nfsd.
We traced this issue back a memory leak in
nfs4_op_getxattr (src/Protocols/NFS/nfs4_op_xattr.c, line 83):

gxr_value.utf8string_val = gsh_malloc(gxr_value.utf8string_len + 1);

This block of 1025 bytes is only freed if the function succeeds. In our
case (libceph) the function call
obj_handle->obj_ops->getxattrs (line 98) returns an error ( -61
(-ENODATA)) if there are no xattrs for the respective file.

Some client activity (gocryptfs+rsync) caused lots of getxattrs-calls
leading to ~40MB/min memory-growth.


To solve the problem I prepared the following patch, that we tested
during December:

[lars@vmwnh SOURCES]$ cat ganesha_xattr_memleak.patch
diff -Naru nfs-ganesha-5.9_orig/src/Protocols/NFS/nfs4_op_xattr.c
nfs-ganesha-5.9/src/Protocols/NFS/nfs4_op_xattr.c
--- nfs-ganesha-5.9_orig/src/Protocols/NFS/nfs4_op_xattr.c 2025-12-08
14:36:49.778825846 +0100
+++ nfs-ganesha-5.9/src/Protocols/NFS/nfs4_op_xattr.c 2025-12-08
14:51:43.666539343 +0100
@@ -79,9 +79,6 @@
  res_GETXATTR4->GETXATTR4res_u.resok4.gxr_value.utf8string_len = 0;
  res_GETXATTR4->GETXATTR4res_u.resok4.gxr_value.utf8string_val = NULL;

-    gxr_value.utf8string_len = XATTR_VALUE_SIZE;
-    gxr_value.utf8string_val = gsh_malloc(gxr_value.utf8string_len + 1);
-
      /* Do basic checks on a filehandle */
      res_GETXATTR4->status = nfs4_sanity_check_FH(data, NO_FILE_TYPE,
false);

@@ -95,16 +92,19 @@
          return NFS_REQ_ERROR;
      }

+    gxr_value.utf8string_len = XATTR_VALUE_SIZE;
+    gxr_value.utf8string_val = gsh_malloc(gxr_value.utf8string_len + 1);
+
      fsal_status = obj_handle->obj_ops->getxattrs(obj_handle,
                              &arg_GETXATTR4->gxa_name,
                              &gxr_value);
      if (FSAL_IS_ERROR(fsal_status)) {
+        gsh_free(gxr_value.utf8string_val);
          if (fsal_status.major == ERR_FSAL_XATTR2BIG) {
              LogDebug(COMPONENT_NFS_V4,
                   "FSAL buffer len %d too small",
                    XATTR_VALUE_SIZE);
              /* Get size of xattr value  */
-            gsh_free(gxr_value.utf8string_val);
              gxr_value.utf8string_len = 0;
              gxr_value.utf8string_val = NULL;
              fsal_status = obj_handle->obj_ops->getxattrs(obj_handle,
@@ -128,6 +128,7 @@
                              &gxr_value);

              if (FSAL_IS_ERROR(fsal_status)) {
+                gsh_free(gxr_value.utf8string_val);
                  res_GETXATTR4->status = nfs4_Errno_state(
                      state_error_convert(fsal_status));
                  return NFS_REQ_ERROR;

This patch is quite similar to
https://github.com/nfs-ganesha/nfs-ganesha/commit/c8c6b8d8c03ac746c7d7e96eb01e99a080f8153d.

Have a nice day!

Best
Lars


--
Dr. Lars Knipschild | Universität Osnabrück - Rechenzentrum |
High-Performance-Computing Koordinator | lars@uos.de | 0541 969 2316



--

Kaleb