From e745b27a683fea07f7684d17678e8255520c297b Mon Sep 17 00:00:00 2001 From: grialion <48643945+grialion@users.noreply.github.com> Date: Tue, 6 Aug 2024 17:11:18 +0200 Subject: [PATCH 1/2] feat(chvt): use custom implementation instead of system() Calling system() is vulnerable and shouldn't be used. --- Makefile | 4 ++-- include/chvt.h | 21 +++++++++++++++++++++ src/chvt.c | 22 ++++++++++++++++++++++ src/main.c | 15 ++++++++------- 4 files changed, 53 insertions(+), 9 deletions(-) create mode 100644 include/chvt.h create mode 100644 src/chvt.c diff --git a/Makefile b/Makefile index 2e7a340..d76889c 100644 --- a/Makefile +++ b/Makefile @@ -10,10 +10,10 @@ ALLFLAGS=$(CFLAGS) -I$(IDIR) LIBS=-lm -lpam -lpam_misc -_DEPS = util.h ui.h config.h auth.h efield.h keys.h users.h sessions.h +_DEPS = util.h ui.h config.h auth.h efield.h keys.h users.h sessions.h chvt.h DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS)) -_OBJ = main.o util.o ui.o config.o auth.o efield.o users.o sessions.o +_OBJ = main.o util.o ui.o config.o auth.o efield.o users.o sessions.o chvt.o OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ)) $(ODIR)/%.o: $(CDIR)/%.c $(DEPS) diff --git a/include/chvt.h b/include/chvt.h new file mode 100644 index 0000000..3b0f279 --- /dev/null +++ b/include/chvt.h @@ -0,0 +1,21 @@ +#ifndef _CHVTH_ +#define _CHVTH_ + +#include +#include +#include +#include + +#define KDGKBTYPE 0x4b33 +#define VT_ACTIVATE 0x5606 +#define VT_WAITACTIVE 0x5607 + +/** + * @brief change foreground virtual terminal to `n` + * + * @param n virtual terminal number + * @return int non-negative value on success + */ +int chvt(int n); + +#endif diff --git a/src/chvt.c b/src/chvt.c new file mode 100644 index 0000000..1ccd7d9 --- /dev/null +++ b/src/chvt.c @@ -0,0 +1,22 @@ +#include "chvt.h" + +static char *vterms[] = {"/dev/tty", "/dev/tty0", "/dev/vc/0", "/dev/systty", + "/dev/console"}; + +int chvt(int n) { + char c = 0; + for (int i = 0; i < sizeof(vterms) / sizeof(vterms[0]); i++) { + int fd = open(vterms[i], O_RDWR); + if (fd >= 0 && isatty(fd) && ioctl(fd, KDGKBTYPE, &c) == 0 && c < 3) { + if (ioctl(fd, VT_ACTIVATE, n) < 0 || ioctl(fd, VT_WAITACTIVE, n) < 0) { + printf("Couldn't active vt %d\n", n); + return -1; + } + return 0; + } + close(fd); + } + + printf("Couldn't get a file descriptor referring to the console.\n"); + return -1; +} diff --git a/src/main.c b/src/main.c index 8ed7467..3ba1931 100644 --- a/src/main.c +++ b/src/main.c @@ -4,22 +4,23 @@ #include #include +#include #include #include #include #include -void chvt(char *arg) { - size_t bsize = snprintf(NULL, 0, "chvt %s", arg) + 1; - char *buf = malloc(bsize); - snprintf(buf, bsize, "chvt %s", arg); - system(buf); - free(buf); +int chvt_char(char c) { + int i = c - '0'; + if (i >= 0 && i <= 9) { + return chvt(i); + } + return -1; } int main(int argc, char *argv[]) { if (argc == 2) - chvt(argv[1]); + chvt_char(argv[1][0]); struct config *config = parse_config("/etc/lidm.ini"); if (config == NULL) { From 4de2720bedc8ca222175a517aa0760c2060b2aab Mon Sep 17 00:00:00 2001 From: javalsai Date: Wed, 7 Aug 2024 00:07:44 +0200 Subject: [PATCH 2/2] small changes --- include/chvt.h | 7 ++----- src/chvt.c | 9 ++++++--- src/main.c | 20 ++++++++++++++------ 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/include/chvt.h b/include/chvt.h index 3b0f279..5d291f5 100644 --- a/include/chvt.h +++ b/include/chvt.h @@ -2,14 +2,11 @@ #define _CHVTH_ #include -#include +#include +#include #include #include -#define KDGKBTYPE 0x4b33 -#define VT_ACTIVATE 0x5606 -#define VT_WAITACTIVE 0x5607 - /** * @brief change foreground virtual terminal to `n` * diff --git a/src/chvt.c b/src/chvt.c index 1ccd7d9..b729a11 100644 --- a/src/chvt.c +++ b/src/chvt.c @@ -1,15 +1,18 @@ -#include "chvt.h" +#include + +#include static char *vterms[] = {"/dev/tty", "/dev/tty0", "/dev/vc/0", "/dev/systty", "/dev/console"}; int chvt(int n) { + fprintf(stderr, "activating vt %d\n", n); char c = 0; for (int i = 0; i < sizeof(vterms) / sizeof(vterms[0]); i++) { int fd = open(vterms[i], O_RDWR); if (fd >= 0 && isatty(fd) && ioctl(fd, KDGKBTYPE, &c) == 0 && c < 3) { if (ioctl(fd, VT_ACTIVATE, n) < 0 || ioctl(fd, VT_WAITACTIVE, n) < 0) { - printf("Couldn't active vt %d\n", n); + fprintf(stderr, "Couldn't activate vt %d\n", n); return -1; } return 0; @@ -17,6 +20,6 @@ int chvt(int n) { close(fd); } - printf("Couldn't get a file descriptor referring to the console.\n"); + fprintf(stderr, "Couldn't get a file descriptor referring to the console.\n"); return -1; } diff --git a/src/main.c b/src/main.c index 3ba1931..20e562c 100644 --- a/src/main.c +++ b/src/main.c @@ -1,3 +1,5 @@ +#include +#include #include #include #include @@ -10,17 +12,23 @@ #include #include -int chvt_char(char c) { - int i = c - '0'; - if (i >= 0 && i <= 9) { - return chvt(i); +int chvt_str(char *str) { + char *err; + long i = strtol(str, &err, 10); + if (errno) { + perror("strol"); + return -1; } - return -1; + // I'm not gonna elaborate on this.... + if (i > INT_MAX || i < INT_MIN || *err) + return -1; + + return chvt((int)i); } int main(int argc, char *argv[]) { if (argc == 2) - chvt_char(argv[1][0]); + chvt_str(argv[1]); struct config *config = parse_config("/etc/lidm.ini"); if (config == NULL) {