diff --git a/src/libnss.zig b/src/libnss.zig index 97dadb4..786c79d 100644 --- a/src/libnss.zig +++ b/src/libnss.zig @@ -482,6 +482,7 @@ fn initgroups_dyn( const offset = user.additional_gids_offset; var vit = compress.varintSliceIteratorMust(db.additional_gids[offset..]); var gids = compress.deltaDecompressionIterator(&vit); + const remaining = vit.remaining; // the implementation below is ported from glibc's db-initgroups.c // even though we know the size of the groups upfront, I found it too difficult @@ -493,10 +494,17 @@ fn initgroups_dyn( return c.NSS_STATUS_SUCCESS; const oldsize = @intCast(usize, size.*); + const newsize_want = blk: { + // double the oldsize until it is above or equal 'remaining' + var res = oldsize; + while (res < remaining) res *= 2; + break :blk res; + }; + const newsize: usize = if (limit <= 0) - 2 * oldsize + newsize_want else - math.min(@intCast(usize, limit), 2 * oldsize); + math.min(@intCast(usize, limit), newsize_want); var buf = groupsp.*[0..oldsize]; const new_groups = state.initgroups_dyn_allocator.realloc(buf, newsize);