From: Christian Brauner Date: Mon, 9 Mar 2020 09:18:55 +0000 (+0100) Subject: tree-wide: make files cloexec whenever possible X-Git-Tag: lxc-4.0.0~42^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4110345b7a66da119c56d68e550994454933348d;p=thirdparty%2Flxc.git tree-wide: make files cloexec whenever possible Signed-off-by: Christian Brauner --- diff --git a/src/lxc/attach.c b/src/lxc/attach.c index cee696752..7b2550aa6 100644 --- a/src/lxc/attach.c +++ b/src/lxc/attach.c @@ -429,7 +429,7 @@ static char *lxc_attach_getpwshell(uid_t uid) close(pipes[1]); - pipe_f = fdopen(pipes[0], "r"); + pipe_f = fdopen(pipes[0], "re"); if (!pipe_f) { close(pipes[0]); goto reap_child; @@ -525,7 +525,7 @@ static void lxc_attach_get_init_uidgid(uid_t *init_uid, gid_t *init_gid) if (ret < 0 || ret >= LXC_PROC_STATUS_LEN) return; - proc_file = fopen(proc_fn, "r"); + proc_file = fopen(proc_fn, "re"); if (!proc_file) return; diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c index 7677567cb..4c21a6f29 100644 --- a/src/lxc/cgroups/cgfsng.c +++ b/src/lxc/cgroups/cgfsng.c @@ -224,7 +224,7 @@ static char *read_file(const char *fnam) char *buf = NULL; size_t len = 0, fulllen = 0; - f = fopen(fnam, "r"); + f = fopen(fnam, "re"); if (!f) return NULL; while ((linelen = getline(&line, &len, f)) != -1) { @@ -902,7 +902,7 @@ static int get_existing_subsystems(char ***klist, char ***nlist) __do_fclose FILE *f = NULL; size_t len = 0; - f = fopen("/proc/self/cgroup", "r"); + f = fopen("/proc/self/cgroup", "re"); if (!f) return -1; @@ -2961,7 +2961,7 @@ static int cg_hybrid_init(struct cgroup_ops *ops, bool relative, bool unprivileg if (ret < 0) return log_error_errno(-1, errno, "Failed to retrieve available legacy cgroup controllers"); - f = fopen("/proc/self/mountinfo", "r"); + f = fopen("/proc/self/mountinfo", "re"); if (!f) return log_error_errno(-1, errno, "Failed to open \"/proc/self/mountinfo\""); diff --git a/src/lxc/cmd/lxc_init.c b/src/lxc/cmd/lxc_init.c index 000cefddb..10fe64f2b 100644 --- a/src/lxc/cmd/lxc_init.c +++ b/src/lxc/cmd/lxc_init.c @@ -85,7 +85,7 @@ static void prevent_forking(void) char path[PATH_MAX]; size_t len = 0; - f = fopen("/proc/self/cgroup", "r"); + f = fopen("/proc/self/cgroup", "re"); if (!f) return; @@ -150,7 +150,7 @@ static void kill_children(pid_t pid) return; } - f = fopen(path, "r"); + f = fopen(path, "re"); if (!f) { if (my_args.quiet) fprintf(stderr, "Failed to open %s\n", path); diff --git a/src/lxc/cmd/lxc_user_nic.c b/src/lxc/cmd/lxc_user_nic.c index 43b58d11c..f2388a5b4 100644 --- a/src/lxc/cmd/lxc_user_nic.c +++ b/src/lxc/cmd/lxc_user_nic.c @@ -323,7 +323,7 @@ static int get_alloted(char *me, char *intype, char *link, int count = 0; size_t len = 0; - fin = fopen(LXC_USERNIC_CONF, "r"); + fin = fopen(LXC_USERNIC_CONF, "re"); if (!fin) { CMD_SYSERROR("Failed to open \"%s\"\n", LXC_USERNIC_CONF); return -1; diff --git a/src/lxc/cmd/lxc_usernsexec.c b/src/lxc/cmd/lxc_usernsexec.c index 31e6d52cb..6441fb3c8 100644 --- a/src/lxc/cmd/lxc_usernsexec.c +++ b/src/lxc/cmd/lxc_usernsexec.c @@ -195,7 +195,7 @@ static int read_default_map(char *fnam, int which, char *user) int ret = -1; size_t sz = 0; - fin = fopen(fnam, "r"); + fin = fopen(fnam, "re"); if (!fin) return -1; diff --git a/src/lxc/conf.c b/src/lxc/conf.c index 9678fe7bf..a8d2ffadf 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -1392,7 +1392,7 @@ int lxc_chroot(const struct lxc_rootfs *rootfs) int progress = 0; size_t len = 0; - f = fopen("./proc/self/mountinfo", "r"); + f = fopen("./proc/self/mountinfo", "re"); if (!f) { SYSERROR("Failed to open \"/proc/self/mountinfo\""); return -1; @@ -2366,6 +2366,7 @@ FILE *make_anonymous_mount_file(struct lxc_list *mount, bool include_nesting_helpers) { __do_close_prot_errno int fd = -EBADF; + FILE *f; int ret; char *mount_entry; struct lxc_list *iterator; @@ -2412,7 +2413,10 @@ FILE *make_anonymous_mount_file(struct lxc_list *mount, if (ret < 0) return NULL; - return fdopen(move_fd(fd), "r+"); + f = fdopen(fd, "re+"); + if (f) + move_fd(fd); /* Transfer ownership of fd. */ + return f; } static int setup_mount_entries(const struct lxc_conf *conf, @@ -3304,7 +3308,7 @@ again: return; } - f = fdopen(memfd, "r"); + f = fdopen(memfd, "re"); if (!f) { SYSERROR("Failed to open copy of \"/proc/self/mountinfo\" to mark all shared. Continuing"); return; @@ -4704,7 +4708,7 @@ void suggest_default_idmap(void) if (!gname) return; - subuid_f = fopen(subuidfile, "r"); + subuid_f = fopen(subuidfile, "re"); if (!subuid_f) { ERROR("Your system is not configured with subuids"); return; @@ -4741,7 +4745,7 @@ void suggest_default_idmap(void) WARN("Could not parse UID range"); } - subgid_f = fopen(subgidfile, "r"); + subgid_f = fopen(subgidfile, "re"); if (!subgid_f) { ERROR("Your system is not configured with subgids"); return; diff --git a/src/lxc/confile.c b/src/lxc/confile.c index 804663868..a24bcff74 100644 --- a/src/lxc/confile.c +++ b/src/lxc/confile.c @@ -150,7 +150,7 @@ lxc_config_define(proc); /* * Important Note: - * If a new config option is added to this table, be aware that + * If a new config option is added to this table, be aware that * the order in which the options are places into the table matters. * That means that more specific options of a namespace have to be * placed above more generic ones. @@ -2464,8 +2464,8 @@ int append_unexp_config_line(const char *line, struct lxc_conf *conf) static int do_includedir(const char *dirp, struct lxc_conf *lxc_conf) { + __do_closedir DIR *dir = NULL; struct dirent *direntp; - DIR *dir; char path[PATH_MAX]; int len; int ret = -1; @@ -2489,21 +2489,15 @@ static int do_includedir(const char *dirp, struct lxc_conf *lxc_conf) continue; len = snprintf(path, PATH_MAX, "%s/%s", dirp, fnam); - if (len < 0 || len >= PATH_MAX) { - ret = -1; - goto out; - } + if (len < 0 || len >= PATH_MAX) + return -1; ret = lxc_config_read(path, lxc_conf, true); if (ret < 0) - goto out; + return -1; } - ret = 0; -out: - closedir(dir); - - return ret; + return 0; } static int set_config_includefiles(const char *key, const char *value, diff --git a/src/lxc/criu.c b/src/lxc/criu.c index a68b4674c..59e50047b 100644 --- a/src/lxc/criu.c +++ b/src/lxc/criu.c @@ -89,7 +89,7 @@ static int load_tty_major_minor(char *directory, char *output, int len) return -1; } - f = fopen(path, "r"); + f = fopen(path, "re"); if (!f) { /* This means we're coming from a liblxc which didn't export * the tty info. In this case they had to have lxc.console.path @@ -793,7 +793,7 @@ static bool criu_version_ok(char **version) return false; } - f = fdopen(pipes[0], "r"); + f = fdopen(pipes[0], "re"); if (!f) { close(pipes[0]); return false; @@ -1085,7 +1085,7 @@ static void do_restore(struct lxc_container *c, int status_pipe, struct migrate_ goto out_fini_handler; } - FILE *f = fopen(buf, "r"); + FILE *f = fopen(buf, "re"); if (!f) { SYSERROR("couldn't read restore's children file %s", buf); goto out_fini_handler; @@ -1202,7 +1202,7 @@ static int save_tty_major_minor(char *directory, struct lxc_container *c, char * return -1; } - f = fopen(path, "w"); + f = fopen(path, "we"); if (!f) { SYSERROR("failed to open %s", path); return -1; diff --git a/src/lxc/file_utils.c b/src/lxc/file_utils.c index 009d26d7c..687a4a7e9 100644 --- a/src/lxc/file_utils.c +++ b/src/lxc/file_utils.c @@ -235,7 +235,7 @@ int print_to_file(const char *file, const char *content) FILE *f; int ret = 0; - f = fopen(file, "w"); + f = fopen(file, "we"); if (!f) return -1; @@ -395,45 +395,6 @@ again: return ret; } -char *file_to_buf(char *path, size_t *length) -{ - int fd; - char buf[PATH_MAX]; - char *copy = NULL; - - if (!length) - return NULL; - - fd = open(path, O_RDONLY | O_CLOEXEC); - if (fd < 0) - return NULL; - - *length = 0; - for (;;) { - int n; - char *old = copy; - - n = lxc_read_nointr(fd, buf, sizeof(buf)); - if (n < 0) - goto on_error; - if (!n) - break; - - copy = must_realloc(old, (*length + n) * sizeof(*old)); - memcpy(copy + *length, buf, n); - *length += n; - } - - close(fd); - return copy; - -on_error: - close(fd); - free(copy); - - return NULL; -} - int fd_to_fd(int from, int to) { for (;;) { @@ -463,3 +424,80 @@ int fd_to_fd(int from, int to) return 0; } + +static char *fd_to_buf(int fd, size_t *length) +{ + __do_free char *copy = NULL; + + if (!length) + return NULL; + + *length = 0; + for (;;) { + ssize_t bytes_read; + char buf[4096]; + char *old = copy; + + bytes_read = lxc_read_nointr(fd, buf, sizeof(buf)); + if (bytes_read < 0) + return NULL; + + if (!bytes_read) + break; + + copy = must_realloc(old, (*length + bytes_read) * sizeof(*old)); + memcpy(copy + *length, buf, bytes_read); + *length += bytes_read; + } + + return move_ptr(copy); +} + +char *file_to_buf(const char *path, size_t *length) +{ + __do_close_prot_errno int fd = -EBADF; + + if (!length) + return NULL; + + fd = open(path, O_RDONLY | O_CLOEXEC); + if (fd < 0) + return NULL; + + return fd_to_buf(fd, length); +} + +FILE *fopen_cached(const char *path, const char *mode, void **caller_freed_buffer) +{ + __do_free char *buf = NULL; + size_t len = 0; + FILE *f; + + buf = file_to_buf(path, &len); + if (!buf) + return NULL; + + f = fmemopen(buf, len, mode); + if (!f) + return NULL; + *caller_freed_buffer = move_ptr(buf); + return f; +} + +FILE *fdopen_cached(int fd, const char *mode, void **caller_freed_buffer) +{ + __do_free char *buf = NULL; + size_t len = 0; + FILE *f; + + buf = fd_to_buf(fd, &len); + if (!buf) + return NULL; + + f = fmemopen(buf, len, mode); + if (!f) + return NULL; + + *caller_freed_buffer = move_ptr(buf); + return f; +} diff --git a/src/lxc/file_utils.h b/src/lxc/file_utils.h index 9faf41d36..8b31b976e 100644 --- a/src/lxc/file_utils.h +++ b/src/lxc/file_utils.h @@ -48,8 +48,11 @@ extern bool is_fs_type(const struct statfs *fs, fs_type_magic magic_val); extern FILE *fopen_cloexec(const char *path, const char *mode); extern ssize_t lxc_sendfile_nointr(int out_fd, int in_fd, off_t *offset, size_t count); -extern char *file_to_buf(char *path, size_t *length); +extern char *file_to_buf(const char *path, size_t *length); extern int fd_to_fd(int from, int to); extern int lxc_open_dirfd(const char *dir); +extern FILE *fdopen_cached(int fd, const char *mode, void **caller_freed_buffer); +extern FILE *fopen_cached(const char *path, const char *mode, + void **caller_freed_buffer); #endif /* __LXC_FILE_UTILS_H */ diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 55e391870..3bc347f4d 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -719,7 +719,7 @@ WRAP_API_2(bool, lxcapi_wait, const char *, int) static bool am_single_threaded(void) { - DIR *dir; + __do_closedir DIR *dir = NULL; struct dirent *direntp; int count = 0; @@ -738,7 +738,6 @@ static bool am_single_threaded(void) if (count > 1) break; } - closedir(dir); return count == 1; } @@ -1649,7 +1648,7 @@ static bool prepend_lxc_header(char *path, const char *t, char *const argv[]) char *tpath; #endif - f = fopen(path, "r"); + f = fopen(path, "re"); if (f == NULL) return false; @@ -1702,7 +1701,7 @@ static bool prepend_lxc_header(char *path, const char *t, char *const argv[]) free(tpath); #endif - f = fopen(path, "w"); + f = fopen(path, "we"); if (f == NULL) { SYSERROR("Reopening config for writing"); free(contents); @@ -2699,7 +2698,7 @@ static bool mod_rdep(struct lxc_container *c0, struct lxc_container *c, bool inc /* If we find an lxc-snapshot file using the old format only listing the * number of snapshots we will keep using it. */ - f1 = fopen(path, "r"); + f1 = fopen(path, "re"); if (f1) { n = fscanf(f1, "%d", &v); fclose(f1); @@ -2714,7 +2713,7 @@ static bool mod_rdep(struct lxc_container *c0, struct lxc_container *c, bool inc if (n == 1) { v += inc ? 1 : -1; - f1 = fopen(path, "w"); + f1 = fopen(path, "we"); if (!f1) goto out; @@ -2733,7 +2732,7 @@ static bool mod_rdep(struct lxc_container *c0, struct lxc_container *c, bool inc /* Here we know that we have or can use an lxc-snapshot file * using the new format. */ if (inc) { - f1 = fopen(path, "a"); + f1 = fopen(path, "ae"); if (!f1) goto out; @@ -2817,7 +2816,7 @@ void mod_all_rdeps(struct lxc_container *c, bool inc) return; } - f = fopen(path, "r"); + f = fopen(path, "re"); if (f == NULL) return; @@ -2868,7 +2867,7 @@ static bool has_fs_snapshots(struct lxc_container *c) v = fbuf.st_size; if (v != 0) { - f = fopen(path, "r"); + f = fopen(path, "re"); if (!f) goto out; @@ -2887,10 +2886,10 @@ out: static bool has_snapshots(struct lxc_container *c) { + __do_closedir DIR *dir = NULL; char path[PATH_MAX]; struct dirent *direntp; - int count=0; - DIR *dir; + int count = 0; if (!get_snappath_dir(c, path)) return false; @@ -2909,7 +2908,6 @@ static bool has_snapshots(struct lxc_container *c) break; } - closedir(dir); return count > 0; } @@ -3540,7 +3538,7 @@ static bool add_rdepends(struct lxc_container *c, struct lxc_container *c0) if (ret < 0 || ret >= PATH_MAX) return false; - f = fopen(path, "a"); + f = fopen(path, "ae"); if (!f) return false; @@ -3736,7 +3734,7 @@ static int clone_update_rootfs(struct clone_update_data *data) if (!file_exists(path)) return 0; - if (!(fout = fopen(path, "w"))) { + if (!(fout = fopen(path, "we"))) { SYSERROR("unable to open %s: ignoring", path); return 0; } @@ -4216,7 +4214,7 @@ static int do_lxcapi_snapshot(struct lxc_container *c, const char *commentfile) len = strlen(snappath) + 1 + strlen(newname) + 1 + strlen(LXC_TIMESTAMP_FNAME) + 1; dfnam = must_realloc(NULL, len); snprintf(dfnam, len, "%s/%s/%s", snappath, newname, LXC_TIMESTAMP_FNAME); - f = fopen(dfnam, "w"); + f = fopen(dfnam, "we"); if (!f) { ERROR("Failed to open %s", dfnam); return -1; @@ -4284,7 +4282,7 @@ static char *get_timestamp(char* snappath, char *name) if (ret < 0 || ret >= PATH_MAX) return NULL; - fin = fopen(path, "r"); + fin = fopen(path, "re"); if (!fin) return NULL; @@ -4309,11 +4307,11 @@ static char *get_timestamp(char* snappath, char *name) static int do_lxcapi_snapshot_list(struct lxc_container *c, struct lxc_snapshot **ret_snaps) { + __do_closedir DIR *dir = NULL; char snappath[PATH_MAX], path2[PATH_MAX]; int count = 0, ret; struct dirent *direntp; struct lxc_snapshot *snaps =NULL, *nsnaps; - DIR *dir; if (!c || !lxcapi_is_defined(c)) return -1; @@ -4376,17 +4374,12 @@ static int do_lxcapi_snapshot_list(struct lxc_container *c, struct lxc_snapshot out_free: if (snaps) { - int i; - - for (i=0; i= len) - goto bad; + return NULL; - f = fopen(path, "r"); + f = fopen(path, "re"); if (!f) - goto bad; + return NULL; /* Feh - sb.st_size is always 4096. */ fseek(f, 0, SEEK_END); physlen = ftell(f); fseek(f, 0, SEEK_SET); - if (physlen < 0) { - fclose(f); - goto bad; - } + if (physlen < 0) + return NULL; physname = malloc(physlen + 1); - if (!physname) { - fclose(f); - goto bad; - } + if (!physname) + return NULL; memset(physname, 0, physlen + 1); ret = fread(physname, 1, physlen, f); - fclose(f); if (ret < 0) - goto bad; + return NULL; for (i = 0; i < physlen; i++) { if (physname[i] == '\n') @@ -1284,11 +1278,7 @@ char *is_wlan(const char *ifname) break; } - return physname; - -bad: - free(physname); - return NULL; + return move_ptr(physname); } static int lxc_netdev_rename_by_name_in_netns(pid_t pid, const char *old, diff --git a/src/lxc/pam/pam_cgfs.c b/src/lxc/pam/pam_cgfs.c index 1624ce160..0ea6b2406 100644 --- a/src/lxc/pam/pam_cgfs.c +++ b/src/lxc/pam/pam_cgfs.c @@ -486,8 +486,8 @@ static bool write_int(char *path, int v) /* Recursively remove directory and its parents. */ static int recursive_rmdir(char *dirname) { + __do_closedir DIR *dir = NULL; struct dirent *direntp; - DIR *dir; int r = 0; dir = opendir(dirname); @@ -527,12 +527,6 @@ next: r = -1; } - if (closedir(dir) < 0) { - if (!r) - pam_cgfs_debug("Failed to delete %s: %s\n", dirname, strerror(errno)); - r = -1; - } - return r; } diff --git a/src/lxc/parse.c b/src/lxc/parse.c index e6b0460f5..291bf3efc 100644 --- a/src/lxc/parse.c +++ b/src/lxc/parse.c @@ -141,12 +141,12 @@ on_error: int lxc_file_for_each_line(const char *file, lxc_file_cb callback, void *data) { - FILE *f; + __do_fclose FILE *f = NULL; + __do_free char *line = NULL; int err = 0; - char *line = NULL; size_t len = 0; - f = fopen(file, "r"); + f = fopen(file, "re"); if (!f) { SYSERROR("Failed to open \"%s\"", file); return -1; @@ -164,7 +164,5 @@ int lxc_file_for_each_line(const char *file, lxc_file_cb callback, void *data) } } - free(line); - fclose(f); return err; } diff --git a/src/lxc/seccomp.c b/src/lxc/seccomp.c index f1ed81384..0c56ec5ca 100644 --- a/src/lxc/seccomp.c +++ b/src/lxc/seccomp.c @@ -1133,16 +1133,16 @@ bad_line: */ static bool use_seccomp(const struct lxc_conf *conf) { + __do_free char *line = NULL; + __do_fclose FILE *f = NULL; int ret, v; - FILE *f; size_t line_bufsz = 0; - char *line = NULL; bool already_enabled = false, found = false; if (conf->seccomp.allow_nesting > 0) return true; - f = fopen("/proc/self/status", "r"); + f = fopen("/proc/self/status", "re"); if (!f) return true; @@ -1157,8 +1157,6 @@ static bool use_seccomp(const struct lxc_conf *conf) break; } } - free(line); - fclose(f); if (!found) { INFO("Seccomp is not enabled in the kernel"); @@ -1175,8 +1173,8 @@ static bool use_seccomp(const struct lxc_conf *conf) int lxc_read_seccomp_config(struct lxc_conf *conf) { + __do_fclose FILE *f = NULL; int ret; - FILE *f; if (!conf->seccomp.seccomp) return 0; @@ -1217,16 +1215,13 @@ int lxc_read_seccomp_config(struct lxc_conf *conf) } #endif - f = fopen(conf->seccomp.seccomp, "r"); + f = fopen(conf->seccomp.seccomp, "re"); if (!f) { SYSERROR("Failed to open seccomp policy file %s", conf->seccomp.seccomp); return -1; } - ret = parse_config(f, conf); - fclose(f); - - return ret; + return parse_config(f, conf); } int lxc_seccomp_load(struct lxc_conf *conf) diff --git a/src/lxc/utils.c b/src/lxc/utils.c index 8397d54ae..a3495635a 100644 --- a/src/lxc/utils.c +++ b/src/lxc/utils.c @@ -514,19 +514,17 @@ int lxc_pclose(struct lxc_popen_FILE *fp) int randseed(bool srand_it) { - FILE *f; + __do_fclose FILE *f = NULL; /* * srand pre-seed function based on /dev/urandom */ unsigned int seed = time(NULL) + getpid(); - f = fopen("/dev/urandom", "r"); + f = fopen("/dev/urandom", "re"); if (f) { int ret = fread(&seed, sizeof(seed), 1, f); if (ret != 1) SYSDEBUG("Unable to fread /dev/urandom, fallback to time+pid rand seed"); - - fclose(f); } if (srand_it) @@ -537,12 +535,12 @@ int randseed(bool srand_it) uid_t get_ns_uid(uid_t orig) { - char *line = NULL; + __do_free char *line = NULL; + __do_fclose FILE *f = NULL; size_t sz = 0; uid_t nsid, hostid, range; - FILE *f; - f = fopen("/proc/self/uid_map", "r"); + f = fopen("/proc/self/uid_map", "re"); if (!f) { SYSERROR("Failed to open uid_map"); return 0; @@ -552,28 +550,21 @@ uid_t get_ns_uid(uid_t orig) if (sscanf(line, "%u %u %u", &nsid, &hostid, &range) != 3) continue; - if (hostid <= orig && hostid + range > orig) { - nsid += orig - hostid; - goto found; - } + if (hostid <= orig && hostid + range > orig) + return nsid += orig - hostid; } - nsid = LXC_INVALID_UID; - -found: - fclose(f); - free(line); - return nsid; + return LXC_INVALID_UID; } gid_t get_ns_gid(gid_t orig) { - char *line = NULL; + __do_free char *line = NULL; + __do_fclose FILE *f = NULL; size_t sz = 0; gid_t nsid, hostid, range; - FILE *f; - f = fopen("/proc/self/gid_map", "r"); + f = fopen("/proc/self/gid_map", "re"); if (!f) { SYSERROR("Failed to open gid_map"); return 0; @@ -583,18 +574,11 @@ gid_t get_ns_gid(gid_t orig) if (sscanf(line, "%u %u %u", &nsid, &hostid, &range) != 3) continue; - if (hostid <= orig && hostid + range > orig) { - nsid += orig - hostid; - goto found; - } + if (hostid <= orig && hostid + range > orig) + return nsid += orig - hostid; } - nsid = LXC_INVALID_GID; - -found: - fclose(f); - free(line); - return nsid; + return LXC_INVALID_GID; } bool dir_exists(const char *path) @@ -640,7 +624,7 @@ bool is_shared_mountpoint(const char *path) int i; size_t len = 0; - f = fopen("/proc/self/mountinfo", "r"); + f = fopen("/proc/self/mountinfo", "re"); if (!f) return 0; @@ -722,19 +706,19 @@ bool switch_to_ns(pid_t pid, const char *ns) */ bool detect_ramfs_rootfs(void) { - FILE *f; - char *p, *p2; - char *line = NULL; + __do_free char *line = NULL; + __do_free void *fopen_cache = NULL; + __do_fclose FILE *f = NULL; size_t len = 0; - int i; - f = fopen("/proc/self/mountinfo", "r"); - if (!f) { - SYSERROR("Failed to open mountinfo"); + f = fopen_cached("/proc/self/mountinfo", "re", &fopen_cache); + if (!f) return false; - } while (getline(&line, &len, f) != -1) { + int i; + char *p, *p2; + for (p = line, i = 0; p && i < 4; i++) p = strchr(p + 1, ' '); if (!p) @@ -743,22 +727,15 @@ bool detect_ramfs_rootfs(void) p2 = strchr(p + 1, ' '); if (!p2) continue; - *p2 = '\0'; if (strcmp(p + 1, "/") == 0) { /* This is '/'. Is it the ramfs? */ p = strchr(p2 + 1, '-'); - if (p && strncmp(p, "- rootfs rootfs ", 16) == 0) { - free(line); - fclose(f); - INFO("Rootfs is located on ramfs"); + if (p && strncmp(p, "- rootfs rootfs ", 16) == 0) return true; - } } } - free(line); - fclose(f); return false; } @@ -1317,21 +1294,21 @@ int null_stdfds(void) #define __PROC_STATUS_LEN (6 + INTTYPE_TO_STRLEN(pid_t) + 7 + 1) bool task_blocks_signal(pid_t pid, int signal) { + __do_free char *line = NULL; + __do_fclose FILE *f = NULL; int ret; char status[__PROC_STATUS_LEN] = {0}; - FILE *f; uint64_t sigblk = 0, one = 1; size_t n = 0; bool bret = false; - char *line = NULL; ret = snprintf(status, __PROC_STATUS_LEN, "/proc/%d/status", pid); if (ret < 0 || ret >= __PROC_STATUS_LEN) return bret; - f = fopen(status, "r"); + f = fopen(status, "re"); if (!f) - return bret; + return false; while (getline(&line, &n, f) != -1) { char *numstr; @@ -1342,7 +1319,7 @@ bool task_blocks_signal(pid_t pid, int signal) numstr = lxc_trim_whitespace_in_place(line + 7); ret = lxc_safe_uint64(numstr, &sigblk, 16); if (ret < 0) - goto out; + return false; break; } @@ -1350,9 +1327,6 @@ bool task_blocks_signal(pid_t pid, int signal) if (sigblk & (one << (signal - 1))) bret = true; -out: - free(line); - fclose(f); return bret; } @@ -1723,10 +1697,11 @@ static int process_dead(/* takes */ int status_fd) if (fd_cloexec(dupfd, true) < 0) return -1; - /* transfer ownership of fd */ f = fdopen(dupfd, "re"); if (!f) return -1; + + /* Transfer ownership of fd. */ move_fd(dupfd); ret = 0; diff --git a/src/lxc/utils.h b/src/lxc/utils.h index 24d615de4..18476bb11 100644 --- a/src/lxc/utils.h +++ b/src/lxc/utils.h @@ -24,6 +24,7 @@ #include "file_utils.h" #include "initutils.h" #include "macro.h" +#include "memory_utils.h" #include "raw_syscalls.h" #include "string_utils.h" @@ -93,7 +94,7 @@ inline static bool am_guest_unpriv(void) { /* are we unprivileged with respect to init_user_ns */ inline static bool am_host_unpriv(void) { - FILE *f; + __do_fclose FILE *f = NULL; uid_t user, host, count; int ret; @@ -103,20 +104,15 @@ inline static bool am_host_unpriv(void) /* Now: are we in a user namespace? Because then we're also * unprivileged. */ - f = fopen("/proc/self/uid_map", "r"); - if (!f) { + f = fopen("/proc/self/uid_map", "re"); + if (!f) return false; - } ret = fscanf(f, "%u %u %u", &user, &host, &count); - fclose(f); - if (ret != 3) { + if (ret != 3) return false; - } - if (user != 0 || host != 0 || count != UINT32_MAX) - return true; - return false; + return user != 0 || host != 0 || count != UINT32_MAX; } /*