Merge pull request #24 from c-edw/feature/AbortSUIDWithPAM

Log error and exit if swaylock is suid with PAM backend.
This commit is contained in:
Drew DeVault 2019-01-18 09:07:17 -05:00 committed by GitHub
commit 52eeb9fc1e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 36 additions and 30 deletions

View File

@ -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);

2
main.c
View File

@ -977,7 +977,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){

8
pam.c
View File

@ -11,7 +11,13 @@
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 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()) {
exit(EXIT_FAILURE);
}

View File

@ -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);
}
}
}