The branch main has been updated by imp:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=3570b19d74ed94dcc7fac2dcbf42b378bc72362e

commit 3570b19d74ed94dcc7fac2dcbf42b378bc72362e
Author:     NVSRahul <[email protected]>
AuthorDate: 2026-01-13 05:52:06 +0000
Commit:     Warner Losh <[email protected]>
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 <[email protected]>
    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

Reply via email to