logo

skeud

Simple and portable utilities to deal with user accounts (su, login)
commit: afcf20ccf2b6035ddf318eb3e5a2738a7ca1e1d4
parent 13715e8379eb96bab015e29b7a685b5dfd57b96b
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date:   Sat,  8 Oct 2022 11:17:42 +0200

Add flawfinder in lint target

Diffstat:

MMakefile1+
Mcommon.c30+++++++++++++++++-------------
Mcommon.h2+-
Mlogin.c25++++++++++++-------------
Msu.c26+++++++++++++++-----------
5 files changed, 46 insertions(+), 38 deletions(-)

diff --git a/Makefile b/Makefile @@ -49,3 +49,4 @@ clean: lint: reuse lint mandoc -Tlint -Wunsupp,error,warning $(MAN1) + flawfinder -DQ --error-level=4 . diff --git a/common.c b/common.c @@ -22,7 +22,9 @@ smin(size_t a, size_t b) static bool hash_match(char *a, char *b) { + /* flawfinder: ignore CWE-126 */ size_t len_a = strlen(a); + /* flawfinder: ignore CWE-126 */ size_t len_b = strlen(b); size_t n = smin(len_a, len_b); bool ret = true; @@ -42,6 +44,7 @@ skeud_crypt_check(char *hash, char *password) if(!hash) return false; if(strcmp(hash, "") == 0) return false; + /* flawfinder: ignore CWE-327, crypt is the only relevant function */ char *chk_hash = crypt(password, hash); if(chk_hash == NULL) { @@ -57,17 +60,18 @@ skeud_crypt_check(char *hash, char *password) } ssize_t -skeud_getpass(const char *prompt, char **password) +skeud_getpass(char **password) { struct termios t; - size_t len = 0; - ssize_t read = -1; + size_t len = 0; + ssize_t got = -1; + /* flawfinder: ignore CWE-362 */ FILE *tty = fopen("/dev/tty", "rb+"); if(tty == NULL) { perror("open(\"/dev/tty\")"); - return read; + return got; } int tty_fd = fileno(tty); if(tty_fd < 0) @@ -82,7 +86,7 @@ skeud_getpass(const char *prompt, char **password) goto getpass_end; } - fprintf(tty, prompt); + fprintf(tty, "Password: "); t.c_lflag &= ~ECHO; if(tcsetattr(tty_fd, TCSANOW, &t) < 0) { @@ -90,9 +94,9 @@ skeud_getpass(const char *prompt, char **password) goto getpass_end; } - read = getline(password, &len, tty); + got = getline(password, &len, tty); fprintf(tty, "\n"); - if(read < 0) + if(got < 0) { t.c_lflag &= ECHO; tcsetattr(tty_fd, TCSANOW, &t); @@ -100,21 +104,21 @@ skeud_getpass(const char *prompt, char **password) perror("getline"); goto getpass_end; } - (*password)[read] = 0; - (*password)[read - 1] = 0; - read--; + (*password)[got] = 0; + (*password)[got - 1] = 0; + got--; t.c_lflag &= ECHO; if(tcsetattr(tty_fd, TCSANOW, &t) < 0) { perror("tcsetattr(ECHO)"); - explicit_bzero(password, read); - read = -1; + explicit_bzero(password, got); + got = -1; goto getpass_end; } getpass_end: fclose(tty); - return read; + return got; } diff --git a/common.h b/common.h @@ -4,5 +4,5 @@ #include <stdbool.h> // bool #include <sys/types.h> // ssize_t -ssize_t skeud_getpass(const char *prompt, char **password); +ssize_t skeud_getpass(char **password); bool skeud_crypt_check(char *hash, char *password); diff --git a/login.c b/login.c @@ -22,7 +22,7 @@ #include <unistd.h> // getuid, getopt, opt*, chdir, setuid, setgid extern char **environ; -char *envclear[1]; +char *envclear[] = {NULL}; int main(int argc, char *argv[]) @@ -40,8 +40,7 @@ main(int argc, char *argv[]) return 1; } - // login [-p] [username] - // login [-p] -f username + /* flawfinder: ignore CWE-120, CWE-20 */ while((c = getopt(argc, argv, ":f:p:")) != EOF) { switch(c) @@ -80,15 +79,15 @@ main(int argc, char *argv[]) size_t len = 0; printf("username: "); - ssize_t read = getline(&username, &len, stdin); - if(read < 0) + ssize_t got = getline(&username, &len, stdin); + if(got < 0) { perror("getline"); return 1; } - username[read] = 0; - username[read - 1] = 0; + username[got] = 0; + username[got - 1] = 0; } if(username != NULL) @@ -130,8 +129,8 @@ main(int argc, char *argv[]) #endif /* __linux__ */ char *password = NULL; - ssize_t read = skeud_getpass("password: ", &password); - if(read < 0) + ssize_t got = skeud_getpass(&password); + if(got < 0) { return 1; } @@ -143,14 +142,13 @@ main(int argc, char *argv[]) return 1; } - explicit_bzero(password, read); - explicit_bzero(pw_hash, sizeof(pw_hash)); + explicit_bzero(password, got); + if(pw_hash) explicit_bzero(pw_hash, sizeof(pw_hash)); } if(!opt_p) { - environ = envclear; - envclear[0] = NULL; + environ = envclear; } if(pwent != NULL) @@ -188,6 +186,7 @@ main(int argc, char *argv[]) setenv("SHELL", shell, 1); errno = 0; + /* flawfinder: ignore CWE-78 */ if(execl(shell, shell, NULL) < 0) { if(errno == ENOENT) diff --git a/su.c b/su.c @@ -22,7 +22,7 @@ #include <unistd.h> // getuid, getopt, opt*, chdir, setuid, setgid extern char **environ; -char *envclear[1]; +char *envclear[] = {NULL}; int main(int argc, char *argv[]) @@ -40,8 +40,7 @@ main(int argc, char *argv[]) return 1; } - // su [-p] [-s SHELL] [username] - // su [-p] [-s SHELL] [-l|-] username + /* flawfinder: ignore CWE-120, CWE-20 */ while((c = getopt(argc, argv, ":l:s:p:")) != EOF) { switch(c) @@ -97,10 +96,14 @@ main(int argc, char *argv[]) if(getuid() != 0) { - char *pw_hash = pwent->pw_passwd; + char *pw_hash = NULL; + if(pwent && pwent->pw_passwd) + { + pw_hash = pwent->pw_passwd; + } #ifdef __linux__ - if(strcmp(pw_hash, "x") == 0) + if(pw_hash && strcmp(pw_hash, "x") == 0) { errno = 0; struct spwd *swent = getspnam(username); @@ -115,8 +118,8 @@ main(int argc, char *argv[]) #endif /* __linux__ */ char *password = NULL; - ssize_t read = skeud_getpass("password: ", &password); - if(read < 0) + ssize_t got = skeud_getpass(&password); + if(got < 0) { return 1; } @@ -128,14 +131,13 @@ main(int argc, char *argv[]) return 1; } - explicit_bzero(password, read); - explicit_bzero(pw_hash, sizeof(pw_hash)); + explicit_bzero(password, got); + if(pw_hash) explicit_bzero(pw_hash, sizeof(pw_hash)); } if(!opt_p) { - environ = envclear; - envclear[0] = NULL; + environ = envclear; } if(pwent != NULL) @@ -172,6 +174,7 @@ main(int argc, char *argv[]) if(shell == NULL) { + /* flawfinder: CWE-807, CWE-20 */ shell = getenv("SHELL"); } @@ -183,6 +186,7 @@ main(int argc, char *argv[]) setenv("SHELL", shell, 1); errno = 0; + /* flawfinder: ignore CWE-78 */ if(execlp(shell, shell, NULL) < 0) { if(errno == ENOENT)