From ef8b80cfd7d43bb4a12d70fdf18babe8f790c214 Mon Sep 17 00:00:00 2001 From: Martijn Dekker Date: Fri, 26 Feb 2021 12:56:36 +0000 Subject: [PATCH] edit.c: make tput invocation work in restricted mode (re: 7ff6b73b) At init, and then whenever the TERM variable changes, ed_setup() uses sh_trap() to run the external 'tput' command to get the current terminal escape sequence for moving up the cursor one line. A sh_trap() call executes a shell command as if a shell script's trap action had executed it, so is subject to modes like the restricted mode. As of 7ff6b73b, we execute tput using its absolute path (found and hardcoded at compile time) for better robustness/security. This fails in restricted mode as it does not allow executing commands by absolute path. But in C, nothing stops us from turning that off. src/cmd/ksh93/edit/edit.c: ed_setup(): - Block SIGINT while doing all of the following, so the user can't interrupt it and escape from restricted mode. Even without that, it's probably a good idea to do this, so an interrupt doesn't cause an inconsistent state. Note that sigblock() and sigrelease() are macros defined in features/sigfeatures. To get those, we need to include . - Temporarily turn off SH_RESTRICTED before sh_trap()ping tput to get the terminal command to move the cursor up one position. - Avoid potentially using a sequence that was cut off. Only use the resulting string if its length does not exceed the space reserved for CURSOR_UP. Otherwise, empty it. src/cmd/ksh93/Mamfile: - Add fault.h dependency to edit.c. src/cmd/ksh93/edit/history.c: - Fix typos in introductory comment. --- src/cmd/ksh93/Mamfile | 1 + src/cmd/ksh93/edit/edit.c | 13 +++++++++++-- src/cmd/ksh93/edit/history.c | 6 +++--- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/cmd/ksh93/Mamfile b/src/cmd/ksh93/Mamfile index 9f3174377..e1d0fcd82 100644 --- a/src/cmd/ksh93/Mamfile +++ b/src/cmd/ksh93/Mamfile @@ -767,6 +767,7 @@ make install done FEATURE/cmds generated prev FEATURE/time implicit prev FEATURE/options implicit + prev include/fault.h implicit prev ${PACKAGE_ast_INCLUDE}/ccode.h implicit prev ${PACKAGE_ast_INCLUDE}/ast.h implicit done edit/edit.c diff --git a/src/cmd/ksh93/edit/edit.c b/src/cmd/ksh93/edit/edit.c index 3338bd31d..8cffb861d 100644 --- a/src/cmd/ksh93/edit/edit.c +++ b/src/cmd/ksh93/edit/edit.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "FEATURE/options" #include "FEATURE/time" #include "FEATURE/cmds" @@ -785,6 +786,9 @@ void ed_setup(register Edit_t *ep, int fd, int reedit) ep->e_term = nv_search("TERM",shp->var_tree,0); if(ep->e_term && (term=nv_getval(ep->e_term)) && strlen(term)e_termname) && strcmp(term,ep->e_termname)) { + char was_restricted = (sh_isoption(SH_RESTRICTED)!=0); + sigblock(SIGINT); + sh_offoption(SH_RESTRICTED); #if _tput_terminfo sh_trap(".sh.subscript=$(" _pth_tput " cuu1 2>/dev/null)",0); #elif _tput_termcap @@ -792,10 +796,15 @@ void ed_setup(register Edit_t *ep, int fd, int reedit) #else #error no tput method #endif - if(pp=nv_getval(SH_SUBSCRNOD)) - strncpy(CURSOR_UP,pp,sizeof(CURSOR_UP)-1); + if((pp = nv_getval(SH_SUBSCRNOD)) && strlen(pp) < sizeof(CURSOR_UP)) + strcpy(CURSOR_UP,pp); + else + CURSOR_UP[0] = '\0'; /* no escape sequence is better than a faulty one */ nv_unset(SH_SUBSCRNOD); strcpy(ep->e_termname,term); + if(was_restricted) + sh_onoption(SH_RESTRICTED); + sigrelease(SIGINT); } #endif ep->e_wsize = MAXLINE - (ep->e_plen+1); diff --git a/src/cmd/ksh93/edit/history.c b/src/cmd/ksh93/edit/history.c index 45b5a78e8..473d1ed68 100644 --- a/src/cmd/ksh93/edit/history.c +++ b/src/cmd/ksh93/edit/history.c @@ -27,14 +27,14 @@ */ /* - * Each command in the history file starts on an even byte is null terminated. + * Each command in the history file starts on an even byte and is null-terminated. * The first byte must contain the special character HIST_UNDO and the second * byte is the version number. The sequence HIST_UNDO 0, following a command, - * nullifies the previous command. A six byte sequence starting with + * nullifies the previous command. A six-byte sequence starting with * HIST_CMDNO is used to store the command number so that it is not necessary * to read the file from beginning to end to get to the last block of * commands. This format of this sequence is different in version 1 - * then in version 0. Version 1 allows commands to use the full 8 bit + * than in version 0. Version 1 allows commands to use the full 8-bit * character set. It can understand version 0 format files. */