Download raw body.
close-on-exec
We recently disabled closefrom() return value checks because closefrom() returns void on some non-OpenBSD platforms. During discussion of this change, millert@ suggested use of the close-on-exec flag to avoid leaking open files into a child process without a need for closefrom(). This patch adds the "e" flag to all fopen() calls, and the O_CLOEXEC flag to all open() and openat() calls. Is this sufficient or do we need to cover any other variants of fopen() and/or open()? Do all of the various C libraries in use on Linux systems support the close-on-exec flag? The linux kernel supports O_CLOEXEC since 2.6.23, glibc supports the fopen "e" flag since 2.7. I have not checked other libc, and I do not even know which libc are important to people running got-portable. Our use of closefrom() could now be deleted but we would then need to use close-on-exec consistently in new code. I would rather keep both mechanisms in place, such that closefrom() acts as a safety net which should close any file descriptors that were accidentally not marked close-on-exec. These changes affect the main process only since none of the libexec helpers are able to open files. All files used by libexec helpers are passed from the main process via imsg. Regression tests are still passing on OpenBSD. ok? diff refs/heads/main refs/heads/close-on-exec blob - 9e4617d2d22bb0cc089b03f64f1d2bca3d19ab51 blob + 0b61ca99747d4d1bde47a50eecd572ce88c838f8 --- got/got.c +++ got/got.c @@ -504,7 +504,7 @@ edit_logmsg(char **logmsg, const char *editor, const c return got_error_from_errno("malloc"); (*logmsg)[0] = '\0'; - fp = fopen(logmsg_path, "r"); + fp = fopen(logmsg_path, "re"); if (fp == NULL) { err = got_error_from_errno("fopen"); goto done; @@ -1236,7 +1236,7 @@ create_gotconfig(const char *proto, const char *host, err = got_error_from_errno("got_repo_get_path_gotconfig"); goto done; } - gotconfig_file = fopen(gotconfig_path, "a"); + gotconfig_file = fopen(gotconfig_path, "ae"); if (gotconfig_file == NULL) { err = got_error_from_errno2("fopen", gotconfig_path); goto done; @@ -1296,7 +1296,7 @@ create_gitconfig(const char *git_url, const char *defa err = got_error_from_errno("got_repo_get_path_gitconfig"); goto done; } - gitconfig_file = fopen(gitconfig_path, "a"); + gitconfig_file = fopen(gitconfig_path, "ae"); if (gitconfig_file == NULL) { err = got_error_from_errno2("fopen", gitconfig_path); goto done; @@ -4435,7 +4435,8 @@ print_diff(void *arg, unsigned char status, unsigned c } if (dirfd != -1) { - fd = openat(dirfd, de_name, O_RDONLY | O_NOFOLLOW); + fd = openat(dirfd, de_name, + O_RDONLY | O_NOFOLLOW | O_CLOEXEC); if (fd == -1) { if (!got_err_open_nofollow_on_symlink()) { err = got_error_from_errno2("openat", @@ -4448,7 +4449,7 @@ print_diff(void *arg, unsigned char status, unsigned c goto done; } } else { - fd = open(abspath, O_RDONLY | O_NOFOLLOW); + fd = open(abspath, O_RDONLY | O_NOFOLLOW | O_CLOEXEC); if (fd == -1) { if (!got_err_open_nofollow_on_symlink()) { err = got_error_from_errno2("open", @@ -7296,7 +7297,7 @@ cmd_revert(int argc, char *argv[]) goto done; if (patch_script_path) { - patch_script_file = fopen(patch_script_path, "r"); + patch_script_file = fopen(patch_script_path, "re"); if (patch_script_file == NULL) { error = got_error_from_errno2("fopen", patch_script_path); @@ -7392,7 +7393,7 @@ read_prepared_logmsg(char **logmsg, const char *path) *logmsg = NULL; memset(&sb, 0, sizeof(sb)); - f = fopen(path, "r"); + f = fopen(path, "re"); if (f == NULL) return got_error_from_errno2("fopen", path); @@ -9824,7 +9825,7 @@ histedit_run_editor(struct got_histedit_list *histedit goto done; } - f = fopen(path, "r"); + f = fopen(path, "re"); if (f == NULL) { err = got_error_from_errno("fopen"); goto done; @@ -9910,7 +9911,7 @@ histedit_save_list(struct got_histedit_list *histedit_ if (err) return err; - f = fopen(path, "w"); + f = fopen(path, "we"); if (f == NULL) { err = got_error_from_errno2("fopen", path); goto done; @@ -9957,7 +9958,7 @@ histedit_load_list(struct got_histedit_list *histedit_ const struct got_error *err = NULL; FILE *f = NULL; - f = fopen(path, "r"); + f = fopen(path, "re"); if (f == NULL) { err = got_error_from_errno2("fopen", path); goto done; @@ -11241,7 +11242,7 @@ cmd_stage(int argc, char *argv[]) goto done; if (patch_script_path) { - patch_script_file = fopen(patch_script_path, "r"); + patch_script_file = fopen(patch_script_path, "re"); if (patch_script_file == NULL) { error = got_error_from_errno2("fopen", patch_script_path); @@ -11361,7 +11362,7 @@ cmd_unstage(int argc, char *argv[]) goto done; if (patch_script_path) { - patch_script_file = fopen(patch_script_path, "r"); + patch_script_file = fopen(patch_script_path, "re"); if (patch_script_file == NULL) { error = got_error_from_errno2("fopen", patch_script_path); blob - eeaf4cbd73e78bea7a719194a8223f1826901821 blob + 6363042469cbd22c9740556448d1cc20c5eafdab --- gotweb/gotweb.c +++ gotweb/gotweb.c @@ -2670,7 +2670,7 @@ gw_get_repo_description(char **description, struct gw_ if (asprintf(&d_file, "%s/description", dir) == -1) return got_error_from_errno("asprintf"); - f = fopen(d_file, "r"); + f = fopen(d_file, "re"); if (f == NULL) { if (errno == ENOENT || errno == EACCES) return NULL; @@ -2973,7 +2973,7 @@ gw_get_clone_url(char **url, struct gw_trans *gw_trans if (asprintf(&d_file, "%s/cloneurl", dir) == -1) return got_error_from_errno("asprintf"); - f = fopen(d_file, "r"); + f = fopen(d_file, "re"); if (f == NULL) { if (errno != ENOENT && errno != EACCES) error = got_error_from_errno2("fopen", d_file); blob - 1d91c1f05c748a155769cbfd96cb8871ffd0c8cc blob + dac1eae40679c47137747bc4f1d9aa0f054e8f59 --- gotweb/parse.y +++ gotweb/parse.y @@ -503,7 +503,7 @@ pushfile(struct file **nfile, const char *name) free(nfile); return got_error_from_errno2(__func__, "strdup"); } - if (((*nfile)->stream = fopen((*nfile)->name, "r")) == NULL) { + if (((*nfile)->stream = fopen((*nfile)->name, "re")) == NULL) { char *msg = NULL; if (asprintf(&msg, "%s", (*nfile)->name) == -1) return got_error_from_errno("asprintf"); blob - f17dddcabf8aa19fd01c17dec68dc1a8ec2dd748 blob + 05d16ce90ea867ddc912cd1321d68b0262228307 --- lib/buf.c +++ lib/buf.c @@ -280,7 +280,7 @@ buf_write(BUF *b, const char *path, mode_t mode) const struct got_error *err = NULL; int fd; open: - if ((fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, mode)) == -1) { + if ((fd = open(path, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, mode)) == -1) { err = got_error_from_errno2("open", path); if (errno == EACCES && unlink(path) != -1) goto open; blob - 95fdb0726bce1615a82c90e53763702fa49bc139 blob + ec933af31517a8e95d2772b7199c7efcb9064c82 --- lib/diff3.c +++ lib/diff3.c @@ -207,12 +207,12 @@ diffreg(BUF **d, const char *path1, const char *path2, *d = NULL; - f1 = fopen(path1, "r"); + f1 = fopen(path1, "re"); if (f1 == NULL) { err = got_error_from_errno2("fopen", path1); goto done; } - f2 = fopen(path2, "r"); + f2 = fopen(path2, "re"); if (f1 == NULL) { err = got_error_from_errno2("fopen", path2); goto done; @@ -460,11 +460,11 @@ diff3_internal(char *dp13, char *dp23, char *path1, ch if (err) return err; - if ((d3s->fp[0] = fopen(path1, "r")) == NULL) + if ((d3s->fp[0] = fopen(path1, "re")) == NULL) return got_error_from_errno2("fopen", path1); - if ((d3s->fp[1] = fopen(path2, "r")) == NULL) + if ((d3s->fp[1] = fopen(path2, "re")) == NULL) return got_error_from_errno2("fopen", path2); - if ((d3s->fp[2] = fopen(path3, "r")) == NULL) + if ((d3s->fp[2] = fopen(path3, "re")) == NULL) return got_error_from_errno2("fopen", path3); return merge(m, n, d3s); @@ -604,7 +604,7 @@ readin(size_t *n, char *name, struct diff **dd, struct *n = 0; - f = fopen(name, "r"); + f = fopen(name, "re"); if (f == NULL) return got_error_from_errno2("fopen", name); err = getchange(&p, f, d3s); blob - 91a35e46fce2547ae0c44ba7edf82da9edd9e097 blob + 60539f2a09b85e1abbc55e1e6fb94f7210db3b14 --- lib/fileindex.c +++ lib/fileindex.c @@ -1059,7 +1059,7 @@ walk_dir(struct got_pathlist_entry **next, struct got_ } subdirfd = openat(fd, de->d_name, - O_RDONLY | O_NOFOLLOW | O_DIRECTORY); + O_RDONLY | O_NOFOLLOW | O_DIRECTORY | O_CLOEXEC); if (subdirfd == -1) { if (errno == EACCES) { *next = TAILQ_NEXT(dle, entry); blob - 7133ec58bdbaf535f13ad65c71428d7eb891a975 blob + 664f170821f75b4356a1f141c1aebcf860ac1868 --- lib/gotconfig.c +++ lib/gotconfig.c @@ -51,7 +51,7 @@ got_gotconfig_read(struct got_gotconfig **conf, const if (*conf == NULL) return got_error_from_errno("calloc"); - fd = open(gotconfig_path, O_RDONLY); + fd = open(gotconfig_path, O_RDONLY | O_CLOEXEC); if (fd == -1) { if (errno == ENOENT) return NULL; blob - 846038c091fec21e8c028ab14a6fcdb0ea52c913 blob + e1a1870147bfefcb7e3caaaedf16d6b92e78a5c1 --- lib/lockfile.c +++ lib/lockfile.c @@ -55,11 +55,11 @@ got_lockfile_lock(struct got_lockfile **lf, const char do { if (dir_fd != -1) { (*lf)->fd = openat(dir_fd, (*lf)->path, - O_RDONLY | O_CREAT | O_EXCL | O_EXLOCK, + O_RDONLY | O_CREAT | O_EXCL | O_EXLOCK | O_CLOEXEC, GOT_DEFAULT_FILE_MODE); } else { (*lf)->fd = open((*lf)->path, - O_RDONLY | O_CREAT | O_EXCL | O_EXLOCK, + O_RDONLY | O_CREAT | O_EXCL | O_EXLOCK | O_CLOEXEC, GOT_DEFAULT_FILE_MODE); } if ((*lf)->fd != -1) blob - 5cfc0aee3892c25a4378b608302c31ca629fcabd blob + a4cf395476aee75f57a0281a2184b91a09e360e3 --- lib/object.c +++ lib/object.c @@ -136,7 +136,7 @@ got_object_open_loose_fd(int *fd, struct got_object_id err = got_object_get_path(&path, id, repo); if (err) return err; - *fd = open(path, O_RDONLY | O_NOFOLLOW); + *fd = open(path, O_RDONLY | O_NOFOLLOW | O_CLOEXEC); if (*fd == -1) { err = got_error_from_errno2("open", path); goto done; blob - 1092bb03e5e276167684b61088c369b208953167 blob + 687f6f051b8fd962cbc58e0415b5cd3d2d385fcf --- lib/object_create.c +++ lib/object_create.c @@ -127,7 +127,7 @@ got_object_blob_file_create(struct got_object_id **id, SHA1Init(&sha1_ctx); - fd = open(ondisk_path, O_RDONLY | O_NOFOLLOW); + fd = open(ondisk_path, O_RDONLY | O_NOFOLLOW | O_CLOEXEC); if (fd == -1) { if (!got_err_open_nofollow_on_symlink()) return got_error_from_errno2("open", ondisk_path); blob - b29f6d25ce45802ebffcccce90ca9975efdbf260 blob + cda2a94c06d5421f629332f0997eca5ce2c66c5c --- lib/pack.c +++ lib/pack.c @@ -368,7 +368,7 @@ got_packidx_open(struct got_packidx **packidx, goto done; } - p->fd = openat(dir_fd, relpath, O_RDONLY | O_NOFOLLOW); + p->fd = openat(dir_fd, relpath, O_RDONLY | O_NOFOLLOW | O_CLOEXEC); if (p->fd == -1) { err = got_error_from_errno2("openat", relpath); free(p); blob - d94d085c6a81b1232aacfe54421d5ffa740b8393 blob + a00402e5edffaefb92ba18770b49fc07c8826c58 --- lib/path.c +++ lib/path.c @@ -500,7 +500,7 @@ got_path_create_file(const char *path, const char *con const struct got_error *err = NULL; int fd = -1; - fd = open(path, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, + fd = open(path, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW | O_CLOEXEC, GOT_DEFAULT_FILE_MODE); if (fd == -1) { err = got_error_from_errno2("open", path); blob - eff4b9a3e9d57466366fd04d73b1eeb8d92bd371 blob + b7336cfa9779d26b5bc510b4bb45c1f5f64df5c1 --- lib/reference.c +++ lib/reference.c @@ -189,7 +189,7 @@ parse_ref_file(struct got_reference **ref, const char } } - f = fopen(abspath, "rb"); + f = fopen(abspath, "rbe"); if (f == NULL) { if (errno != ENOTDIR && errno != ENOENT) err = got_error_from_errno2("fopen", abspath); @@ -495,7 +495,7 @@ got_ref_open(struct got_reference **ref, struct got_re if (err) goto done; } - f = fopen(packed_refs_path, "rb"); + f = fopen(packed_refs_path, "rbe"); free(packed_refs_path); if (f != NULL) { struct stat sb; @@ -1088,7 +1088,7 @@ got_ref_list(struct got_reflist_head *refs, struct got goto done; } - f = fopen(packed_refs_path, "r"); + f = fopen(packed_refs_path, "re"); free(packed_refs_path); if (f) { size_t linesize = 0; @@ -1342,7 +1342,7 @@ delete_packed_ref(struct got_reference *delref, struct goto done; } - f = fopen(packed_refs_path, "r"); + f = fopen(packed_refs_path, "re"); if (f == NULL) { err = got_error_from_errno2("fopen", packed_refs_path); goto done; blob - 3c4b83d77f6d8a35b74a2aeaffe36f60f8f0a7c3 blob + 41da7b15ca61d79a06862f1f0a9534002c2cdfca --- lib/repository.c +++ lib/repository.c @@ -391,7 +391,8 @@ open_repo(struct got_repository *repo, const char *pat err = got_error_from_errno("strdup"); goto done; } - repo->gitdir_fd = open(repo->path_git_dir, O_DIRECTORY); + repo->gitdir_fd = open(repo->path_git_dir, + O_DIRECTORY | O_CLOEXEC); if (repo->gitdir_fd == -1) { err = got_error_from_errno2("open", repo->path_git_dir); @@ -413,7 +414,8 @@ open_repo(struct got_repository *repo, const char *pat err = got_error_from_errno("strdup"); goto done; } - repo->gitdir_fd = open(repo->path_git_dir, O_DIRECTORY); + repo->gitdir_fd = open(repo->path_git_dir, + O_DIRECTORY | O_CLOEXEC); if (repo->gitdir_fd == -1) { err = got_error_from_errno2("open", repo->path_git_dir); @@ -464,7 +466,7 @@ parse_gitconfig_file(int *gitconfig_repository_format_ if (gitconfig_owner) *gitconfig_owner = NULL; - fd = open(gitconfig_path, O_RDONLY); + fd = open(gitconfig_path, O_RDONLY | O_CLOEXEC); if (fd == -1) { if (errno == ENOENT) return NULL; @@ -1123,7 +1125,7 @@ got_repo_search_packidx(struct got_packidx **packidx, /* No luck. Search the filesystem. */ packdir_fd = openat(got_repo_get_fd(repo), - GOT_OBJECTS_PACK_DIR, O_DIRECTORY); + GOT_OBJECTS_PACK_DIR, O_DIRECTORY | O_CLOEXEC); if (packdir_fd == -1) { if (errno == ENOENT) err = got_error_no_obj(id); @@ -1231,7 +1233,8 @@ open_packfile(int *fd, struct got_repository *repo, { const struct got_error *err = NULL; - *fd = openat(got_repo_get_fd(repo), relpath, O_RDONLY | O_NOFOLLOW); + *fd = openat(got_repo_get_fd(repo), relpath, + O_RDONLY | O_NOFOLLOW | O_CLOEXEC); if (*fd == -1) return got_error_from_errno_fmt("openat: %s/%s", got_repo_get_path_git_dir(repo), relpath); @@ -1405,7 +1408,7 @@ match_packed_object(struct got_object_id **unique_id, STAILQ_INIT(&matched_ids); packdir_fd = openat(got_repo_get_fd(repo), - GOT_OBJECTS_PACK_DIR, O_DIRECTORY); + GOT_OBJECTS_PACK_DIR, O_DIRECTORY | O_CLOEXEC); if (packdir_fd == -1) { if (errno != ENOENT) err = got_error_from_errno2("openat", GOT_OBJECTS_PACK_DIR); blob - d7d0ab9f80f5bc272b6a81a901c3647364c3e962 blob + 4e1253bcafe34044a40c52250b6a96a552b4b609 --- lib/repository_admin.c +++ lib/repository_admin.c @@ -483,7 +483,7 @@ got_repo_find_pack(FILE **packfile, struct got_object_ goto done; } - packfd = open(packfile_path, O_RDONLY | O_NOFOLLOW); + packfd = open(packfile_path, O_RDONLY | O_NOFOLLOW | O_CLOEXEC); if (packfd == -1) { err = got_error_from_errno2("open", packfile_path); goto done; @@ -1215,7 +1215,7 @@ got_repo_remove_lonely_packidx(struct got_repository * struct stat sb; packdir_fd = openat(got_repo_get_fd(repo), - GOT_OBJECTS_PACK_DIR, O_DIRECTORY); + GOT_OBJECTS_PACK_DIR, O_DIRECTORY | O_CLOEXEC); if (packdir_fd == -1) { if (errno == ENOENT) return NULL; blob - 08a1d596cc47c30cfb0e5dd2c6118178530bdd72 blob + 87959af131f11571b21d37fe9087acd551dd9250 --- lib/worktree.c +++ lib/worktree.c @@ -1044,7 +1044,7 @@ merge_blob(int *local_changes_subsumed, struct got_wor goto done; } else { int fd; - fd = open(ondisk_path, O_RDONLY | O_NOFOLLOW); + fd = open(ondisk_path, O_RDONLY | O_NOFOLLOW | O_CLOEXEC); if (fd == -1) { err = got_error_from_errno2("open", ondisk_path); goto done; @@ -1159,7 +1159,7 @@ replace_existing_symlink(int *did_something, const cha * caller. If we can successfully open a regular file then we simply * replace this file with a symlink below. */ - fd = open(ondisk_path, O_RDWR | O_EXCL | O_NOFOLLOW); + fd = open(ondisk_path, O_RDWR | O_EXCL | O_NOFOLLOW | O_CLOEXEC); if (fd == -1) { if (!got_err_open_nofollow_on_symlink()) return got_error_from_errno2("open", ondisk_path); @@ -1389,8 +1389,8 @@ install_blob(struct got_worktree *worktree, const char int update = 0; char *tmppath = NULL; - fd = open(ondisk_path, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, - GOT_DEFAULT_FILE_MODE); + fd = open(ondisk_path, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW | + O_CLOEXEC, GOT_DEFAULT_FILE_MODE); if (fd == -1) { if (errno == ENOENT) { char *parent; @@ -1402,7 +1402,7 @@ install_blob(struct got_worktree *worktree, const char if (err) return err; fd = open(ondisk_path, - O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, + O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW | O_CLOEXEC, GOT_DEFAULT_FILE_MODE); if (fd == -1) return got_error_from_errno2("open", @@ -1657,7 +1657,7 @@ get_file_status(unsigned char *status, struct stat *sb goto done; } } else { - fd = open(abspath, O_RDONLY | O_NOFOLLOW); + fd = open(abspath, O_RDONLY | O_NOFOLLOW | O_CLOEXEC); if (fd == -1 && errno != ENOENT && !got_err_open_nofollow_on_symlink()) return got_error_from_errno2("open", abspath); @@ -1717,7 +1717,7 @@ get_file_status(unsigned char *status, struct stat *sb } if (dirfd != -1) { - fd = openat(dirfd, de_name, O_RDONLY | O_NOFOLLOW); + fd = openat(dirfd, de_name, O_RDONLY | O_NOFOLLOW | O_CLOEXEC); if (fd == -1) { err = got_error_from_errno2("openat", abspath); goto done; @@ -2342,7 +2342,7 @@ open_fileindex(struct got_fileindex **fileindex, char if (err) goto done; - index = fopen(*fileindex_path, "rb"); + index = fopen(*fileindex_path, "rbe"); if (index == NULL) { if (errno != ENOENT) err = got_error_from_errno2("fopen", *fileindex_path); @@ -2816,7 +2816,7 @@ merge_file_cb(void *arg, struct got_blob_object *blob1 if (err) goto done; - fd = open(ondisk_path, O_RDONLY | O_NOFOLLOW); + fd = open(ondisk_path, O_RDONLY | O_NOFOLLOW | O_CLOEXEC); if (fd == -1) { err = got_error_from_errno2("open", ondisk_path); @@ -3460,7 +3460,8 @@ add_ignores(struct got_pathlist_head *ignores, const c return got_error_from_errno("asprintf"); if (dirfd != -1) { - fd = openat(dirfd, ignores_filename, O_RDONLY | O_NOFOLLOW); + fd = openat(dirfd, ignores_filename, + O_RDONLY | O_NOFOLLOW | O_CLOEXEC); if (fd == -1) { if (errno != ENOENT && errno != EACCES) err = got_error_from_errno2("openat", @@ -3476,7 +3477,7 @@ add_ignores(struct got_pathlist_head *ignores, const c } } } else { - ignoresfile = fopen(ignorespath, "r"); + ignoresfile = fopen(ignorespath, "re"); if (ignoresfile == NULL) { if (errno != ENOENT && errno != EACCES) err = got_error_from_errno2("fopen", @@ -3649,7 +3650,7 @@ worktree_status(struct got_worktree *worktree, const c worktree->root_path, path[0] ? "/" : "", path) == -1) return got_error_from_errno("asprintf"); - fd = open(ondisk_path, O_RDONLY | O_NOFOLLOW | O_DIRECTORY); + fd = open(ondisk_path, O_RDONLY | O_NOFOLLOW | O_DIRECTORY | O_CLOEXEC); if (fd == -1) { if (errno != ENOTDIR && errno != ENOENT && errno != EACCES && !got_err_open_nofollow_on_symlink()) @@ -4356,7 +4357,8 @@ create_patched_content(char **path_outfile, int revers return err; if (dirfd2 != -1) { - fd2 = openat(dirfd2, de_name2, O_RDONLY | O_NOFOLLOW); + fd2 = openat(dirfd2, de_name2, + O_RDONLY | O_NOFOLLOW | O_CLOEXEC); if (fd2 == -1) { if (!got_err_open_nofollow_on_symlink()) { err = got_error_from_errno2("openat", path2); @@ -4370,7 +4372,7 @@ create_patched_content(char **path_outfile, int revers sb2.st_size = link_len; } } else { - fd2 = open(path2, O_RDONLY | O_NOFOLLOW); + fd2 = open(path2, O_RDONLY | O_NOFOLLOW | O_CLOEXEC); if (fd2 == -1) { if (!got_err_open_nofollow_on_symlink()) { err = got_error_from_errno2("open", path2); @@ -8286,7 +8288,7 @@ unstage_hunks(struct got_object_id *staged_blob_id, goto done; } - f = fopen(path_unstaged_content, "r"); + f = fopen(path_unstaged_content, "re"); if (f == NULL) { err = got_error_from_errno2("fopen", path_unstaged_content); @@ -8347,7 +8349,8 @@ unstage_hunks(struct got_object_id *staged_blob_id, goto done; } else { int fd; - fd = open(ondisk_path, O_RDONLY | O_NOFOLLOW); + fd = open(ondisk_path, + O_RDONLY | O_NOFOLLOW | O_CLOEXEC); if (fd == -1) { err = got_error_from_errno2("open", ondisk_path); goto done; blob - 4a589cf5ece62d780a9e4fac1215b2df6a5ea5cc blob + 965700c2ad7edf85000a045f92b3727fc9ebc460 --- lib/worktree_open.c +++ lib/worktree_open.c @@ -56,7 +56,7 @@ read_meta_file(char **content, const char *path_got, c goto done; } - fd = open(path, O_RDONLY | O_NOFOLLOW); + fd = open(path, O_RDONLY | O_NOFOLLOW | O_CLOEXEC); if (fd == -1) { if (errno == ENOENT) err = got_error_path(path, GOT_ERR_WORKTREE_META); @@ -131,7 +131,7 @@ open_worktree(struct got_worktree **worktree, const ch goto done; } - fd = open(path_lock, O_RDWR | O_EXLOCK | O_NONBLOCK); + fd = open(path_lock, O_RDWR | O_EXLOCK | O_NONBLOCK | O_CLOEXEC); if (fd == -1) { err = (errno == EWOULDBLOCK ? got_error(GOT_ERR_WORKTREE_BUSY) : got_error_from_errno2("open", path_lock)); @@ -213,7 +213,8 @@ open_worktree(struct got_worktree **worktree, const ch err = got_gotconfig_read(&(*worktree)->gotconfig, (*worktree)->gotconfig_path); - (*worktree)->root_fd = open((*worktree)->root_path, O_DIRECTORY); + (*worktree)->root_fd = open((*worktree)->root_path, + O_DIRECTORY | O_CLOEXEC); if ((*worktree)->root_fd == -1) { err = got_error_from_errno2("open", (*worktree)->root_path); goto done;
close-on-exec