mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 11:25:21 +01:00
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
This commit is contained in:
1 parent
16c82e2840
commit
3570b19d74
4 files changed
+51
-42
No files matched your search
@@ -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
|
||||
|
||||
+44
-37
@@ -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()");
|
||||
store = calloc(MIN(count, UUIDGEN_BATCH_MAX), sizeof(uuid_t));
|
||||
if (store == NULL)
|
||||
err(1, "calloc()");
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
while (count > 0) {
|
||||
int batch = (count > UUIDGEN_BATCH_MAX) ? UUIDGEN_BATCH_MAX : count;
|
||||
|
||||
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);
|
||||
}
|
||||
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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in new issue
Block a user