Adding checks for fd omission
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>
This commit is contained in:
committed by
Serge Hallyn
parent
b76fc2947f
commit
d2f2c1877a
@@ -61,6 +61,7 @@ libshadow_la_SOURCES = \
|
|||||||
faillog.h \
|
faillog.h \
|
||||||
failure.c \
|
failure.c \
|
||||||
failure.h \
|
failure.h \
|
||||||
|
fd.c \
|
||||||
fields.c \
|
fields.c \
|
||||||
find_new_gid.c \
|
find_new_gid.c \
|
||||||
find_new_uid.c \
|
find_new_uid.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();
|
||||||
|
}
|
||||||
@@ -120,6 +120,9 @@ extern void initenv (void);
|
|||||||
extern void set_env (int, char *const *);
|
extern void set_env (int, char *const *);
|
||||||
extern void sanitize_env (void);
|
extern void sanitize_env (void);
|
||||||
|
|
||||||
|
/* fd.c */
|
||||||
|
extern void check_fds (void);
|
||||||
|
|
||||||
/* fields.c */
|
/* fields.c */
|
||||||
extern void change_field (char *, size_t, const char *);
|
extern void change_field (char *, size_t, const char *);
|
||||||
extern int valid_field (const char *, const char *);
|
extern int valid_field (const char *, const char *);
|
||||||
|
|||||||
+3
-4
@@ -768,13 +768,12 @@ int main (int argc, char **argv)
|
|||||||
gid_t rgid;
|
gid_t rgid;
|
||||||
const struct passwd *pw;
|
const struct passwd *pw;
|
||||||
|
|
||||||
/*
|
sanitize_env ();
|
||||||
* Get the program name so that error messages can use it.
|
check_fds ();
|
||||||
*/
|
|
||||||
log_set_progname(Prog);
|
log_set_progname(Prog);
|
||||||
log_set_logfd(stderr);
|
log_set_logfd(stderr);
|
||||||
|
|
||||||
sanitize_env ();
|
|
||||||
(void) setlocale (LC_ALL, "");
|
(void) setlocale (LC_ALL, "");
|
||||||
(void) bindtextdomain (PACKAGE, LOCALEDIR);
|
(void) bindtextdomain (PACKAGE, LOCALEDIR);
|
||||||
(void) textdomain (PACKAGE);
|
(void) textdomain (PACKAGE);
|
||||||
|
|||||||
+3
-1
@@ -620,10 +620,12 @@ int main (int argc, char **argv)
|
|||||||
char *user;
|
char *user;
|
||||||
const struct passwd *pw;
|
const struct passwd *pw;
|
||||||
|
|
||||||
|
sanitize_env ();
|
||||||
|
check_fds ();
|
||||||
|
|
||||||
log_set_progname(Prog);
|
log_set_progname(Prog);
|
||||||
log_set_logfd(stderr);
|
log_set_logfd(stderr);
|
||||||
|
|
||||||
sanitize_env ();
|
|
||||||
(void) setlocale (LC_ALL, "");
|
(void) setlocale (LC_ALL, "");
|
||||||
(void) bindtextdomain (PACKAGE, LOCALEDIR);
|
(void) bindtextdomain (PACKAGE, LOCALEDIR);
|
||||||
(void) textdomain (PACKAGE);
|
(void) textdomain (PACKAGE);
|
||||||
|
|||||||
@@ -472,6 +472,7 @@ int main (int argc, char **argv)
|
|||||||
const struct passwd *pw; /* Password entry from /etc/passwd */
|
const struct passwd *pw; /* Password entry from /etc/passwd */
|
||||||
|
|
||||||
sanitize_env ();
|
sanitize_env ();
|
||||||
|
check_fds ();
|
||||||
|
|
||||||
log_set_progname(Prog);
|
log_set_progname(Prog);
|
||||||
log_set_logfd(stderr);
|
log_set_logfd(stderr);
|
||||||
|
|||||||
+3
-2
@@ -125,11 +125,12 @@ int main (int argc, char **argv)
|
|||||||
struct passwd *pwd;
|
struct passwd *pwd;
|
||||||
struct spwd *spwd;
|
struct spwd *spwd;
|
||||||
|
|
||||||
|
sanitize_env ();
|
||||||
|
check_fds ();
|
||||||
|
|
||||||
log_set_progname(Prog);
|
log_set_progname(Prog);
|
||||||
log_set_logfd(stderr);
|
log_set_logfd(stderr);
|
||||||
|
|
||||||
sanitize_env ();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Start by disabling all of the keyboard signals.
|
* Start by disabling all of the keyboard signals.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -930,6 +930,8 @@ int main (int argc, char **argv)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
sanitize_env ();
|
sanitize_env ();
|
||||||
|
check_fds ();
|
||||||
|
|
||||||
(void) setlocale (LC_ALL, "");
|
(void) setlocale (LC_ALL, "");
|
||||||
(void) bindtextdomain (PACKAGE, LOCALEDIR);
|
(void) bindtextdomain (PACKAGE, LOCALEDIR);
|
||||||
(void) textdomain (PACKAGE);
|
(void) textdomain (PACKAGE);
|
||||||
|
|||||||
@@ -390,6 +390,9 @@ int main (int argc, char **argv)
|
|||||||
#ifdef WITH_AUDIT
|
#ifdef WITH_AUDIT
|
||||||
audit_help_open ();
|
audit_help_open ();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
check_fds ();
|
||||||
|
|
||||||
(void) setlocale (LC_ALL, "");
|
(void) setlocale (LC_ALL, "");
|
||||||
(void) bindtextdomain (PACKAGE, LOCALEDIR);
|
(void) bindtextdomain (PACKAGE, LOCALEDIR);
|
||||||
(void) textdomain (PACKAGE);
|
(void) textdomain (PACKAGE);
|
||||||
|
|||||||
@@ -728,6 +728,7 @@ int main (int argc, char **argv)
|
|||||||
const struct spwd *sp; /* Shadow file entry for user */
|
const struct spwd *sp; /* Shadow file entry for user */
|
||||||
|
|
||||||
sanitize_env ();
|
sanitize_env ();
|
||||||
|
check_fds ();
|
||||||
|
|
||||||
log_set_progname(Prog);
|
log_set_progname(Prog);
|
||||||
log_set_logfd(stderr);
|
log_set_logfd(stderr);
|
||||||
|
|||||||
@@ -1007,6 +1007,8 @@ int main (int argc, char **argv)
|
|||||||
int ret;
|
int ret;
|
||||||
#endif /* USE_PAM */
|
#endif /* USE_PAM */
|
||||||
|
|
||||||
|
check_fds ();
|
||||||
|
|
||||||
(void) setlocale (LC_ALL, "");
|
(void) setlocale (LC_ALL, "");
|
||||||
(void) bindtextdomain (PACKAGE, LOCALEDIR);
|
(void) bindtextdomain (PACKAGE, LOCALEDIR);
|
||||||
(void) textdomain (PACKAGE);
|
(void) textdomain (PACKAGE);
|
||||||
|
|||||||
Reference in New Issue
Block a user