From 2c1e20f5bfa7e66d7601092a1a2378a22053b344 Mon Sep 17 00:00:00 2001 From: McDope Date: Wed, 3 Jan 2024 13:06:22 +0100 Subject: [PATCH] Fix misc. problems (#217) - force external commands to english locale - some string/mem fixes - fix pusb_get_process_envvar() returning local variable Maybe affected/fixed issues by this: #205, #199 - but needs testing/validation --- src/local.c | 26 +++++++++++++++++++++----- src/process.c | 24 ++++++++++++++++-------- src/tmux.c | 8 +++----- 3 files changed, 40 insertions(+), 18 deletions(-) diff --git a/src/local.c b/src/local.c index 3f647714..2d6202c5 100644 --- a/src/local.c +++ b/src/local.c @@ -117,6 +117,13 @@ char *pusb_get_tty_from_display_server(const char *display) DIR *d_fd = opendir(fd_path); if (d_fd == NULL) { log_debug(" Determining tty by display server failed (running 'pamusb-check' as user?)\n", fd_path); + + xfree(cmdline_path); + xfree(cmdline); + xfree(fd_path); + xfree(link_path); + xfree(fd_target); + return NULL; } @@ -136,6 +143,11 @@ char *pusb_get_tty_from_display_server(const char *display) closedir(d_fd); closedir(d_proc); + xfree(cmdline_path); + xfree(cmdline); + xfree(fd_path); + xfree(link_path); + return fd_target; } } @@ -147,6 +159,12 @@ char *pusb_get_tty_from_display_server(const char *display) } closedir(d_proc); + xfree(cmdline_path); + xfree(cmdline); + xfree(fd_path); + xfree(link_path); + xfree(fd_target); + return NULL; } @@ -177,7 +195,7 @@ char *pusb_get_tty_by_xorg_display(const char *display, const char *user) char *pusb_get_tty_by_loginctl() { - char loginctl_cmd[BUFSIZ] = "LOGINCTL_SESSION_ID=`loginctl user-status | grep -m 1 \"├─session-\" | grep -o '[0-9]\\+'`; loginctl show-session $LOGINCTL_SESSION_ID -p TTY | awk -F= '{print $2}'"; + char loginctl_cmd[BUFSIZ] = "LC_ALL=c; LOGINCTL_SESSION_ID=`loginctl user-status | grep -m 1 \"├─session-\" | grep -o '[0-9]\\+'`; loginctl show-session $LOGINCTL_SESSION_ID -p TTY | awk -F= '{print $2}'"; char buf[BUFSIZ]; FILE *fp; @@ -209,7 +227,7 @@ char *pusb_get_tty_by_loginctl() int pusb_is_loginctl_local() { - char loginctl_cmd[BUFSIZ] = "LOGINCTL_SESSION_ID=`loginctl user-status | grep -m 1 \"├─session-\" | grep -o '[0-9]\\+'`; loginctl show-session $LOGINCTL_SESSION_ID -p Remote | awk -F= '{print $2}'"; + char loginctl_cmd[BUFSIZ] = "LC_ALL=c; LOGINCTL_SESSION_ID=`loginctl user-status | grep -m 1 \"├─session-\" | grep -o '[0-9]\\+'`; loginctl show-session $LOGINCTL_SESSION_ID -p Remote | awk -F= '{print $2}'"; char buf[BUFSIZ]; FILE *fp; @@ -312,9 +330,7 @@ int pusb_local_login(t_pusb_options *opts, const char *user, const char *service { // DISPLAY contains not only display but also default screen, truncate screen part in this case log_debug(" DISPLAY contains screen, truncating...\n"); - char display_tmp[sizeof(display)]; - snprintf(display_tmp, sizeof(display) - 2, "%s", display); - snprintf(display, strnlen(display_tmp, (sizeof(display_tmp)+1))-1, "%s", display_tmp); + memset(display + strlen(display) - 2, 0, 2); } local_request = pusb_is_tty_local((char *) display); diff --git a/src/process.c b/src/process.c index e39e3d0c..e204360b 100644 --- a/src/process.c +++ b/src/process.c @@ -34,7 +34,7 @@ * @param pid PID of the process * @param name Name of the process * - * Source: http://stackoverflow.com/questions/15545341/process-name-from-its-pid-in-linux + * Source: https://stackoverflow.com/questions/15545341/process-name-from-its-pid-in-linux */ void pusb_get_process_name(const pid_t pid, char * name) { @@ -70,7 +70,7 @@ void pusb_get_process_parent_id(const pid_t pid, pid_t * ppid) size_t size = fread(buffer, sizeof (char), sizeof (buffer), fp); if (size > 0) { - // See: http://man7.org/linux/man-pages/man5/proc.5.html section /proc/[pid]/stat + // See: https://man7.org/linux/man-pages/man5/proc.5.html section /proc/[pid]/stat strtok(buffer, " "); // (1) pid %d strtok(NULL, " "); // (2) comm %s strtok(NULL, " "); // (3) state %c @@ -82,19 +82,25 @@ void pusb_get_process_parent_id(const pid_t pid, pid_t * ppid) } /** - * Read environment variable of another process + * Read environment variable of another process via its /proc/processId/environ file. To so so + * it replaces the zero bytes by # to be able to use strtok on its content. When the requested variable + * is found its name and the equals/assign character will be cut off and the result then returned. * * @param pid pid of process to read the environment of * @param var envvar to look up * * @return content of var if found, else NULL + * + * @see https://man7.org/linux/man-pages/man7/environ.7.html + * @see https://askubuntu.com/a/978715 */ char *pusb_get_process_envvar(pid_t pid, char *var) { char buffer[BUFSIZ]; + char* output = xmalloc(BUFSIZ); + sprintf(buffer, "/proc/%d/environ", pid); FILE* fp = fopen(buffer, "r"); - char *variable_content = (char *)xmalloc(BUFSIZ); if (fp) { size_t size = fread(buffer, sizeof (char), sizeof (buffer), fp); @@ -104,20 +110,22 @@ char *pusb_get_process_envvar(pid_t pid, char *var) if (!buffer[i] && i != size) buffer[i] = '#'; // replace \0 with "#" since strtok uses \0 internally } - if (size > 0) + if (size > 0) { - variable_content = strtok(buffer, "#"); + char* variable_content = strtok(buffer, "#"); while (variable_content != NULL) { - if (strncmp(var, variable_content, strnlen(var, sizeof(var))) == 0) + if (strncmp(var, variable_content, strlen(var)) == 0) { - return variable_content + strnlen(var, sizeof(var)) + 1; + return output; } variable_content = strtok(NULL, "#"); + strcpy(output, variable_content + (strlen(var) +1)); // cut var= and set output string } } } + xfree(output); return NULL; } \ No newline at end of file diff --git a/src/tmux.c b/src/tmux.c index 96bd5938..9a6b75da 100644 --- a/src/tmux.c +++ b/src/tmux.c @@ -29,8 +29,6 @@ char *pusb_tmux_get_client_tty(pid_t env_pid) if (tmux_details == NULL) { log_debug(" No TMUX env var, checking parent process in case this is a sudo request\n"); - - tmux_details = (char *)xmalloc(BUFSIZ); tmux_details = pusb_get_process_envvar(env_pid, "TMUX"); if (tmux_details == NULL) @@ -46,8 +44,8 @@ char *pusb_tmux_get_client_tty(pid_t env_pid) char *tmux_socket_path = strtok(tmux_details, ","); log_debug(" Got tmux_socket_path: %s\n", tmux_socket_path); - char get_tmux_session_details_cmd[64]; - sprintf(get_tmux_session_details_cmd, "tmux -S \"%s\" list-clients -t \"\\$%s\"", tmux_socket_path, tmux_client_id); + char get_tmux_session_details_cmd[128]; + sprintf(get_tmux_session_details_cmd, "LC_ALL=c; tmux -S \"%s\" list-clients -t \"\\$%s\"", tmux_socket_path, tmux_client_id); log_debug(" Built get_tmux_session_details_cmd: %s\n", get_tmux_session_details_cmd); char buf[BUFSIZ]; @@ -101,7 +99,7 @@ int pusb_tmux_has_remote_clients(const char* username) { log_debug(" Checking for IPv%d connections...\n", (4 + (i * 2))); - if ((fp = popen("w", "r")) == NULL) + if ((fp = popen("LC_ALL=c; w", "r")) == NULL) { log_error("tmux detected, but couldn't get `w`. Denying since remote check for tmux impossible without it!\n"); return (-1);