mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-28 03:49:38 +03:00
72a366f018
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
84 lines
2.0 KiB
C
84 lines
2.0 KiB
C
/*
|
|
* CDDL HEADER START
|
|
*
|
|
* The contents of this file are subject to the terms of the
|
|
* Common Development and Distribution License (the "License").
|
|
* You may not use this file except in compliance with the License.
|
|
*
|
|
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
|
* or https://opensource.org/licenses/CDDL-1.0.
|
|
* See the License for the specific language governing permissions
|
|
* and limitations under the License.
|
|
*
|
|
* When distributing Covered Code, include this CDDL HEADER in each
|
|
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
|
* If applicable, add the following below this CDDL HEADER, with the
|
|
* fields enclosed by brackets "[]" replaced with your own identifying
|
|
* information: Portions Copyright [yyyy] [name of copyright owner]
|
|
*
|
|
* CDDL HEADER END
|
|
*/
|
|
/*
|
|
* Copyright (c) 2017, Lawrence Livermore National Security, LLC.
|
|
*/
|
|
|
|
#include <fcntl.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/systeminfo.h>
|
|
|
|
static unsigned long
|
|
get_spl_hostid(void)
|
|
{
|
|
FILE *f;
|
|
unsigned long hostid;
|
|
char *env;
|
|
|
|
/*
|
|
* Allow the hostid to be subverted for testing.
|
|
*/
|
|
env = getenv("ZFS_HOSTID");
|
|
if (env)
|
|
return (strtoull(env, NULL, 0));
|
|
|
|
f = fopen("/proc/sys/kernel/spl/hostid", "re");
|
|
if (!f)
|
|
return (0);
|
|
|
|
if (fscanf(f, "%lx", &hostid) != 1)
|
|
hostid = 0;
|
|
|
|
fclose(f);
|
|
|
|
return (hostid);
|
|
}
|
|
|
|
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,
|
|
* depending on the libc and /etc/hostid presence,
|
|
* and the kernel and userspace must agree.
|
|
* See comments above hostid_read() in the SPL.
|
|
*/
|
|
if (hostid == 0) {
|
|
int fd = open("/etc/hostid", O_RDONLY | O_CLOEXEC);
|
|
if (fd >= 0) {
|
|
if (read(fd, &system_hostid, sizeof (system_hostid))
|
|
!= sizeof (system_hostid))
|
|
hostid = 0;
|
|
else
|
|
hostid = system_hostid;
|
|
(void) close(fd);
|
|
}
|
|
}
|
|
|
|
return (hostid & HOSTID_MASK);
|
|
}
|