Skip to content

Commit ac95ee2

Browse files
committed
uuidgen: generate UUIDs in bounded batches to respect kernel limit
The kernel uuidgen(2) system call enforces a hard limit of 2048 UUIDs per call, but uuidgen(1) attempted to generate arbitrarily many UUIDs in a single invocation and allocate memory proportional to the request size. Generate UUIDs in fixed-size batches instead to: - respect the kernel ABI - avoid unbounded memory allocation - prevent integer overflow in size calculations - preserve streaming behavior for large -n values Signed-off-by: NVSRahul <[email protected]>
1 parent 4cb65fd commit ac95ee2

File tree

1 file changed

+45
-38
lines changed

1 file changed

+45
-38
lines changed

bin/uuidgen/uuidgen.c

Lines changed: 45 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include <stdlib.h>
3535
#include <unistd.h>
3636
#include <uuid.h>
37+
#define UUID_BATCH_SIZE 2048
3738

3839
static void
3940
usage(void)
@@ -156,46 +157,52 @@ main(int argc, char *argv[])
156157
if (count == -1)
157158
count = 1;
158159

159-
store = (uuid_t *)malloc(sizeof(uuid_t) * count);
160-
if (store == NULL)
161-
err(1, "malloc()");
162-
163-
if (!iterate) {
164-
/* Get them all in a single batch */
165-
if (version == 1) {
166-
if (uuidgen(store, count) != 0)
167-
err(1, "uuidgen()");
168-
} else if (version == 4) {
169-
if (uuidgen_v4(store, count) != 0)
170-
err(1, "uuidgen_v4()");
171-
} else {
172-
err(1, "unsupported version");
173-
}
174-
} else {
175-
uuid = store;
176-
for (i = 0; i < count; i++) {
177-
if (version == 1) {
178-
if (uuidgen(uuid++, 1) != 0)
179-
err(1, "uuidgen()");
180-
} else if (version == 4) {
181-
if (uuidgen_v4(uuid++, 1) != 0)
182-
err(1, "uuidgen_v4()");
183-
} else {
184-
err(1, "unsupported version");
185-
}
186-
}
187-
}
160+
store = calloc(UUID_BATCH_SIZE, sizeof(uuid_t));
161+
if (store == NULL)
162+
err(1, "calloc()");
163+
164+
while (count > 0) {
165+
int batch = (count > UUID_BATCH_SIZE) ? UUID_BATCH_SIZE : count;
166+
167+
if (!iterate) {
168+
if (version == 1) {
169+
if (uuidgen(store, batch) != 0)
170+
err(1, "uuidgen()");
171+
} else if (version == 4) {
172+
if (uuidgen_v4(store, batch) != 0)
173+
err(1, "uuidgen_v4()");
174+
} else {
175+
err(1, "unsupported version");
176+
}
177+
} else {
178+
uuid = store;
179+
for (i = 0; i < batch; i++) {
180+
if (version == 1) {
181+
if (uuidgen(uuid++, 1) != 0)
182+
err(1, "uuidgen()");
183+
} else if (version == 4) {
184+
if (uuidgen_v4(uuid++, 1) != 0)
185+
err(1, "uuidgen_v4()");
186+
} else {
187+
err(1, "unsupported version");
188+
}
189+
}
190+
}
191+
192+
uuid = store;
193+
for (i = 0; i < batch; i++) {
194+
tostring(uuid++, &p, &status);
195+
if (status != uuid_s_ok)
196+
err(1, "cannot stringify a UUID");
197+
fprintf(fp, "%s\n", p);
198+
free(p);
199+
}
200+
201+
count -= batch;
202+
}
203+
free(store);
188204

189-
uuid = store;
190-
while (count--) {
191-
tostring(uuid++, &p, &status);
192-
if (status != uuid_s_ok)
193-
err(1, "cannot stringify a UUID");
194-
fprintf(fp, "%s\n", p);
195-
free(p);
196-
}
197205

198-
free(store);
199206
if (fp != stdout)
200207
fclose(fp);
201208
return (0);

0 commit comments

Comments
 (0)