git: 3570b19d74ed - main - uuidgen: generate UUIDs in bounded batches to respect kernel limit
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 07 Mar 2026 07:51:25 UTC
The branch main has been updated by imp:
URL: https://cgit.FreeBSD.org/src/commit/?id=3570b19d74ed94dcc7fac2dcbf42b378bc72362e
commit 3570b19d74ed94dcc7fac2dcbf42b378bc72362e
Author: NVSRahul <nvsrahul@hotmail.com>
AuthorDate: 2026-01-13 05:52:06 +0000
Commit: Warner Losh <imp@FreeBSD.org>
CommitDate: 2026-03-07 07:51:16 +0000
uuidgen: generate UUIDs in bounded batches to respect kernel limit
The uuidgen(2) system call enforces a hard upper limit of 2048 UUIDs per
invocation. uuidgen(1) previously attempted to generate arbitrary counts
in a single call and allocated memory accordingly, leading to EINVAL
errors, unnecessary memory usage, and potential overflow risks.
Generate UUIDs in fixed-size batches, streaming output incrementally
while preserving existing semantics. Mirror the kernel limit explicitly
since it is not exposed via a public interface.
Signed-off-by: NVSRahul <nvsrahul@hotmail.com>
Reviewed by: imp
Pull Request: https://github.com/freebsd/freebsd-src/pull/1965
---
bin/uuidgen/uuidgen.1 | 4 ---
bin/uuidgen/uuidgen.c | 85 ++++++++++++++++++++++++++++-----------------------
sys/kern/kern_uuid.c | 2 +-
sys/sys/uuid.h | 6 ++++
4 files changed, 53 insertions(+), 44 deletions(-)
diff --git a/bin/uuidgen/uuidgen.1 b/bin/uuidgen/uuidgen.1
index f7911b408f36..f88ea8d8631d 100644
--- a/bin/uuidgen/uuidgen.1
+++ b/bin/uuidgen/uuidgen.1
@@ -56,10 +56,6 @@ This option controls creation of compact UUID (without hyphen).
.It Fl n
This option controls the number of identifiers generated.
By default, multiple identifiers are generated in batch.
-The upper hard limit is 2048
-.Po see
-.Xr uuidgen 2
-.Pc .
.It Fl o
Redirect output to
.Ar filename
diff --git a/bin/uuidgen/uuidgen.c b/bin/uuidgen/uuidgen.c
index 3e2c0324a959..bcb7a45b665d 100644
--- a/bin/uuidgen/uuidgen.c
+++ b/bin/uuidgen/uuidgen.c
@@ -26,7 +26,9 @@
*
*/
+#include <sys/param.h>
#include <sys/capsicum.h>
+#include <sys/uuid.h>
#include <capsicum_helpers.h>
#include <err.h>
@@ -156,46 +158,51 @@ main(int argc, char *argv[])
if (count == -1)
count = 1;
- store = (uuid_t *)malloc(sizeof(uuid_t) * count);
- if (store == NULL)
- err(1, "malloc()");
-
- if (!iterate) {
- /* Get them all in a single batch */
- if (version == 1) {
- if (uuidgen(store, count) != 0)
- err(1, "uuidgen()");
- } else if (version == 4) {
- if (uuidgen_v4(store, count) != 0)
- err(1, "uuidgen_v4()");
- } else {
- err(1, "unsupported version");
- }
- } else {
- uuid = store;
- for (i = 0; i < count; i++) {
- if (version == 1) {
- if (uuidgen(uuid++, 1) != 0)
- err(1, "uuidgen()");
- } else if (version == 4) {
- if (uuidgen_v4(uuid++, 1) != 0)
- err(1, "uuidgen_v4()");
- } else {
- err(1, "unsupported version");
- }
- }
- }
-
- uuid = store;
- while (count--) {
- tostring(uuid++, &p, &status);
- if (status != uuid_s_ok)
- err(1, "cannot stringify a UUID");
- fprintf(fp, "%s\n", p);
- free(p);
- }
+ store = calloc(MIN(count, UUIDGEN_BATCH_MAX), sizeof(uuid_t));
+ if (store == NULL)
+ err(1, "calloc()");
+
+ while (count > 0) {
+ int batch = (count > UUIDGEN_BATCH_MAX) ? UUIDGEN_BATCH_MAX : count;
+
+ if (!iterate) {
+ if (version == 1) {
+ if (uuidgen(store, batch) != 0)
+ err(1, "uuidgen()");
+ } else if (version == 4) {
+ if (uuidgen_v4(store, batch) != 0)
+ err(1, "uuidgen_v4()");
+ } else {
+ err(1, "unsupported version");
+ }
+ } else {
+ uuid = store;
+ for (i = 0; i < batch; i++) {
+ if (version == 1) {
+ if (uuidgen(uuid++, 1) != 0)
+ err(1, "uuidgen()");
+ } else if (version == 4) {
+ if (uuidgen_v4(uuid++, 1) != 0)
+ err(1, "uuidgen_v4()");
+ } else {
+ err(1, "unsupported version");
+ }
+ }
+ }
+
+ uuid = store;
+ for (i = 0; i < batch; i++) {
+ tostring(uuid++, &p, &status);
+ if (status != uuid_s_ok)
+ err(1, "cannot stringify a UUID");
+ fprintf(fp, "%s\n", p);
+ free(p);
+ }
+
+ count -= batch;
+ }
+ free(store);
- free(store);
if (fp != stdout)
fclose(fp);
return (0);
diff --git a/sys/kern/kern_uuid.c b/sys/kern/kern_uuid.c
index fb27f7bbf736..136242ca2087 100644
--- a/sys/kern/kern_uuid.c
+++ b/sys/kern/kern_uuid.c
@@ -186,7 +186,7 @@ sys_uuidgen(struct thread *td, struct uuidgen_args *uap)
* like to have some sort of upper-bound that's less than 2G :-)
* XXX probably needs to be tunable.
*/
- if (uap->count < 1 || uap->count > 2048)
+ if (uap->count < 1 || uap->count > UUIDGEN_BATCH_MAX)
return (EINVAL);
count = uap->count;
diff --git a/sys/sys/uuid.h b/sys/sys/uuid.h
index 5fc5e61457de..3694988ccf5c 100644
--- a/sys/sys/uuid.h
+++ b/sys/sys/uuid.h
@@ -34,6 +34,12 @@
/* Length of a node address (an IEEE 802 address). */
#define _UUID_NODE_LEN 6
+/*
+ * The kernel imposes a limit on the number of UUIDs generated per call
+ * to avoid unbounded allocations.
+ */
+#define UUIDGEN_BATCH_MAX 2048
+
/*
* See also:
* http://www.opengroup.org/dce/info/draft-leach-uuids-guids-01.txt