From ccefa54bb7d00f1ea923f283434b6af86e27708d Mon Sep 17 00:00:00 2001 From: Connor E <38229097+c-edw@users.noreply.github.com> Date: Fri, 18 Jan 2019 12:56:00 +0000 Subject: [PATCH 1/2] Log error and exit if swaylock is suid with PAM backend. --- pam.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pam.c b/pam.c index 0c21536..a192f84 100644 --- a/pam.c +++ b/pam.c @@ -12,6 +12,11 @@ static char *pw_buf = NULL; void initialize_pw_backend(void) { + if (getuid() != geteuid() || getgid() != getegid()) { + swaylock_log(LOG_ERROR, + "swaylock has suid but doesn't require it with PAM backend"); + exit(EXIT_FAILURE); + } if (!spawn_comm_child()) { exit(EXIT_FAILURE); } From 648b0ccd64c45f6a37c8b6c49a39416a78230a2f Mon Sep 17 00:00:00 2001 From: Connor E <38229097+c-edw@users.noreply.github.com> Date: Fri, 18 Jan 2019 13:52:17 +0000 Subject: [PATCH 2/2] Make setuid error clearer. --- include/swaylock.h | 2 +- main.c | 2 +- pam.c | 5 +++-- shadow.c | 54 +++++++++++++++++++++++----------------------- 4 files changed, 32 insertions(+), 31 deletions(-) diff --git a/include/swaylock.h b/include/swaylock.h index 32ded18..56cee3b 100644 --- a/include/swaylock.h +++ b/include/swaylock.h @@ -112,7 +112,7 @@ void damage_state(struct swaylock_state *state); void clear_password_buffer(struct swaylock_password *pw); void schedule_indicator_clear(struct swaylock_state *state); -void initialize_pw_backend(void); +void initialize_pw_backend(int argc, char **argv); void run_pw_backend_child(void); void clear_buffer(char *buf, size_t size); diff --git a/main.c b/main.c index 5c21817..b8e1945 100644 --- a/main.c +++ b/main.c @@ -970,7 +970,7 @@ static void comm_in(int fd, short mask, void *data) { int main(int argc, char **argv) { swaylock_log_init(LOG_ERROR); - initialize_pw_backend(); + initialize_pw_backend(argc, argv); enum line_mode line_mode = LM_LINE; state.args = (struct swaylock_args){ diff --git a/pam.c b/pam.c index a192f84..a603bd8 100644 --- a/pam.c +++ b/pam.c @@ -11,10 +11,11 @@ static char *pw_buf = NULL; -void initialize_pw_backend(void) { +void initialize_pw_backend(int argc, char **argv) { if (getuid() != geteuid() || getgid() != getegid()) { swaylock_log(LOG_ERROR, - "swaylock has suid but doesn't require it with PAM backend"); + "swaylock is setuid, but was compiled with the PAM" + " backend. Run 'chmod a-s %s' to fix. Aborting.", argv[0]); exit(EXIT_FAILURE); } if (!spawn_comm_child()) { diff --git a/shadow.c b/shadow.c index f98301e..70d00a8 100644 --- a/shadow.c +++ b/shadow.c @@ -12,6 +12,32 @@ #include "log.h" #include "swaylock.h" +void initialize_pw_backend(int argc, char **argv) { + if (geteuid() != 0) { + swaylock_log(LOG_ERROR, + "swaylock needs to be setuid to read /etc/shadow"); + exit(EXIT_FAILURE); + } + + if (!spawn_comm_child()) { + exit(EXIT_FAILURE); + } + + if (setgid(getgid()) != 0) { + swaylock_log_errno(LOG_ERROR, "Unable to drop root"); + exit(EXIT_FAILURE); + } + if (setuid(getuid()) != 0) { + swaylock_log_errno(LOG_ERROR, "Unable to drop root"); + exit(EXIT_FAILURE); + } + if (setuid(0) != -1) { + swaylock_log_errno(LOG_ERROR, "Unable to drop root (we shouldn't be " + "able to restore it after setuid)"); + exit(EXIT_FAILURE); + } +} + void run_pw_backend_child(void) { /* This code runs as root */ struct passwd *pwent = getpwuid(getuid()); @@ -72,30 +98,4 @@ void run_pw_backend_child(void) { clear_buffer(encpw, strlen(encpw)); exit(EXIT_SUCCESS); -} - -void initialize_pw_backend(void) { - if (geteuid() != 0) { - swaylock_log(LOG_ERROR, - "swaylock needs to be setuid to read /etc/shadow"); - exit(EXIT_FAILURE); - } - - if (!spawn_comm_child()) { - exit(EXIT_FAILURE); - } - - if (setgid(getgid()) != 0) { - swaylock_log_errno(LOG_ERROR, "Unable to drop root"); - exit(EXIT_FAILURE); - } - if (setuid(getuid()) != 0) { - swaylock_log_errno(LOG_ERROR, "Unable to drop root"); - exit(EXIT_FAILURE); - } - if (setuid(0) != -1) { - swaylock_log_errno(LOG_ERROR, "Unable to drop root (we shouldn't be " - "able to restore it after setuid)"); - exit(EXIT_FAILURE); - } -} +} \ No newline at end of file