libzfs: zpool_load_compat(): open feature file cloexec
As a bonus, this also passes the open flags into the open flags instead of the mode (it worked by accident because O_RDONLY is 0), correctly detects a failed map, and prefaults the entire file since we're always writing to every page Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz> Closes #11993
This commit is contained in:
parent
74256266ff
commit
133fd00930
|
@ -4812,14 +4812,14 @@ zpool_load_compat(const char *compat, boolean_t *features, char *report,
|
||||||
file != NULL;
|
file != NULL;
|
||||||
file = strtok_r(NULL, ",", &ps)) {
|
file = strtok_r(NULL, ",", &ps)) {
|
||||||
|
|
||||||
boolean_t l_features[SPA_FEATURES];
|
boolean_t l_features[SPA_FEATURES] = {B_FALSE};
|
||||||
|
|
||||||
enum { Z_SYSCONF, Z_DATA } source;
|
enum { Z_SYSCONF, Z_DATA } source;
|
||||||
|
|
||||||
/* try sysconfdir first, then datadir */
|
/* try sysconfdir first, then datadir */
|
||||||
source = Z_SYSCONF;
|
source = Z_SYSCONF;
|
||||||
if ((featfd = openat(sdirfd, file, 0, O_RDONLY)) < 0) {
|
if ((featfd = openat(sdirfd, file, O_RDONLY | O_CLOEXEC)) < 0) {
|
||||||
featfd = openat(ddirfd, file, 0, O_RDONLY);
|
featfd = openat(ddirfd, file, O_RDONLY | O_CLOEXEC);
|
||||||
source = Z_DATA;
|
source = Z_DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4835,13 +4835,18 @@ zpool_load_compat(const char *compat, boolean_t *features, char *report,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(MAP_POPULATE) && defined(MAP_PREFAULT_READ)
|
||||||
|
#define MAP_POPULATE MAP_PREFAULT_READ
|
||||||
|
#elif !defined(MAP_POPULATE)
|
||||||
|
#define MAP_POPULATE 0
|
||||||
|
#endif
|
||||||
/* private mmap() so we can strtok safely */
|
/* private mmap() so we can strtok safely */
|
||||||
fc = (char *)mmap(NULL, fs.st_size,
|
fc = (char *)mmap(NULL, fs.st_size,
|
||||||
PROT_READ|PROT_WRITE, MAP_PRIVATE, featfd, 0);
|
PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_POPULATE, featfd, 0);
|
||||||
(void) close(featfd);
|
(void) close(featfd);
|
||||||
|
|
||||||
/* map ok, and last character == newline? */
|
/* map ok, and last character == newline? */
|
||||||
if (fc < 0 || fc[fs.st_size - 1] != '\n') {
|
if (fc == MAP_FAILED || fc[fs.st_size - 1] != '\n') {
|
||||||
(void) munmap((void *) fc, fs.st_size);
|
(void) munmap((void *) fc, fs.st_size);
|
||||||
strlcat(err_badfile, file, ZFS_MAXPROPLEN);
|
strlcat(err_badfile, file, ZFS_MAXPROPLEN);
|
||||||
strlcat(err_badfile, " ", ZFS_MAXPROPLEN);
|
strlcat(err_badfile, " ", ZFS_MAXPROPLEN);
|
||||||
|
@ -4851,9 +4856,6 @@ zpool_load_compat(const char *compat, boolean_t *features, char *report,
|
||||||
|
|
||||||
ret_nofiles = B_FALSE;
|
ret_nofiles = B_FALSE;
|
||||||
|
|
||||||
for (uint_t i = 0; i < SPA_FEATURES; i++)
|
|
||||||
l_features[i] = B_FALSE;
|
|
||||||
|
|
||||||
/* replace last char with NUL to ensure we have a delimiter */
|
/* replace last char with NUL to ensure we have a delimiter */
|
||||||
fc[fs.st_size - 1] = '\0';
|
fc[fs.st_size - 1] = '\0';
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue