|
| 1 | +From 031bb5a5d0d950253b68138b498dc93be69a64cb Mon Sep 17 00:00:00 2001 |
| 2 | +From: Matthias Gerstner <matthias.gerstner@suse.de> |
| 3 | +Date: Wed, 27 Dec 2023 14:01:59 +0100 |
| 4 | +Subject: [PATCH] pam_namespace: protect_dir(): use O_DIRECTORY to prevent |
| 5 | + local DoS situations |
| 6 | + |
| 7 | +Without O_DIRECTORY the path crawling logic is subject to e.g. FIFOs |
| 8 | +being placed in user controlled directories, causing the PAM module to |
| 9 | +block indefinitely during `openat()`. |
| 10 | + |
| 11 | +Pass O_DIRECTORY to cause the `openat()` to fail if the path does not |
| 12 | +refer to a directory. |
| 13 | + |
| 14 | +With this the check whether the final path element is a directory |
| 15 | +becomes unnecessary, drop it. |
| 16 | +--- |
| 17 | + modules/pam_namespace/pam_namespace.c | 18 +----------------- |
| 18 | + 1 file changed, 1 insertion(+), 17 deletions(-) |
| 19 | + |
| 20 | +diff --git a/modules/pam_namespace/pam_namespace.c b/modules/pam_namespace/pam_namespace.c |
| 21 | +index 2528cff86..f72d67189 100644 |
| 22 | +--- a/modules/pam_namespace/pam_namespace.c |
| 23 | ++++ b/modules/pam_namespace/pam_namespace.c |
| 24 | +@@ -1201,7 +1201,7 @@ static int protect_dir(const char *path, mode_t mode, int do_mkdir, |
| 25 | + int dfd = AT_FDCWD; |
| 26 | + int dfd_next; |
| 27 | + int save_errno; |
| 28 | +- int flags = O_RDONLY; |
| 29 | ++ int flags = O_RDONLY | O_DIRECTORY; |
| 30 | + int rv = -1; |
| 31 | + struct stat st; |
| 32 | + |
| 33 | +@@ -1255,22 +1255,6 @@ static int protect_dir(const char *path, mode_t mode, int do_mkdir, |
| 34 | + rv = openat(dfd, dir, flags); |
| 35 | + } |
| 36 | + |
| 37 | +- if (rv != -1) { |
| 38 | +- if (fstat(rv, &st) != 0) { |
| 39 | +- save_errno = errno; |
| 40 | +- close(rv); |
| 41 | +- rv = -1; |
| 42 | +- errno = save_errno; |
| 43 | +- goto error; |
| 44 | +- } |
| 45 | +- if (!S_ISDIR(st.st_mode)) { |
| 46 | +- close(rv); |
| 47 | +- errno = ENOTDIR; |
| 48 | +- rv = -1; |
| 49 | +- goto error; |
| 50 | +- } |
| 51 | +- } |
| 52 | +- |
| 53 | + if (flags & O_NOFOLLOW) { |
| 54 | + /* we are inside user-owned dir - protect */ |
| 55 | + if (protect_mount(rv, p, idata) == -1) { |
0 commit comments