]> git.ipfire.org Git - thirdparty/shadow.git/commitdiff
Adding checks for fd omission
authorSkyler Ferrante <sjf5462@rit.edu>
Fri, 8 Mar 2024 17:53:21 +0000 (12:53 -0500)
committerSerge Hallyn <serge@hallyn.com>
Mon, 11 Mar 2024 00:56:40 +0000 (19:56 -0500)
Adding function check_fds to new file fd.c. The function check_fds
should be called in every setuid/setgid program.

Co-developed-by: Alejandro Colomar <alx@kernel.org>
lib/Makefile.am
lib/fd.c [new file with mode: 0644]
lib/prototypes.h
src/chage.c
src/chfn.c
src/chsh.c
src/expiry.c
src/gpasswd.c
src/newgrp.c
src/passwd.c
src/su.c

index 5383857261bbaca85288832465bb80d1ced99dbb..86c6be73d774d498525349996e970f0bc817d357 100644 (file)
@@ -61,6 +61,7 @@ libshadow_la_SOURCES = \
        faillog.h \
        failure.c \
        failure.h \
+       fd.c \
        fields.c \
        find_new_gid.c \
        find_new_uid.c \
diff --git a/lib/fd.c b/lib/fd.c
new file mode 100644 (file)
index 0000000..bcfa374
--- /dev/null
+++ b/lib/fd.c
@@ -0,0 +1,41 @@
+// SPDX-FileCopyrightText: 2024, Skyler Ferrante <sjf5462@rit.edu>
+// SPDX-License-Identifier: BSD-3-Clause
+
+/**
+ * To protect against file descriptor omission attacks, we open the std file
+ * descriptors with /dev/null if they are not already open. Code is based on
+ * fix_fds from sudo.c.
+ */
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "prototypes.h"
+
+static void check_fd(int fd);
+
+void
+check_fds(void)
+{
+       /**
+        * Make sure stdin, stdout, stderr are open
+        * If they are closed, set them to /dev/null
+        */
+       check_fd(STDIN_FILENO);
+       check_fd(STDOUT_FILENO);
+       check_fd(STDERR_FILENO);
+}
+
+static void
+check_fd(int fd)
+{
+       int  devnull;
+
+       if (fcntl(fd, F_GETFL, 0) != -1)
+               return;
+
+       devnull = open("/dev/null", O_RDWR);
+       if (devnull != fd)
+               abort();
+}
index 0fac291c6689bd061fedfc54dd1324b1e3c16bd9..ff4f7f9963a561a0081a6cac8a984e4d6c57643f 100644 (file)
@@ -120,6 +120,9 @@ extern void initenv (void);
 extern void set_env (int, char *const *);
 extern void sanitize_env (void);
 
+/* fd.c */
+extern void check_fds (void);
+
 /* fields.c */
 extern void change_field (char *, size_t, const char *);
 extern int valid_field (const char *, const char *);
index 5226810646a05d40a59329616b3ef5198db40da3..c29ef99e54c43a8d236a6011e079f724799ddeb0 100644 (file)
@@ -768,13 +768,12 @@ int main (int argc, char **argv)
        gid_t rgid;
        const struct passwd *pw;
 
-       /*
-        * Get the program name so that error messages can use it.
-        */
+       sanitize_env ();
+       check_fds ();
+
        log_set_progname(Prog);
        log_set_logfd(stderr);
 
-       sanitize_env ();
        (void) setlocale (LC_ALL, "");
        (void) bindtextdomain (PACKAGE, LOCALEDIR);
        (void) textdomain (PACKAGE);
index 6dc9829011a6171330e3996e26f29739bae0236a..0877ab7e84a13fac77e1cc4ac1d469c0725e3b26 100644 (file)
@@ -620,10 +620,12 @@ int main (int argc, char **argv)
        char                 *user;
        const struct passwd  *pw;
 
+       sanitize_env ();
+       check_fds ();
+
        log_set_progname(Prog);
        log_set_logfd(stderr);
 
-       sanitize_env ();
        (void) setlocale (LC_ALL, "");
        (void) bindtextdomain (PACKAGE, LOCALEDIR);
        (void) textdomain (PACKAGE);
index ce9b1629948245386e620e65aca3456159e8ea4b..9be52e3db05897a645c3895dcd5d429adaeb5d83 100644 (file)
@@ -472,6 +472,7 @@ int main (int argc, char **argv)
        const struct passwd *pw;        /* Password entry from /etc/passwd   */
 
        sanitize_env ();
+       check_fds ();
 
        log_set_progname(Prog);
        log_set_logfd(stderr);
index 792f33f20cfdd02aa903a74fa9e5c26983400e30..12647a23ade3cd8ab2f09926016a4c5b5155c1de 100644 (file)
@@ -125,11 +125,12 @@ int main (int argc, char **argv)
        struct passwd *pwd;
        struct spwd *spwd;
 
+       sanitize_env ();
+       check_fds ();
+
        log_set_progname(Prog);
        log_set_logfd(stderr);
 
-       sanitize_env ();
-
        /*
         * Start by disabling all of the keyboard signals.
         */
index 9692e2511bfe6172a2612ee481e2b4cf0a8fd840..de6b1c4ccde8b18cdcebc7f8d84c2fe17a9917e5 100644 (file)
@@ -930,6 +930,8 @@ int main (int argc, char **argv)
 #endif
 
        sanitize_env ();
+       check_fds ();
+
        (void) setlocale (LC_ALL, "");
        (void) bindtextdomain (PACKAGE, LOCALEDIR);
        (void) textdomain (PACKAGE);
index c536e084be4028714d0e9a97be1af014ed4535b1..1b3d76b83cac6f0cde1f41defdcec6f3d337f67a 100644 (file)
@@ -390,6 +390,9 @@ int main (int argc, char **argv)
 #ifdef WITH_AUDIT
        audit_help_open ();
 #endif
+
+       check_fds ();
+
        (void) setlocale (LC_ALL, "");
        (void) bindtextdomain (PACKAGE, LOCALEDIR);
        (void) textdomain (PACKAGE);
index 2b77c2761468ff0ec39c3973ca4e861f5070a9dd..63729f82db66985719b137a91b094eed97460394 100644 (file)
@@ -728,6 +728,7 @@ int main (int argc, char **argv)
        const struct spwd *sp;  /* Shadow file entry for user   */
 
        sanitize_env ();
+       check_fds ();
 
        log_set_progname(Prog);
        log_set_logfd(stderr);
index ea0e7223c27567acdaa4a22301e53b73e552157a..80c0859711cd7f16f0f80c4dae21b9eb2c39c636 100644 (file)
--- a/src/su.c
+++ b/src/su.c
@@ -1007,6 +1007,8 @@ int main (int argc, char **argv)
        int ret;
 #endif                         /* USE_PAM */
 
+       check_fds ();
+
        (void) setlocale (LC_ALL, "");
        (void) bindtextdomain (PACKAGE, LOCALEDIR);
        (void) textdomain (PACKAGE);