Skip to content

Commit

Permalink
Linux: Fix big endian and partial read bugs in get_system_hostid()
Browse files Browse the repository at this point in the history
Coverity made two complaints about this function. The first is that we
ignore the number of bytes read. The second is that we have a sizeof
mismatch.

On 64-bit systems, long is a 64-bit type. Paradoxically, the standard
says that hostid is 32-bit, yet is also a long type. On 64-bit big
endian systems, reading into the long would cause us to return 0 as our
hostid after the mask. This is wrong.

Also, if a partial read were to happen (it should not), we would return
a partial hostid, which is also wrong.

We introduce a uint32_t system_hostid stack variable and ensure that the
read is done into it and check the read's return value. Then we set the
value based on whether the read was successful. This should fix both of
coverity's complaints.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Neal Gompa <ngompa@datto.com>
Signed-off-by: Richard Yao <richard.yao@alumni.stonybrook.edu>
Closes #13968
  • Loading branch information
ryao authored Oct 20, 2022
1 parent ab32a14 commit 72a366f
Showing 1 changed file with 5 additions and 1 deletion.
6 changes: 5 additions & 1 deletion lib/libspl/os/linux/gethostid.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ unsigned long
get_system_hostid(void)
{
unsigned long hostid = get_spl_hostid();
uint32_t system_hostid;

/*
* We do not use gethostid(3) because it can return a bogus ID,
Expand All @@ -69,8 +70,11 @@ get_system_hostid(void)
if (hostid == 0) {
int fd = open("/etc/hostid", O_RDONLY | O_CLOEXEC);
if (fd >= 0) {
if (read(fd, &hostid, 4) < 0)
if (read(fd, &system_hostid, sizeof (system_hostid))
!= sizeof (system_hostid))
hostid = 0;
else
hostid = system_hostid;
(void) close(fd);
}
}
Expand Down

0 comments on commit 72a366f

Please sign in to comment.