Commit 8bd0cdad05519cbb08d8d11223bdde0472678150

Stefan Sperling 2021-12-31T09:11:21

add O_CLOEXEC (close-on-exec) flag to open(2) calls suggested by millert ok thomas_adam

diff --git a/got/got.c b/got/got.c
index 3ed755a..49c56bc 100644
--- a/got/got.c
+++ b/got/got.c
@@ -4448,7 +4448,7 @@ print_diff(void *arg, unsigned char status, unsigned char staged_status,
 					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",
diff --git a/lib/buf.c b/lib/buf.c
index f17dddc..05d16ce 100644
--- a/lib/buf.c
+++ b/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;
diff --git a/lib/gotconfig.c b/lib/gotconfig.c
index 7133ec5..664f170 100644
--- a/lib/gotconfig.c
+++ b/lib/gotconfig.c
@@ -51,7 +51,7 @@ got_gotconfig_read(struct got_gotconfig **conf, const char *gotconfig_path)
 	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;
diff --git a/lib/lockfile.c b/lib/lockfile.c
index 846038c..7d5db03 100644
--- a/lib/lockfile.c
+++ b/lib/lockfile.c
@@ -59,7 +59,7 @@ got_lockfile_lock(struct got_lockfile **lf, const char *path, int dir_fd)
 			    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)
diff --git a/lib/object.c b/lib/object.c
index 5cfc0ae..a4cf395 100644
--- a/lib/object.c
+++ b/lib/object.c
@@ -136,7 +136,7 @@ got_object_open_loose_fd(int *fd, struct got_object_id *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;
diff --git a/lib/object_create.c b/lib/object_create.c
index 0053470..e5e4c44 100644
--- a/lib/object_create.c
+++ b/lib/object_create.c
@@ -127,7 +127,7 @@ got_object_blob_file_create(struct got_object_id **id, FILE **blobfile,
 
 	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);
diff --git a/lib/path.c b/lib/path.c
index d94d085..a00402e 100644
--- a/lib/path.c
+++ b/lib/path.c
@@ -500,7 +500,7 @@ got_path_create_file(const char *path, const char *content)
 	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);
diff --git a/lib/repository.c b/lib/repository.c
index 3c4b83d..76be29a 100644
--- a/lib/repository.c
+++ b/lib/repository.c
@@ -391,7 +391,8 @@ open_repo(struct got_repository *repo, const char *path)
 			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 *path)
 			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_version,
 	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;
diff --git a/lib/repository_admin.c b/lib/repository_admin.c
index d7d0ab9..3eb6c06 100644
--- a/lib/repository_admin.c
+++ b/lib/repository_admin.c
@@ -483,7 +483,7 @@ got_repo_find_pack(FILE **packfile, struct got_object_id **pack_hash,
 		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;
diff --git a/lib/worktree.c b/lib/worktree.c
index 5cb71cf..213daba 100644
--- a/lib/worktree.c
+++ b/lib/worktree.c
@@ -1044,7 +1044,7 @@ merge_blob(int *local_changes_subsumed, struct got_worktree *worktree,
 			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 char *ondisk_path,
 	 * 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 *ondisk_path,
 	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 *ondisk_path,
 			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);
@@ -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);
@@ -3649,7 +3649,7 @@ worktree_status(struct got_worktree *worktree, const char *path,
 	    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())
@@ -4370,7 +4370,7 @@ create_patched_content(char **path_outfile, int reverse_patch,
 			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);
@@ -8347,7 +8347,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;
diff --git a/lib/worktree_open.c b/lib/worktree_open.c
index 4a589cf..965700c 100644
--- a/lib/worktree_open.c
+++ b/lib/worktree_open.c
@@ -56,7 +56,7 @@ read_meta_file(char **content, const char *path_got, const char *name)
 		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 char *path)
 		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 char *path)
 	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;