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 \
|
||||
failure.c \
|
||||
failure.h \
|
||||
fd.c \
|
||||
fields.c \
|
||||
find_new_gid.c \
|
||||
find_new_uid.c \
|
||||
|
||||
41
lib/fd.c
Normal file
41
lib/fd.c
Normal file
@@ -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 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 *);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user