]> git.ipfire.org Git - thirdparty/shadow.git/commitdiff
libsubid: Add routine to free allocated memory
authorDaniel Bershatsky <d.bershatsky2@skoltech.ru>
Mon, 10 Jun 2024 22:12:45 +0000 (01:12 +0300)
committerAlejandro Colomar <alx@kernel.org>
Wed, 12 Jun 2024 19:45:31 +0000 (21:45 +0200)
lib/nss.c
lib/prototypes.h
lib/subordinateio.c
lib/subordinateio.h
libsubid/api.c
libsubid/subid.h.in
src/getsubids.c

index 779d8259dd8287d55b500542b62dded0a5d511d8..9174e97bfb8d3334a57d1537503433a7f0ef51a1 100644 (file)
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -131,6 +131,11 @@ void nss_init(const char *nsswitch_path) {
                fprintf(shadow_logfd, "%s did not provide @find_subid_owners@\n", libname);
                goto close_lib;
        }
+       subid_nss->free= dlsym(h, "shadow_subid_free");
+       if (!subid_nss->free) {
+               // Fallback to default `free()` for backward compatibility.
+               subid_nss->free = free;
+       }
        subid_nss->handle = h;
        goto done;
 
index 5c56e77e4eeca42109d5ad6ade8361abe10e93a8..7e2f5d224379764a1c18a859fb4606aca0e898ba 100644 (file)
@@ -284,6 +284,19 @@ struct subid_nss_ops {
         */
        enum subid_status (*find_subid_owners)(unsigned long id, enum subid_type id_type, uid_t **uids, int *count);
 
+       /*
+        * nss_free: free a memory block allocated by a subid plugin.
+        *
+        * @ptr - a pointer to a memory block to deallocate
+        *
+        * Some routines of subid_nss_ops allocate memory which should be freed by
+        * caller after use. In order to deallocate that memory block, one should
+        * use this routine to release that memory. By default, this function
+        * pointer is set to free() for backward compatibility. However, it is
+        * strongly recommended to define this routine explicitly.
+        */
+       void (*free)(void *ptr);
+
        /* The dlsym handle to close */
        void *handle;
 };
index e7cd4b48207a5a00e84714115767b2e0ab52aaa0..bd59d8cf72b977b101ceb850b6e187d8627939a4 100644 (file)
@@ -1117,6 +1117,15 @@ bool release_subid_range(struct subordinate_range *range, enum subid_type id_typ
        return ret;
 }
 
+void free_subid_pointer(void *ptr) {
+       struct subid_nss_ops *h = get_subid_nss_handle();
+       if (h) {
+               h->free(ptr);
+       } else {
+               free(ptr);
+       }
+}
+
 #else                          /* !ENABLE_SUBIDS */
 extern int ISO_C_forbids_an_empty_translation_unit;
 #endif                         /* !ENABLE_SUBIDS */
index d32733de940aa0fdb765361ee6fc3ec5ce7713af..3d1a054713cebf0486f14c322308d390a2942f3e 100644 (file)
@@ -43,6 +43,9 @@ extern int sub_gid_unlock (void);
 extern int sub_gid_add (const char *owner, gid_t start, unsigned long count);
 extern int sub_gid_remove (const char *owner, gid_t start, unsigned long count);
 extern uid_t sub_gid_find_free_range(gid_t min, gid_t max, unsigned long count);
+
+extern void free_subid_pointer(void *ptr);
+
 #endif                         /* ENABLE_SUBIDS */
 
 #endif
index 65d20abf960c97ec46a34c22cf0e0901fe0410f4..6059b704eff21cac58491c480c8fcca8cb630cb8 100644 (file)
@@ -42,6 +42,10 @@ bool subid_init(const char *progname, FILE * logfd)
        return true;
 }
 
+void subid_free(void *ptr) {
+       free_subid_pointer(ptr);
+}
+
 static
 int get_subid_ranges(const char *owner, enum subid_type id_type, struct subid_range **ranges)
 {
index 79744eda1676b707ecdc4cc8e6f67ae36302fba9..7090c6c80556e39abfbd75a58ff840424760d339 100644 (file)
@@ -55,6 +55,19 @@ extern "C" {
  */
 bool subid_init(const char *progname, FILE *logfd);
 
+/*
+ * subid_free: free memory allocated in any subid_* function
+ *
+ * @ptr: Pointer to a memory block to release.
+ *
+ * Some functions like @subid_get_uid_ranges allocate memory internally. As
+ * soon as a result is no longer needed, it should be freed with this routine.
+ * Initially, default function `free()` was used. Thus for backward
+ * compatibility this function falls back to `free()` if a plugin does not
+ * explicitly specify routine to free allocated memory.
+ */
+void subid_free(void *ptr);
+
 /*
  * subid_get_uid_ranges: return a list of UID ranges for a user
  *
index 0753abd7a5c75cb0cf64d579f69c45666066f604..871e850f2be359673f7162f1494e36ebed61fb78 100644 (file)
@@ -44,6 +44,6 @@ int main(int argc, char *argv[])
                printf("%d: %s %lu %lu\n", i, owner,
                        ranges[i].start, ranges[i].count);
        }
-       free(ranges);
+       subid_free(ranges);
        return 0;
 }