Skip to content

Commit

Permalink
Adding checks for fd omission
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
skyler-ferrante authored and hallyn committed Mar 11, 2024
1 parent b76fc29 commit d2f2c18
Show file tree
Hide file tree
Showing 11 changed files with 63 additions and 7 deletions.
1 change: 1 addition & 0 deletions lib/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
41 changes: 41 additions & 0 deletions lib/fd.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// SPDX-FileCopyrightText: 2024, Skyler Ferrante <[email protected]>
// 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();
}
3 changes: 3 additions & 0 deletions lib/prototypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);
Expand Down
7 changes: 3 additions & 4 deletions src/chage.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 3 additions & 1 deletion src/chfn.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions src/chsh.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
5 changes: 3 additions & 2 deletions src/expiry.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down
2 changes: 2 additions & 0 deletions src/gpasswd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions src/newgrp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions src/passwd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions src/su.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit d2f2c18

Please sign in to comment.