safety checks in group parsing
This commit is contained in:
parent
e1cae43d08
commit
a447e7fdf4
24
src/DB.zig
24
src/DB.zig
@ -368,21 +368,25 @@ pub fn packCGroup(self: *const DB, group: *const PackedGroup, buf: []u8) error{
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getGroupByName(self: *const DB, name: []const u8) ?PackedGroup {
|
pub fn getGroupByName(self: *const DB, name: []const u8) error{Overflow}!?PackedGroup {
|
||||||
const idx = bdz.search(self.bdz_groupname, name);
|
const idx = bdz.search(self.bdz_groupname, name);
|
||||||
if (idx >= self.header.num_groups) return null;
|
if (idx >= self.header.num_groups)
|
||||||
|
return null;
|
||||||
const offset = self.idx_groupname2group[idx];
|
const offset = self.idx_groupname2group[idx];
|
||||||
const group = PackedGroup.fromBytes(@alignCast(8, self.groups[offset << 3 ..])).group;
|
const group = (try PackedGroup.fromBytes(@alignCast(8, self.groups[offset << 3 ..]))).group;
|
||||||
if (!mem.eql(u8, name, group.name())) return null;
|
if (!mem.eql(u8, name, group.name()))
|
||||||
|
return null;
|
||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getGroupByGid(self: *const DB, gid: u32) ?PackedGroup {
|
pub fn getGroupByGid(self: *const DB, gid: u32) error{Overflow}!?PackedGroup {
|
||||||
const idx = bdz.search_u32(self.bdz_gid, gid);
|
const idx = bdz.search_u32(self.bdz_gid, gid);
|
||||||
if (idx >= self.header.num_groups) return null;
|
if (idx >= self.header.num_groups)
|
||||||
|
return null;
|
||||||
const offset = self.idx_gid2group[idx];
|
const offset = self.idx_gid2group[idx];
|
||||||
const group = PackedGroup.fromBytes(@alignCast(8, self.groups[offset << 3 ..])).group;
|
const group = (try PackedGroup.fromBytes(@alignCast(8, self.groups[offset << 3 ..]))).group;
|
||||||
if (gid != group.gid()) return null;
|
if (gid != group.gid())
|
||||||
|
return null;
|
||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -393,7 +397,7 @@ pub fn getgrnam(
|
|||||||
buf: []u8,
|
buf: []u8,
|
||||||
omit_members: bool,
|
omit_members: bool,
|
||||||
) error{ Overflow, BufferTooSmall }!?CGroup {
|
) error{ Overflow, BufferTooSmall }!?CGroup {
|
||||||
const group = self.getGroupByName(name) orelse return null;
|
const group = try self.getGroupByName(name) orelse return null;
|
||||||
if (omit_members)
|
if (omit_members)
|
||||||
return try packCGroupNoMembers(&group, buf)
|
return try packCGroupNoMembers(&group, buf)
|
||||||
else
|
else
|
||||||
@ -407,7 +411,7 @@ pub fn getgrgid(
|
|||||||
buf: []u8,
|
buf: []u8,
|
||||||
omit_members: bool,
|
omit_members: bool,
|
||||||
) error{ Overflow, BufferTooSmall }!?CGroup {
|
) error{ Overflow, BufferTooSmall }!?CGroup {
|
||||||
const group = self.getGroupByGid(gid) orelse return null;
|
const group = try self.getGroupByGid(gid) orelse return null;
|
||||||
if (omit_members)
|
if (omit_members)
|
||||||
return try packCGroupNoMembers(&group, buf)
|
return try packCGroupNoMembers(&group, buf)
|
||||||
else
|
else
|
||||||
|
@ -39,13 +39,11 @@ pub const Entry = struct {
|
|||||||
end: usize,
|
end: usize,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn fromBytes(bytes: []align(8) const u8) Entry {
|
pub fn fromBytes(bytes: []align(8) const u8) error{Overflow}!Entry {
|
||||||
const inner = mem.bytesAsValue(Inner, bytes[0..@sizeOf(Inner)]);
|
const inner = mem.bytesAsValue(Inner, bytes[0..@sizeOf(Inner)]);
|
||||||
const start_blob = @sizeOf(Inner);
|
const start_blob = @sizeOf(Inner);
|
||||||
const end_strings = @sizeOf(Inner) + inner.groupnameLen();
|
const end_strings = @sizeOf(Inner) + inner.groupnameLen();
|
||||||
const members_offset = compress.uvarint(bytes[end_strings..]) catch |err| switch (err) {
|
const members_offset = try compress.uvarint(bytes[end_strings..]);
|
||||||
error.Overflow => unreachable,
|
|
||||||
};
|
|
||||||
const end_blob = end_strings + members_offset.bytes_read;
|
const end_blob = end_strings + members_offset.bytes_read;
|
||||||
|
|
||||||
return Entry{
|
return Entry{
|
||||||
@ -70,9 +68,9 @@ pub const Iterator = struct {
|
|||||||
total: u32,
|
total: u32,
|
||||||
advanced_by: usize = 0,
|
advanced_by: usize = 0,
|
||||||
|
|
||||||
pub fn next(it: *Iterator) ?PackedGroup {
|
pub fn next(it: *Iterator) error{Overflow}!?PackedGroup {
|
||||||
if (it.idx == it.total) return null;
|
if (it.idx == it.total) return null;
|
||||||
const entry = fromBytes(@alignCast(8, it.section[it.next_start..]));
|
const entry = try fromBytes(@alignCast(8, it.section[it.next_start..]));
|
||||||
it.idx += 1;
|
it.idx += 1;
|
||||||
it.next_start += entry.end;
|
it.next_start += entry.end;
|
||||||
it.advanced_by = entry.end;
|
it.advanced_by = entry.end;
|
||||||
@ -149,7 +147,7 @@ test "PackedGroup construct" {
|
|||||||
|
|
||||||
var i: u29 = 0;
|
var i: u29 = 0;
|
||||||
var it = PackedGroup.iterator(buf.items, groups.len);
|
var it = PackedGroup.iterator(buf.items, groups.len);
|
||||||
while (it.next()) |group| : (i += 1) {
|
while (try it.next()) |group| : (i += 1) {
|
||||||
try testing.expectEqual(groups[i].gid, group.gid());
|
try testing.expectEqual(groups[i].gid, group.gid());
|
||||||
try testing.expectEqualStrings(groups[i].name, group.name());
|
try testing.expectEqualStrings(groups[i].name, group.name());
|
||||||
try testing.expectEqual(groups[i].members_offset, group.membersOffset());
|
try testing.expectEqual(groups[i].members_offset, group.membersOffset());
|
||||||
|
@ -369,7 +369,9 @@ fn getgrent_r(
|
|||||||
return c.NSS_STATUS_UNAVAIL;
|
return c.NSS_STATUS_UNAVAIL;
|
||||||
});
|
});
|
||||||
|
|
||||||
const group = it.next() orelse {
|
const group = it.next() catch |err| switch (err) {
|
||||||
|
error.Overflow => return badFile(errnop),
|
||||||
|
} orelse {
|
||||||
errnop.* = 0;
|
errnop.* = 0;
|
||||||
return c.NSS_STATUS_NOTFOUND;
|
return c.NSS_STATUS_NOTFOUND;
|
||||||
};
|
};
|
||||||
|
@ -159,7 +159,7 @@ fn group(stdout: anytype, db: *const DB, keys: []const [*:0]const u8) error{Over
|
|||||||
|
|
||||||
for (keys) |key| {
|
for (keys) |key| {
|
||||||
const keyZ = mem.span(key);
|
const keyZ = mem.span(key);
|
||||||
const maybe_packed_group = if (fmt.parseUnsigned(u32, keyZ, 10)) |gid|
|
const maybe_packed_group = try if (fmt.parseUnsigned(u32, keyZ, 10)) |gid|
|
||||||
db.getGroupByGid(gid)
|
db.getGroupByGid(gid)
|
||||||
else |_|
|
else |_|
|
||||||
db.getGroupByName(keyZ);
|
db.getGroupByName(keyZ);
|
||||||
@ -178,7 +178,7 @@ fn group(stdout: anytype, db: *const DB, keys: []const [*:0]const u8) error{Over
|
|||||||
|
|
||||||
fn groupAll(stdout: anytype, db: *const DB) error{Overflow}!u8 {
|
fn groupAll(stdout: anytype, db: *const DB) error{Overflow}!u8 {
|
||||||
var it = PackedGroup.iterator(db.groups, db.header.num_groups);
|
var it = PackedGroup.iterator(db.groups, db.header.num_groups);
|
||||||
while (it.next()) |g|
|
while (try it.next()) |g|
|
||||||
if (try printGroup(stdout, db, &g)) |exit_code|
|
if (try printGroup(stdout, db, &g)) |exit_code|
|
||||||
return exit_code;
|
return exit_code;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user