From: Daniel Bershatsky Date: Mon, 10 Jun 2024 22:12:45 +0000 (+0300) Subject: libsubid: Add routine to free allocated memory X-Git-Tag: 4.16.0-rc1~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0217516349151ae38c68e35cfe0cb6e0e80f9224;p=thirdparty%2Fshadow.git libsubid: Add routine to free allocated memory --- diff --git a/lib/nss.c b/lib/nss.c index 779d8259d..9174e97bf 100644 --- 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; diff --git a/lib/prototypes.h b/lib/prototypes.h index 5c56e77e4..7e2f5d224 100644 --- a/lib/prototypes.h +++ b/lib/prototypes.h @@ -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; }; diff --git a/lib/subordinateio.c b/lib/subordinateio.c index e7cd4b482..bd59d8cf7 100644 --- a/lib/subordinateio.c +++ b/lib/subordinateio.c @@ -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 */ diff --git a/lib/subordinateio.h b/lib/subordinateio.h index d32733de9..3d1a05471 100644 --- a/lib/subordinateio.h +++ b/lib/subordinateio.h @@ -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 diff --git a/libsubid/api.c b/libsubid/api.c index 65d20abf9..6059b704e 100644 --- a/libsubid/api.c +++ b/libsubid/api.c @@ -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) { diff --git a/libsubid/subid.h.in b/libsubid/subid.h.in index 79744eda1..7090c6c80 100644 --- a/libsubid/subid.h.in +++ b/libsubid/subid.h.in @@ -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 * diff --git a/src/getsubids.c b/src/getsubids.c index 0753abd7a..871e850f2 100644 --- a/src/getsubids.c +++ b/src/getsubids.c @@ -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; }