|
|
15c49f |
From db1f27c0350e9e437c93780ffe88648ae1984467 Mon Sep 17 00:00:00 2001
|
|
|
15c49f |
From: "Todd C. Miller" <Todd.Miller@sudo.ws>
|
|
|
15c49f |
Date: Wed, 6 Jan 2021 10:16:00 -0700
|
|
|
15c49f |
Subject: [PATCH] Fix potential directory existing info leak in sudoedit. When
|
|
|
15c49f |
creating a new file, sudoedit checks to make sure the parent directory exists
|
|
|
15c49f |
so it can provide the user with a sensible error message. However, this
|
|
|
15c49f |
could be used to test for the existence of directories not normally
|
|
|
15c49f |
accessible to the user by pointing to them with a symbolic link when the
|
|
|
15c49f |
parent directory is controlled by the user. Problem reported by Matthias
|
|
|
15c49f |
Gerstner of SUSE.
|
|
|
15c49f |
|
|
|
15c49f |
---
|
|
|
15c49f |
src/sudo_edit.c | 29 ++++++++++++++++++++++++-----
|
|
|
15c49f |
1 file changed, 24 insertions(+), 5 deletions(-)
|
|
|
15c49f |
|
|
|
15c49f |
diff --git a/src/sudo_edit.c b/src/sudo_edit.c
|
|
|
15c49f |
index 82e04a71b..5502b7bd9 100644
|
|
|
15c49f |
--- a/src/sudo_edit.c
|
|
|
15c49f |
+++ b/src/sudo_edit.c
|
|
|
15c49f |
@@ -541,14 +541,33 @@ sudo_edit_create_tfiles(struct command_details *command_details,
|
|
|
15c49f |
S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, command_details);
|
|
|
15c49f |
if (ofd != -1 || errno == ENOENT) {
|
|
|
15c49f |
if (ofd == -1) {
|
|
|
15c49f |
- /* New file, verify parent dir exists unless in cwd. */
|
|
|
15c49f |
+ /*
|
|
|
15c49f |
+ * New file, verify parent dir exists unless in cwd.
|
|
|
15c49f |
+ * This fails early so the user knows ahead of time if the
|
|
|
15c49f |
+ * edit won't succeed. Additional checks are performed
|
|
|
15c49f |
+ * when copying the temporary file back to the origin.
|
|
|
15c49f |
+ */
|
|
|
15c49f |
char *slash = strrchr(files[i], '/');
|
|
|
15c49f |
if (slash != NULL && slash != files[i]) {
|
|
|
15c49f |
- int serrno = errno;
|
|
|
15c49f |
+ const int sflags = command_details->flags;
|
|
|
15c49f |
+ const int serrno = errno;
|
|
|
15c49f |
+ int dfd;
|
|
|
15c49f |
+
|
|
|
15c49f |
+ /*
|
|
|
15c49f |
+ * The parent directory is allowed to be a symbolic
|
|
|
15c49f |
+ * link as long as *its* parent is not writable.
|
|
|
15c49f |
+ */
|
|
|
15c49f |
*slash = '\0';
|
|
|
15c49f |
- if (stat(files[i], &sb) == 0 && S_ISDIR(sb.st_mode)) {
|
|
|
15c49f |
- memset(&sb, 0, sizeof(sb));
|
|
|
15c49f |
- rc = 0;
|
|
|
15c49f |
+ SET(command_details->flags, CD_SUDOEDIT_FOLLOW);
|
|
|
15c49f |
+ dfd = sudo_edit_open(files[i], DIR_OPEN_FLAGS,
|
|
|
15c49f |
+ S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, command_details);
|
|
|
15c49f |
+ command_details->flags = sflags;
|
|
|
15c49f |
+ if (dfd != -1) {
|
|
|
15c49f |
+ if (fstat(dfd, &sb) == 0 && S_ISDIR(sb.st_mode)) {
|
|
|
15c49f |
+ memset(&sb, 0, sizeof(sb));
|
|
|
15c49f |
+ rc = 0;
|
|
|
15c49f |
+ }
|
|
|
15c49f |
+ close(dfd);
|
|
|
15c49f |
}
|
|
|
15c49f |
*slash = '/';
|
|
|
15c49f |
errno = serrno;
|
|
|
15c49f |
--
|
|
|
15c49f |
2.26.2
|
|
|
15c49f |
|