Import from AlmaLinux stable repository
This commit is contained in:
parent
07bb6bb3ad
commit
968888d3d2
194
SOURCES/ksh-1.0.10-blankline.patch
Normal file
194
SOURCES/ksh-1.0.10-blankline.patch
Normal file
@ -0,0 +1,194 @@
|
||||
From a1fcad4bf65fe26a3f9a386b63732ab151ce03ec Mon Sep 17 00:00:00 2001
|
||||
From: Martijn Dekker <martijn@inlv.org>
|
||||
Date: Thu, 5 Dec 2024 02:24:39 +0000
|
||||
Subject: [PATCH] vi: Fix recalling lines starting with whitespace (re:
|
||||
5eeeed06)
|
||||
|
||||
@jghub reports:
|
||||
> if for some reason a command is entered with leading whitespace,
|
||||
> the leading whitespace is preserved in the history file (in
|
||||
> ksh93u+, too). such commands can be recalled from history in 93u+
|
||||
> without problem, both, in vi and emacs mode.
|
||||
>
|
||||
> but in 93u+m such entries are simply ignored when using vi-mode
|
||||
> (set -o vi), i.e. the k and j commands skip over such entries.
|
||||
> emacs mode still works just fine.
|
||||
|
||||
Analysis: the blankline() function in vi.c and emacs.c is used to
|
||||
check for whitespace up to the cursor position. This is used for
|
||||
tab completion and fullscreen editor invocation, where that is
|
||||
okay, and for history recall, where that should be checking the
|
||||
entire line instead.
|
||||
|
||||
In emacs.c this was not really a problem because arrowing up (or
|
||||
^P) positions the cursor to the end of the line anyway. But in vi,
|
||||
arrowing up (or 'k') positions the cursor at the beginning.
|
||||
|
||||
src/cmd/ksh93/edit/vi.c:
|
||||
- Amend blankline() with an 'uptocursor' argument. If nonzero, it
|
||||
checks the current line for whitespace up to the cursor position,
|
||||
otherwise it checks the entire line.
|
||||
- Pass uptocursor==0 to blankline() for history recall and 1 for
|
||||
tab completion.
|
||||
|
||||
src/cmd/ksh93/edit/emacs.c:
|
||||
- Apply the same change here for consistency, even though it's
|
||||
perhaps not really necessary. If ever a form of recall is added
|
||||
that doesn't position the cursor at the end, then that won't
|
||||
introduce this bug there.
|
||||
|
||||
Thanks to @pghvlaans for input into the fix.
|
||||
Resolves: https://github.com/ksh93/ksh/issues/799
|
||||
---
|
||||
src/cmd/ksh93/edit/emacs.c | 14 +++++++-------
|
||||
src/cmd/ksh93/edit/vi.c | 16 ++++++++--------
|
||||
src/cmd/ksh93/tests/pty.sh | 12 ++++++++++++
|
||||
3 files changed, 27 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/src/cmd/ksh93/edit/emacs.c b/src/cmd/ksh93/edit/emacs.c
|
||||
index 128e592..408f6e7 100644
|
||||
--- a/src/cmd/ksh93/edit/emacs.c
|
||||
+++ b/src/cmd/ksh93/edit/emacs.c
|
||||
@@ -178,7 +178,7 @@ static void search(Emacs_t*,genchar*,int);
|
||||
static void setcursor(Emacs_t*,int, int);
|
||||
static void show_info(Emacs_t*,const char*);
|
||||
static void xcommands(Emacs_t*,int);
|
||||
-static char blankline(Emacs_t*, genchar*);
|
||||
+static int blankline(Emacs_t*, genchar*, int);
|
||||
|
||||
int ed_emacsread(void *context, int fd,char *buff,int scend, int reedit)
|
||||
{
|
||||
@@ -720,9 +720,9 @@ update:
|
||||
cur = eol;
|
||||
draw(ep,UPDATE);
|
||||
/* skip blank lines when going up/down in history */
|
||||
- if(c==cntl('N') && hline != histlines && blankline(ep,out))
|
||||
+ if(c==cntl('N') && hline != histlines && blankline(ep,out,0))
|
||||
ed_ungetchar(ep->ed,cntl('N'));
|
||||
- else if(c==cntl('P') && hline != hismin && blankline(ep,out))
|
||||
+ else if(c==cntl('P') && hline != hismin && blankline(ep,out,0))
|
||||
ed_ungetchar(ep->ed,cntl('P'));
|
||||
continue;
|
||||
}
|
||||
@@ -1023,7 +1023,7 @@ static int escape(Emacs_t* ep,genchar *out,int count)
|
||||
case '*': /* filename expansion */
|
||||
case '=': /* escape = - list all matching file names */
|
||||
{
|
||||
- if(cur<1 || blankline(ep,out))
|
||||
+ if(cur<1 || blankline(ep,out,1))
|
||||
{
|
||||
beep();
|
||||
return -1;
|
||||
@@ -1312,7 +1312,7 @@ static void xcommands(Emacs_t *ep,int count)
|
||||
case cntl('E'): /* invoke emacs on current command */
|
||||
if(eol>=0 && sh.hist_ptr)
|
||||
{
|
||||
- if(blankline(ep,drawbuff))
|
||||
+ if(blankline(ep,drawbuff,1))
|
||||
{
|
||||
cur = 0;
|
||||
eol = 1;
|
||||
@@ -1785,11 +1785,11 @@ static int _isword(int c)
|
||||
/*
|
||||
* determine if the command line is blank (empty or all whitespace)
|
||||
*/
|
||||
-static char blankline(Emacs_t *ep, genchar *out)
|
||||
+static int blankline(Emacs_t *ep, genchar *out, int uptocursor)
|
||||
{
|
||||
int x;
|
||||
ep->mark = cur;
|
||||
- for(x=0; x < cur; x++)
|
||||
+ for(x=0; uptocursor ? (x < cur) : (x <= eol); x++)
|
||||
{
|
||||
#if SHOPT_MULTIBYTE
|
||||
if(!iswspace((wchar_t)out[x]))
|
||||
diff --git a/src/cmd/ksh93/edit/vi.c b/src/cmd/ksh93/edit/vi.c
|
||||
index fac40ee..852613c 100644
|
||||
--- a/src/cmd/ksh93/edit/vi.c
|
||||
+++ b/src/cmd/ksh93/edit/vi.c
|
||||
@@ -176,7 +176,7 @@ typedef struct _vi_
|
||||
|
||||
static const char paren_chars[] = "([{)]}"; /* for % command */
|
||||
|
||||
-static char blankline(Vi_t*);
|
||||
+static int blankline(Vi_t*, int);
|
||||
static void cursor(Vi_t*, int);
|
||||
static void del_line(Vi_t*,int);
|
||||
static int getcount(Vi_t*,int);
|
||||
@@ -667,9 +667,9 @@ static int cntlmode(Vi_t *vp)
|
||||
}
|
||||
#endif /* SHOPT_EDPREDICT */
|
||||
/* skip blank lines when going up/down in history */
|
||||
- if((c=='k' || c=='-') && curhline != histmin && blankline(vp))
|
||||
+ if((c=='k' || c=='-') && curhline != histmin && blankline(vp,0))
|
||||
ed_ungetchar(vp->ed,'k');
|
||||
- else if((c=='j' || c=='+') && curhline != histmax && blankline(vp))
|
||||
+ else if((c=='j' || c=='+') && curhline != histmax && blankline(vp,0))
|
||||
ed_ungetchar(vp->ed,'j');
|
||||
break;
|
||||
|
||||
@@ -693,7 +693,7 @@ static int cntlmode(Vi_t *vp)
|
||||
case 'v':
|
||||
if(vp->repeat_set==0)
|
||||
{
|
||||
- if(blankline(vp) || cur_virt == INVALID)
|
||||
+ if(blankline(vp,1) || cur_virt == INVALID)
|
||||
{
|
||||
cur_virt = 0;
|
||||
last_virt = cur_virt;
|
||||
@@ -1294,7 +1294,7 @@ static void getline(Vi_t* vp,int mode)
|
||||
|
||||
case '\t': /** command completion **/
|
||||
{
|
||||
- if(blankline(vp))
|
||||
+ if(blankline(vp,1))
|
||||
{
|
||||
ed_ringbell();
|
||||
break;
|
||||
@@ -2317,7 +2317,7 @@ addin:
|
||||
case '\\': /** do file name completion in place **/
|
||||
case '=': /** list file name expansions **/
|
||||
{
|
||||
- if(cur_virt == INVALID || blankline(vp))
|
||||
+ if(cur_virt == INVALID || blankline(vp,1))
|
||||
return BAD;
|
||||
/* FALLTHROUGH */
|
||||
save_v(vp);
|
||||
@@ -2673,10 +2673,10 @@ yankeol:
|
||||
/*
|
||||
* determine if the command line is blank (empty or all whitespace)
|
||||
*/
|
||||
-static char blankline(Vi_t *vp)
|
||||
+static int blankline(Vi_t *vp, int uptocursor)
|
||||
{
|
||||
int x;
|
||||
- for(x=0; x <= cur_virt; x++)
|
||||
+ for(x=0; x <= (uptocursor ? cur_virt : last_virt); x++)
|
||||
{
|
||||
#if SHOPT_MULTIBYTE
|
||||
if(!iswspace((wchar_t)virtual[x]))
|
||||
diff --git a/src/cmd/ksh93/tests/pty.sh b/src/cmd/ksh93/tests/pty.sh
|
||||
index b4f8e28..ea0c616 100755
|
||||
--- a/src/cmd/ksh93/tests/pty.sh
|
||||
+++ b/src/cmd/ksh93/tests/pty.sh
|
||||
@@ -1269,5 +1269,17 @@ w print Exit status $?
|
||||
u ^Exit status 0\r\n$
|
||||
!
|
||||
|
||||
+((SHOPT_VSH)) && tst $LINENO <<"!"
|
||||
+L 'k' skips over history entries starting with whitespace
|
||||
+# https://github.com/ksh93/ksh/issues/799
|
||||
+
|
||||
+d 40
|
||||
+p :test-1:
|
||||
+w true
|
||||
+p :test-2:
|
||||
+c \Ek
|
||||
+r :test-2: true
|
||||
+!
|
||||
+
|
||||
# ======
|
||||
exit $((Errors<125?Errors:125))
|
||||
--
|
||||
2.49.0
|
||||
|
||||
101
SOURCES/ksh-1.0.10-pjob.patch
Normal file
101
SOURCES/ksh-1.0.10-pjob.patch
Normal file
@ -0,0 +1,101 @@
|
||||
From 685f18d36e162c6f6baf44e1c2c8c762ee41466d Mon Sep 17 00:00:00 2001
|
||||
From: Vincent Mihalkovic <vmihalko@redhat.com>
|
||||
Date: Sat, 13 Jul 2024 23:45:07 +0200
|
||||
Subject: [PATCH] jobs: change p_job variable type from short to int (#763)
|
||||
|
||||
This change addresses an issue where ksh has undefined behavior
|
||||
when the number of jobs exceeds `2^15 - 1` (32767), which is the
|
||||
maximum value for a `short`. The short integer overflow happened in
|
||||
jobs.c, line 1210.
|
||||
---
|
||||
src/cmd/ksh93/include/jobs.h | 5 +++--
|
||||
src/cmd/ksh93/sh/jobs.c | 11 ++++++-----
|
||||
2 files changed, 8 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/src/cmd/ksh93/include/jobs.h b/src/cmd/ksh93/include/jobs.h
|
||||
index 4ae48d70fb7a..758804118f30 100644
|
||||
--- a/src/cmd/ksh93/include/jobs.h
|
||||
+++ b/src/cmd/ksh93/include/jobs.h
|
||||
@@ -2,7 +2,7 @@
|
||||
* *
|
||||
* This software is part of the ast package *
|
||||
* Copyright (c) 1982-2011 AT&T Intellectual Property *
|
||||
-* Copyright (c) 2020-2023 Contributors to ksh 93u+m *
|
||||
+* Copyright (c) 2020-2024 Contributors to ksh 93u+m *
|
||||
* and is licensed under the *
|
||||
* Eclipse Public License, Version 2.0 *
|
||||
* *
|
||||
@@ -14,6 +14,7 @@
|
||||
* Martijn Dekker <martijn@inlv.org> *
|
||||
* Johnothan King <johnothanking@protonmail.com> *
|
||||
* Anuradha Weeraman <anuradha@debian.org> *
|
||||
+* Vincent Mihalkovic <vmihalko@redhat.com> *
|
||||
* *
|
||||
***********************************************************************/
|
||||
#ifndef JOB_NFLAG
|
||||
@@ -51,7 +52,7 @@ struct process
|
||||
pid_t p_pid; /* process ID */
|
||||
pid_t p_pgrp; /* process group */
|
||||
pid_t p_fgrp; /* process group when stopped */
|
||||
- short p_job; /* job number of process */
|
||||
+ int p_job; /* job number of process */
|
||||
unsigned short p_exit; /* exit value or signal number */
|
||||
unsigned short p_exitmin; /* minimum exit value for xargs */
|
||||
unsigned short p_flag; /* flags - see below */
|
||||
diff --git a/src/cmd/ksh93/sh/jobs.c b/src/cmd/ksh93/sh/jobs.c
|
||||
index 871658256f15..86bbe5a9c949 100644
|
||||
--- a/src/cmd/ksh93/sh/jobs.c
|
||||
+++ b/src/cmd/ksh93/sh/jobs.c
|
||||
@@ -13,6 +13,7 @@
|
||||
* David Korn <dgk@research.att.com> *
|
||||
* Martijn Dekker <martijn@inlv.org> *
|
||||
* Johnothan King <johnothanking@protonmail.com> *
|
||||
+* Vincent Mihalkovic <vmihalko@redhat.com> *
|
||||
* *
|
||||
***********************************************************************/
|
||||
/*
|
||||
@@ -437,7 +438,7 @@ int job_reap(int sig)
|
||||
pw->p_flag &= ~P_NOTIFY;
|
||||
if(job.jobcontrol && pid==pw->p_fgrp && pid==tcgetpgrp(JOBTTY))
|
||||
{
|
||||
- px = job_byjid((int)pw->p_job);
|
||||
+ px = job_byjid(pw->p_job);
|
||||
for(; px && (px->p_flag&P_DONE); px=px->p_nxtproc);
|
||||
if(!px)
|
||||
tcsetpgrp(JOBTTY,job.mypid);
|
||||
@@ -1528,7 +1529,7 @@ int job_switch(struct process *pw,int bgflag)
|
||||
{
|
||||
const char *msg;
|
||||
job_lock();
|
||||
- if(!pw || !(pw=job_byjid((int)pw->p_job)))
|
||||
+ if(!pw || !(pw=job_byjid(pw->p_job)))
|
||||
{
|
||||
job_unlock();
|
||||
return 1;
|
||||
@@ -1542,7 +1543,7 @@ int job_switch(struct process *pw,int bgflag)
|
||||
}
|
||||
if(bgflag=='b')
|
||||
{
|
||||
- sfprintf(outfile,"[%d]\t",(int)pw->p_job);
|
||||
+ sfprintf(outfile,"[%d]\t",pw->p_job);
|
||||
sh.bckpid = pw->p_pid;
|
||||
pw->p_flag |= P_BG;
|
||||
msg = "&";
|
||||
@@ -1623,7 +1624,7 @@ static struct process *job_unpost(struct process *pwtop,int notify)
|
||||
sfprintf(sfstderr,"ksh: job line %4d: drop PID=%lld critical=%d PID=%d env=%u\n",__LINE__,(Sflong_t)sh.current_pid,job.in_critical,pwtop->p_pid,pwtop->p_env);
|
||||
sfsync(sfstderr);
|
||||
#endif /* DEBUG */
|
||||
- pwtop = pw = job_byjid((int)pwtop->p_job);
|
||||
+ pwtop = pw = job_byjid(pwtop->p_job);
|
||||
if(!pw)
|
||||
return NULL;
|
||||
#if SHOPT_BGX
|
||||
@@ -1664,7 +1665,7 @@ static struct process *job_unpost(struct process *pwtop,int notify)
|
||||
sfprintf(sfstderr,"ksh: job line %4d: free PID=%lld critical=%d job=%d\n",__LINE__,(Sflong_t)sh.current_pid,job.in_critical,pwtop->p_job);
|
||||
sfsync(sfstderr);
|
||||
#endif /* DEBUG */
|
||||
- job_free((int)pwtop->p_job);
|
||||
+ job_free(pwtop->p_job);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
38
SOURCES/ksh-1.0.10-sigpipe.patch
Normal file
38
SOURCES/ksh-1.0.10-sigpipe.patch
Normal file
@ -0,0 +1,38 @@
|
||||
From bc56018765163a8059600f5205e9e2b1f4059873 Mon Sep 17 00:00:00 2001
|
||||
From: Martijn Dekker <martijn@inlv.org>
|
||||
Date: Sat, 20 Jul 2024 01:40:35 +0100
|
||||
Subject: [PATCH] Re-fix SIGPIPE subshell regression (re: 227c6379, 4df6d674)
|
||||
|
||||
It was committed prematurely and still broken on most systems.
|
||||
|
||||
src/cmd/ksh93/sh/fault.c: sh_done():
|
||||
- Revert changes.
|
||||
|
||||
src/cmd/ksh93/sh/jobs.c: job_wait():
|
||||
- Do not set sh.chldexitsig in the first place if the signal is
|
||||
SIGPIPE and we're in a real subshell.
|
||||
|
||||
This workaround passes all the tests I can throw at it.
|
||||
|
||||
Resolves: https://github.com/ksh93/ksh/issues/765
|
||||
---
|
||||
src/cmd/ksh93/sh/jobs.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/cmd/ksh93/sh/jobs.c b/src/cmd/ksh93/sh/jobs.c
|
||||
index f8c4d5f..580dae0 100644
|
||||
--- a/src/cmd/ksh93/sh/jobs.c
|
||||
+++ b/src/cmd/ksh93/sh/jobs.c
|
||||
@@ -1447,7 +1447,8 @@ int job_wait(pid_t pid)
|
||||
if(px->p_flag&P_SIGNALLED)
|
||||
{
|
||||
sh.exitval |= SH_EXITSIG;
|
||||
- sh.chldexitsig = 1;
|
||||
+ if(!(sh.realsubshell && px->p_exit==SIGPIPE))
|
||||
+ sh.chldexitsig = 1;
|
||||
}
|
||||
if(intr)
|
||||
px->p_flag &= ~P_EXITSAVE;
|
||||
--
|
||||
2.50.0
|
||||
|
||||
264
SOURCES/ksh-1.0.11-segfault-sigwinch.patch
Normal file
264
SOURCES/ksh-1.0.11-segfault-sigwinch.patch
Normal file
@ -0,0 +1,264 @@
|
||||
From b533bc2feb9a1b58b9cdb3a9f5bc94f4ff060a84 Mon Sep 17 00:00:00 2001
|
||||
From: Martijn Dekker <martijn@inlv.org>
|
||||
Date: Fri, 28 Mar 2025 02:59:46 +0000
|
||||
Subject: [PATCH] Fix segfault upon SIGWINCH after 'stty -echo' (re: 83630f9d)
|
||||
|
||||
After disabling terminal echo (stty -echo), ksh either crashes or
|
||||
writes garbage to the terminal upon resizing the terminal window.
|
||||
This also affects the use of ksh for 'M-x shell' in emacs.
|
||||
|
||||
Analysis: The ed_viread and ed_emacsread functions declare buffers
|
||||
as local (automatic) variables that are destroyed when the function
|
||||
exits, but other functions then access then using globally declared
|
||||
pointers in structs of type Edit_t, Emacs_t and Vi_t.
|
||||
|
||||
However, upon 'stty -echo', the terminal cannot be set to raw mode,
|
||||
so the tty_raw call fails in these two functions. At this point,
|
||||
they fall back to ed_read and return, never initialising those
|
||||
pointers. But the SIGWINCH handling routine in edit.c calls redraw
|
||||
routines that depend on those pointers being valid -- and crash.
|
||||
|
||||
src/cmd/ksh93/edit/emacs.c: ed_emacsread():
|
||||
- Attempt to set raw mode before doing or initialising anything
|
||||
else: move the tty_raw call and ed_read fallback to the start.
|
||||
This avoids superfluous init and makes more sense.
|
||||
- Before returning, reset all global pointers that point to this
|
||||
function call's local variables to NULL. (To aid with this, use a
|
||||
'done' goto label and an 'r' variable for the return code.) This
|
||||
ensures these pointers will be either valid or NULL, making
|
||||
debugging easier, as well as allowing the code to check for this.
|
||||
|
||||
src/cmd/ksh93/edit/vi.c: ed_viread():
|
||||
- Same changes as for emacs.
|
||||
|
||||
src/cmd/ksh93/edit/edit.c: ed_read():
|
||||
- If e_prompt is NULL, that is now an indication that ed_emacsread
|
||||
or ed_viread are not being used because the tty_raw call failed;
|
||||
therefore, skip SIGWINCH handling, except for flushing the notify
|
||||
buffer (see 667034ff). This fixes the crash.
|
||||
|
||||
Thanks to @nickpapadonis for the report.
|
||||
Resolves: https://github.com/ksh93/ksh/issues/827
|
||||
---
|
||||
src/cmd/ksh93/edit/edit.c | 22 ++++++++++++++++++----
|
||||
src/cmd/ksh93/edit/emacs.c | 27 ++++++++++++++++-----------
|
||||
src/cmd/ksh93/edit/vi.c | 38 +++++++++++++++-----------------------
|
||||
3 files changed, 49 insertions(+), 38 deletions(-)
|
||||
|
||||
diff --git a/src/cmd/ksh93/edit/edit.c b/src/cmd/ksh93/edit/edit.c
|
||||
index 1dcef1b..846c0d8 100644
|
||||
--- a/src/cmd/ksh93/edit/edit.c
|
||||
+++ b/src/cmd/ksh93/edit/edit.c
|
||||
@@ -690,6 +690,16 @@ static void ed_nputchar(Edit_t *ep, int n, int c)
|
||||
}
|
||||
#endif /* SHOPT_ESH || SHOPT_VSH */
|
||||
|
||||
+/*
|
||||
+ * Show any buffered 'set -b' job notification(s)
|
||||
+ */
|
||||
+static void flush_notifybuf(void)
|
||||
+{
|
||||
+ char *cp;
|
||||
+ if(sh.notifybuf && (cp = sfstruse(sh.notifybuf)) && *cp)
|
||||
+ sfputr(sfstderr, cp, -1);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Do read, restart on interrupt unless SH_SIGSET or SH_SIGTRAP is set
|
||||
* Use select(2) (via sfpkrd()) to wait for input if possible
|
||||
@@ -729,7 +739,12 @@ int ed_read(void *context, int fd, char *buff, int size, int reedit)
|
||||
if(sh.winch && sh_editor_active() && sh_isstate(SH_INTERACTIVE))
|
||||
{
|
||||
int n, newsize;
|
||||
- char *cp;
|
||||
+ if(!ep->e_prompt)
|
||||
+ {
|
||||
+ /* ed_emacsread or ed_viread was unable to put the tty in raw mode */
|
||||
+ flush_notifybuf();
|
||||
+ goto skipwinch;
|
||||
+ }
|
||||
sh_winsize(NULL,&newsize);
|
||||
ed_putchar(ep,'\r');
|
||||
/*
|
||||
@@ -751,9 +766,7 @@ int ed_read(void *context, int fd, char *buff, int size, int reedit)
|
||||
ed_putchar(ep,'\r');
|
||||
}
|
||||
ed_flush(ep);
|
||||
- /* show any buffered 'set -b' job notification(s) */
|
||||
- if(sh.notifybuf && (cp = sfstruse(sh.notifybuf)) && *cp)
|
||||
- sfputr(sfstderr, cp, -1);
|
||||
+ flush_notifybuf();
|
||||
/* update window size */
|
||||
ep->e_winsz = newsize-1;
|
||||
if(ep->e_winsz < MINWINDOW)
|
||||
@@ -777,6 +790,7 @@ int ed_read(void *context, int fd, char *buff, int size, int reedit)
|
||||
emacs_redraw(ep->e_emacs);
|
||||
#endif /* SHOPT_ESH && SHOPT_VSH */
|
||||
}
|
||||
+ skipwinch:
|
||||
#endif /* SHOPT_ESH || SHOPT_VSH */
|
||||
sh.winch = 0;
|
||||
/* an interrupt that should be ignored */
|
||||
diff --git a/src/cmd/ksh93/edit/emacs.c b/src/cmd/ksh93/edit/emacs.c
|
||||
index 1dd6023..128e592 100644
|
||||
--- a/src/cmd/ksh93/edit/emacs.c
|
||||
+++ b/src/cmd/ksh93/edit/emacs.c
|
||||
@@ -185,6 +185,7 @@ int ed_emacsread(void *context, int fd,char *buff,int scend, int reedit)
|
||||
Edit_t *ed = (Edit_t*)context;
|
||||
int c;
|
||||
int i;
|
||||
+ int r = -1; /* return code */
|
||||
genchar *out;
|
||||
int count;
|
||||
Emacs_t *ep = ed->e_emacs;
|
||||
@@ -194,6 +195,10 @@ int ed_emacsread(void *context, int fd,char *buff,int scend, int reedit)
|
||||
genchar *kptr;
|
||||
char prompt[PRSIZE];
|
||||
genchar Screen[MAXLINE];
|
||||
+ /* Set raw mode */
|
||||
+ if(tty_raw(ERRIO,0) < 0)
|
||||
+ return reedit ? reedit : ed_read(context, fd, buff, scend, 0);
|
||||
+ /* Initialize some things */
|
||||
memset(Screen,0,sizeof(Screen));
|
||||
if(!ep)
|
||||
{
|
||||
@@ -206,10 +211,6 @@ int ed_emacsread(void *context, int fd,char *buff,int scend, int reedit)
|
||||
ep->screen = Screen;
|
||||
ep->lastdraw = FINAL;
|
||||
ep->ehist = 0;
|
||||
- if(tty_raw(ERRIO,0) < 0)
|
||||
- {
|
||||
- return reedit ? reedit : ed_read(context,fd,buff,scend,0);
|
||||
- }
|
||||
raw = 1;
|
||||
/* This mess in case the read system call fails */
|
||||
ed_setup(ep->ed,fd,reedit);
|
||||
@@ -240,6 +241,7 @@ int ed_emacsread(void *context, int fd,char *buff,int scend, int reedit)
|
||||
}
|
||||
ep->in_mult = hloff; /* save pos in last command */
|
||||
#endif /* ESH_NFIRST */
|
||||
+ /* Handle user interrupt, user quit, or EOF */
|
||||
i = sigsetjmp(env,0);
|
||||
if (i !=0)
|
||||
{
|
||||
@@ -251,10 +253,8 @@ int ed_emacsread(void *context, int fd,char *buff,int scend, int reedit)
|
||||
}
|
||||
tty_cooked(ERRIO);
|
||||
if (i == UEOF)
|
||||
- {
|
||||
- return 0; /* EOF */
|
||||
- }
|
||||
- return -1; /* some other error */
|
||||
+ r = 0; /* EOF */
|
||||
+ goto done;
|
||||
}
|
||||
out[reedit] = 0;
|
||||
if(scend+plen > (MAXLINE-2))
|
||||
@@ -349,7 +349,8 @@ int ed_emacsread(void *context, int fd,char *buff,int scend, int reedit)
|
||||
case EOFCHAR:
|
||||
ed_flush(ep->ed);
|
||||
tty_cooked(ERRIO);
|
||||
- return 0;
|
||||
+ r = 0;
|
||||
+ goto done;
|
||||
#ifdef u370
|
||||
case cntl('S') :
|
||||
case cntl('Q') :
|
||||
@@ -754,8 +755,12 @@ process:
|
||||
#endif /* SHOPT_MULTIBYTE */
|
||||
i = (int)strlen(buff);
|
||||
if (i)
|
||||
- return i;
|
||||
- return -1;
|
||||
+ r = i;
|
||||
+done:
|
||||
+ /* avoid leaving invalid pointers to destroyed automatic variables */
|
||||
+ Prompt = NULL;
|
||||
+ drawbuff = ep->screen = ep->cursor = NULL;
|
||||
+ return r;
|
||||
}
|
||||
|
||||
static void show_info(Emacs_t *ep,const char *str)
|
||||
diff --git a/src/cmd/ksh93/edit/vi.c b/src/cmd/ksh93/edit/vi.c
|
||||
index 0e878df..fac40ee 100644
|
||||
--- a/src/cmd/ksh93/edit/vi.c
|
||||
+++ b/src/cmd/ksh93/edit/vi.c
|
||||
@@ -208,6 +208,7 @@ int ed_viread(void *context, int fd, char *shbuf, int nchar, int reedit)
|
||||
{
|
||||
Edit_t *ed = (Edit_t*)context;
|
||||
int i; /* general variable */
|
||||
+ int r = -1; /* return value */
|
||||
int term_char=0; /* read() termination character */
|
||||
Vi_t *vp = ed->e_vi;
|
||||
char prompt[PRSIZE+2]; /* prompt */
|
||||
@@ -218,6 +219,10 @@ int ed_viread(void *context, int fd, char *shbuf, int nchar, int reedit)
|
||||
int Globals[9]; /* local global variables */
|
||||
int esc_or_hang=0; /* <ESC> or hangup */
|
||||
char cntl_char=0; /* TRUE if control character present */
|
||||
+
|
||||
+ if( tty_raw(ERRIO,0) < 0 )
|
||||
+ return reedit ? reedit : ed_read(context, fd, shbuf, nchar, 0);
|
||||
+
|
||||
if(!vp)
|
||||
{
|
||||
ed->e_vi = vp = sh_newof(0,Vi_t,1,0);
|
||||
@@ -232,16 +237,9 @@ int ed_viread(void *context, int fd, char *shbuf, int nchar, int reedit)
|
||||
ed_setup(vp->ed,fd, reedit);
|
||||
shbuf[reedit] = 0;
|
||||
|
||||
- {
|
||||
- /*** Set raw mode ***/
|
||||
-
|
||||
- if(tty_raw(ERRIO,0) < 0 )
|
||||
- return reedit ? reedit : ed_read(context, fd, shbuf, nchar,0);
|
||||
- i = last_virt-1;
|
||||
- }
|
||||
-
|
||||
/*** Initialize some things ***/
|
||||
|
||||
+ i = last_virt-1;
|
||||
virtual = (genchar*)shbuf;
|
||||
#if SHOPT_MULTIBYTE
|
||||
virtual = (genchar*)roundof((char*)virtual-(char*)0,sizeof(genchar));
|
||||
@@ -307,18 +305,9 @@ int ed_viread(void *context, int fd, char *shbuf, int nchar, int reedit)
|
||||
}
|
||||
virtual[0] = '\0';
|
||||
tty_cooked(ERRIO);
|
||||
-
|
||||
- switch(i)
|
||||
- {
|
||||
- case UEOF:
|
||||
- /*** EOF ***/
|
||||
- return 0;
|
||||
-
|
||||
- case UINTR:
|
||||
- /** interrupt **/
|
||||
- return -1;
|
||||
- }
|
||||
- return -1;
|
||||
+ if (i == UEOF)
|
||||
+ r = 0; /* EOF */
|
||||
+ goto done;
|
||||
}
|
||||
|
||||
/*** Get a line from the terminal ***/
|
||||
@@ -363,10 +352,13 @@ int ed_viread(void *context, int fd, char *shbuf, int nchar, int reedit)
|
||||
if(vp->ed->nhlist)
|
||||
ed_histlist(vp->ed,0);
|
||||
#endif /* SHOPT_EDPREDICT */
|
||||
- return last_virt;
|
||||
+ r = last_virt;
|
||||
}
|
||||
- else
|
||||
- return -1;
|
||||
+done:
|
||||
+ /* avoid leaving invalid pointers to destroyed automatic variables */
|
||||
+ Prompt = NULL;
|
||||
+ virtual = physical = window = vp->U_space = vp->u_space = NULL;
|
||||
+ return r;
|
||||
}
|
||||
|
||||
|
||||
--
|
||||
2.49.0
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
From e8554b5131fc32b26a6a0b0ab5cf24839e30161a Mon Sep 17 00:00:00 2001
|
||||
From 4350174a5d4acabf78f97b28c6d0ae68ec703e78 Mon Sep 17 00:00:00 2001
|
||||
From: Martijn Dekker <martijn@inlv.org>
|
||||
Date: Sun, 30 Mar 2025 00:14:35 +0000
|
||||
Subject: [PATCH] Fix 'stty -echo' in scripts (re: 41ebb55a)
|
||||
@ -56,14 +56,14 @@ src/cmd/ksh93/sh/jobs.c: job_wait():
|
||||
|
||||
Resolves: https://github.com/ksh93/ksh/issues/836
|
||||
---
|
||||
src/cmd/ksh93/sh/jobs.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
src/cmd/ksh93/sh/jobs.c | 4 ++--
|
||||
1 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/cmd/ksh93/sh/jobs.c b/src/cmd/ksh93/sh/jobs.c
|
||||
index be333b2..081e73a 100644
|
||||
index c65bc6e66094..513afb5582ab 100644
|
||||
--- a/src/cmd/ksh93/sh/jobs.c
|
||||
+++ b/src/cmd/ksh93/sh/jobs.c
|
||||
@@ -1492,9 +1492,9 @@ int job_wait(pid_t pid)
|
||||
@@ -1420,9 +1420,9 @@ int job_wait(pid_t pid)
|
||||
kill(sh.current_pid,SIGTSTP);
|
||||
}
|
||||
}
|
||||
@ -75,6 +75,3 @@ index be333b2..081e73a 100644
|
||||
{
|
||||
if(pw->p_pgrp==0)
|
||||
pw->p_pgrp = pw->p_pid;
|
||||
--
|
||||
2.47.3
|
||||
|
||||
807
SOURCES/ksh-1.0.12-security.patch
Normal file
807
SOURCES/ksh-1.0.12-security.patch
Normal file
@ -0,0 +1,807 @@
|
||||
From 970812e39c236ff385e440ac6d458d196c237667 Mon Sep 17 00:00:00 2001
|
||||
From: Johnothan King <johnothanking@protonmail.com>
|
||||
Date: Fri, 13 Jun 2025 16:29:15 -0700
|
||||
Subject: [PATCH] Fix arbitrary command execution/code injection bugs (#866)
|
||||
|
||||
* Security patch part 1
|
||||
|
||||
Never use $SHELL or sh.shpath when executing shebang-less scripts
|
||||
|
||||
- sh_ntfork(): Removed a misguided optimization that causes ksh to
|
||||
run scripts without a shebang using the binary pointed to by
|
||||
either $SHELL or sh.shpath. This has a few problems:
|
||||
- The shell in sh.shpath or more disastrously in $SHELL has
|
||||
no guarantee of being identical to the currently running
|
||||
copy of ksh93 or even existing at all, so using either is
|
||||
not only bogus, but potentially dangerous.
|
||||
- The optimization has no ability to pass down the current
|
||||
POSIX mode status to the script.
|
||||
- It's only activated for virtual subshells, resulting in
|
||||
arbitrarily different behavior depending on whether or
|
||||
not we're in a virtual subshell.
|
||||
- It does some weird stuff with /dev/fd that seems superfluous,
|
||||
and also lacks any SHOPT_DEVFD if directive. (Additionally,
|
||||
if it did have one, that stat(2) would likely become mere
|
||||
dead code and a waste of context switches.)
|
||||
|
||||
The optimization was probably intended to be used for running a
|
||||
shebang-less script via posix_spawn, which is ostensibly faster
|
||||
than fork. But this simply isn't possible without risking running
|
||||
the shebang-less script in a shell environment different from
|
||||
the current one. (If ksh were updated by the package manager
|
||||
while ksh is still running, this optimization would cause the
|
||||
script to run via the new version, rather than the currently
|
||||
running older version.) The optimization is unfixable by design,
|
||||
and as such must be removed to ensure correct behavior.
|
||||
|
||||
* Security patch part 2 (re: bae02c39)
|
||||
|
||||
rm setuid script code leading to arbitrary command execution
|
||||
|
||||
Changes:
|
||||
- Delete code for setuid scripts on "Solaris 2.5+" because it
|
||||
allows for arbitrary command execution. One millisecond you think
|
||||
you're launching ksh, the next you're at the mercy of a hijacker.
|
||||
Example:
|
||||
SHELL=/bin/ppmflash /bin/ksh -l /dev/fd/0 < <(true)
|
||||
MANPATH: usage: MANPATH flashfactor [ppmfile]
|
||||
flashfactor: 0.0 = original picture, 1.0 = total whiteout
|
||||
The pathshell() code doesn't *seem* to be vulnerable to privilege
|
||||
escalation, but who knows (cf. CVE-2019-14868; this might need its
|
||||
own CVE 2025. Maybe pathshell() should be scrapped entirely???)
|
||||
- Add fickle but functional regression test (you may need to pass
|
||||
KSH=/bin/ksh or some such to get it to fail against vulnerable
|
||||
versions of ksh). The test uses a login shell via the -l option,
|
||||
but the bug *does not* need a login shell. See:
|
||||
https://github.com/ksh93/ksh/issues/874#issue-3128739066
|
||||
Modify the execveat reproducer to pass along environ (which
|
||||
could include a hijacked SHELL), and you're in for a BAD time.
|
||||
|
||||
Maybe the deleted code (introduced sometime within the period of 1995
|
||||
and 1999) was relevant to some Solaris-specific use case or something.
|
||||
Maybe the erasure even causes an incompatibility. But that code must
|
||||
go; it's far too dangerous to execv whatever the hell pathshell gives
|
||||
us during **init**. (Need I bring CVE-2019-14868 back to remembrance
|
||||
again? This bug has similarities to that one.)
|
||||
|
||||
FWIW, all of the regression tests in the ksh and modernish suites pass
|
||||
with this patch applied.
|
||||
|
||||
* Security patch part 3
|
||||
|
||||
Delete pathshell() and replace uses of it with safer equivalents
|
||||
|
||||
This function is a dangerous attack vector that ought not remain
|
||||
in the code base. The value returned by astconf() is doubtless
|
||||
safer than what is returned by pathshell().
|
||||
|
||||
* Other changes
|
||||
|
||||
The libast pathprog function and prog feature test are now unused,
|
||||
and are removed.
|
||||
---
|
||||
src/cmd/ksh93/include/shell.h | 3 -
|
||||
src/cmd/ksh93/sh/init.c | 33 +--------
|
||||
src/cmd/ksh93/sh/main.c | 21 ------
|
||||
src/cmd/ksh93/sh/path.c | 2 -
|
||||
src/cmd/ksh93/sh/xec.c | 20 ------
|
||||
src/cmd/ksh93/tests/basic.sh | 28 ++++++++
|
||||
src/lib/libast/Mamfile | 29 +-------
|
||||
src/lib/libast/comp/omitted.c | 2 +-
|
||||
src/lib/libast/comp/system.c | 48 -------------
|
||||
src/lib/libast/features/prog | 12 ----
|
||||
src/lib/libast/include/ast.h | 2 -
|
||||
src/lib/libast/man/compat.3 | 1 -
|
||||
src/lib/libast/man/path.3 | 13 ----
|
||||
src/lib/libast/man/proc.3 | 5 +-
|
||||
src/lib/libast/misc/cmdarg.c | 2 +-
|
||||
src/lib/libast/misc/procopen.c | 2 +-
|
||||
src/lib/libast/path/pathprog.c | 124 --------------------------------
|
||||
src/lib/libast/path/pathshell.c | 115 -----------------------------
|
||||
18 files changed, 37 insertions(+), 425 deletions(-)
|
||||
delete mode 100644 src/lib/libast/comp/system.c
|
||||
delete mode 100644 src/lib/libast/features/prog
|
||||
delete mode 100644 src/lib/libast/path/pathprog.c
|
||||
delete mode 100644 src/lib/libast/path/pathshell.c
|
||||
|
||||
diff --git a/src/cmd/ksh93/include/shell.h b/src/cmd/ksh93/include/shell.h
|
||||
index 0613ceb..9a1b00e 100644
|
||||
--- a/src/cmd/ksh93/include/shell.h
|
||||
+++ b/src/cmd/ksh93/include/shell.h
|
||||
@@ -213,8 +213,6 @@ struct sh_scoped
|
||||
char **otrapcom; /* save parent EXIT and signals for v=$(trap) */
|
||||
void *timetrap;
|
||||
struct Ufunction *real_fun; /* current 'function name' function */
|
||||
- int repl_index;
|
||||
- char *repl_arg;
|
||||
};
|
||||
|
||||
struct limits
|
||||
@@ -255,7 +253,6 @@ struct Shell_s
|
||||
Namval_t *bltin_nodes;
|
||||
Namval_t *bltin_cmds;
|
||||
History_t *hist_ptr;
|
||||
- char *shpath;
|
||||
char *user;
|
||||
char **sigmsg;
|
||||
char **login_files;
|
||||
diff --git a/src/cmd/ksh93/sh/init.c b/src/cmd/ksh93/sh/init.c
|
||||
index f4daaac..58c4e09 100644
|
||||
--- a/src/cmd/ksh93/sh/init.c
|
||||
+++ b/src/cmd/ksh93/sh/init.c
|
||||
@@ -1355,33 +1355,6 @@ Shell_t *sh_init(int argc,char *argv[], Shinit_f userinit)
|
||||
}
|
||||
sh.shlvl++;
|
||||
nv_offattr(SHLVL,NV_IMPORT);
|
||||
-#if SHOPT_SPAWN
|
||||
- {
|
||||
- /*
|
||||
- * try to find the pathname for this interpreter
|
||||
- * try using environment variable _ or argv[0]
|
||||
- */
|
||||
- char *cp=nv_getval(L_ARGNOD);
|
||||
- char buff[PATH_MAX+1];
|
||||
- sh.shpath = 0;
|
||||
- if((n = pathprog(NULL, buff, sizeof(buff))) > 0 && n <= sizeof(buff))
|
||||
- sh.shpath = sh_strdup(buff);
|
||||
- else if((cp && (sh_type(cp)&SH_TYPE_SH)) || (argc>0 && strchr(cp= *argv,'/')))
|
||||
- {
|
||||
- if(*cp=='/')
|
||||
- sh.shpath = sh_strdup(cp);
|
||||
- else if(cp = nv_getval(PWDNOD))
|
||||
- {
|
||||
- int offset = stktell(sh.stk);
|
||||
- sfputr(sh.stk,cp,'/');
|
||||
- sfputr(sh.stk,argv[0],-1);
|
||||
- pathcanon(stkptr(sh.stk,offset),PATH_DOTDOT);
|
||||
- sh.shpath = sh_strdup(stkptr(sh.stk,offset));
|
||||
- stkseek(sh.stk,offset);
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
-#endif
|
||||
nv_putval(IFSNOD,(char*)e_sptbnl,NV_RDONLY);
|
||||
astconfdisc(newconf);
|
||||
#if SHOPT_TIMEOUT
|
||||
@@ -1394,7 +1367,6 @@ Shell_t *sh_init(int argc,char *argv[], Shinit_f userinit)
|
||||
#endif
|
||||
if(argc>0)
|
||||
{
|
||||
- int dolv_index;
|
||||
/* check for restricted shell */
|
||||
if(type&SH_TYPE_RESTRICTED)
|
||||
sh_onoption(SH_RESTRICTED);
|
||||
@@ -1406,10 +1378,7 @@ Shell_t *sh_init(int argc,char *argv[], Shinit_f userinit)
|
||||
sh_done(0);
|
||||
}
|
||||
opt_info.disc = 0;
|
||||
- dolv_index = (argc - 1) - sh.st.dolc;
|
||||
- sh.st.dolv = argv + dolv_index;
|
||||
- sh.st.repl_index = dolv_index;
|
||||
- sh.st.repl_arg = argv[dolv_index];
|
||||
+ sh.st.dolv = argv + (argc - 1) - sh.st.dolc;
|
||||
sh.st.dolv[0] = argv[0];
|
||||
if(sh.st.dolc < 1)
|
||||
{
|
||||
diff --git a/src/cmd/ksh93/sh/main.c b/src/cmd/ksh93/sh/main.c
|
||||
index 38ae366..712310e 100644
|
||||
--- a/src/cmd/ksh93/sh/main.c
|
||||
+++ b/src/cmd/ksh93/sh/main.c
|
||||
@@ -247,33 +247,12 @@ int sh_main(int ac, char *av[], Shinit_f userinit)
|
||||
/* open stream should have been passed into shell */
|
||||
if(strmatch(name,e_devfdNN))
|
||||
{
|
||||
-#if !_WINIX
|
||||
- char *cp;
|
||||
- int type;
|
||||
-#endif
|
||||
fdin = (int)strtol(name+8, NULL, 10);
|
||||
if(fstat(fdin,&statb)<0)
|
||||
{
|
||||
errormsg(SH_DICT,ERROR_system(1),e_open,name);
|
||||
UNREACHABLE();
|
||||
}
|
||||
-#if !_WINIX
|
||||
- /*
|
||||
- * try to undo effect of Solaris 2.5+
|
||||
- * change for argv for setuid scripts
|
||||
- */
|
||||
- if(sh.st.repl_index > 0)
|
||||
- av[sh.st.repl_index] = sh.st.repl_arg;
|
||||
- if(((type = sh_type(cp = av[0])) & SH_TYPE_SH) && (name = nv_getval(L_ARGNOD)) && (!((type = sh_type(cp = name)) & SH_TYPE_SH)))
|
||||
- {
|
||||
- av[0] = (type & SH_TYPE_LOGIN) ? cp : path_basename(cp);
|
||||
- /* exec to change $0 for ps */
|
||||
- execv(pathshell(),av);
|
||||
- /* exec fails */
|
||||
- sh.st.dolv[0] = av[0];
|
||||
- fixargs(sh.st.dolv,1);
|
||||
- }
|
||||
-#endif
|
||||
name = av[0];
|
||||
sh_offoption(SH_VERBOSE);
|
||||
sh_offoption(SH_XTRACE);
|
||||
diff --git a/src/cmd/ksh93/sh/path.c b/src/cmd/ksh93/sh/path.c
|
||||
index 85f44b5..7728df0 100644
|
||||
--- a/src/cmd/ksh93/sh/path.c
|
||||
+++ b/src/cmd/ksh93/sh/path.c
|
||||
@@ -1195,8 +1195,6 @@ pid_t path_spawn(const char *opath,char **argv, char **envp, Pathcomp_t *libpath
|
||||
errno = ENOEXEC;
|
||||
if(spawn)
|
||||
{
|
||||
- if(sh.subshell)
|
||||
- return -1;
|
||||
do
|
||||
{
|
||||
if((pid=fork())>0)
|
||||
diff --git a/src/cmd/ksh93/sh/xec.c b/src/cmd/ksh93/sh/xec.c
|
||||
index ca67142..003a93c 100644
|
||||
--- a/src/cmd/ksh93/sh/xec.c
|
||||
+++ b/src/cmd/ksh93/sh/xec.c
|
||||
@@ -3417,26 +3417,6 @@ static pid_t sh_ntfork(const Shnode_t *t,char *argv[],int *jobid,int topfd)
|
||||
job_fork(-1);
|
||||
jobfork = 1;
|
||||
spawnpid = path_spawn(path,argv,arge,pp,(grp<<1)|1);
|
||||
- if(spawnpid < 0 && errno==ENOEXEC)
|
||||
- {
|
||||
- char *devfd;
|
||||
- int fd = open(path,O_RDONLY);
|
||||
- argv[-1] = argv[0];
|
||||
- argv[0] = path;
|
||||
- if(fd>=0)
|
||||
- {
|
||||
- struct stat statb;
|
||||
- sfprintf(sh.strbuf,"/dev/fd/%d",fd);
|
||||
- if(stat(devfd=sfstruse(sh.strbuf),&statb)>=0)
|
||||
- argv[0] = devfd;
|
||||
- }
|
||||
- if(!sh.shpath)
|
||||
- sh.shpath = pathshell();
|
||||
- spawnpid = path_spawn(sh.shpath,&argv[-1],arge,pp,(grp<<1)|1);
|
||||
- if(fd>=0)
|
||||
- close(fd);
|
||||
- argv[0] = argv[-1];
|
||||
- }
|
||||
fail:
|
||||
if(jobfork && spawnpid<0)
|
||||
job_fork(-2);
|
||||
diff --git a/src/cmd/ksh93/tests/basic.sh b/src/cmd/ksh93/tests/basic.sh
|
||||
index ea83b6b..0b02f7c 100755
|
||||
--- a/src/cmd/ksh93/tests/basic.sh
|
||||
+++ b/src/cmd/ksh93/tests/basic.sh
|
||||
@@ -1019,5 +1019,33 @@ do
|
||||
done
|
||||
unset testcode
|
||||
|
||||
+# ======
|
||||
+# Hijacking ksh93 via $SHELL for arbitrary command execution during initialization.
|
||||
+# https://github.com/ksh93/ksh/issues/874
|
||||
+bindir=$tmp/dir.$RANDOM/bin
|
||||
+mkdir -p "$bindir"
|
||||
+echo $'#!/bin/sh\necho "CODE INJECTION"' > "$bindir"/hijack_sh
|
||||
+chmod +x "$bindir"/hijack_sh
|
||||
+got=$(set +x; SHELL="$bindir"/hijack_sh "$SHELL" -l <(echo) 2>&1)
|
||||
+[[ $got =~ "CODE INJECTION" ]] && err_exit 'ksh93 is vulnerable to being hijacked during init via $SHELL' \
|
||||
+ "(got $(printf %q "$got"))"
|
||||
+
|
||||
+# Hijacking ksh93 shebang-less scripts for arbitrary command execution.
|
||||
+# https://github.com/ksh93/ksh/pull/866
|
||||
+export bindir
|
||||
+print 'echo GOOD' > "$bindir/dummy.sh"
|
||||
+chmod +x "$bindir/dummy.sh"
|
||||
+cp "$SHELL" "$bindir/hijack_sh"
|
||||
+exp=$'GOOD\nGOOD'
|
||||
+got=$("$bindir/hijack_sh" -c $'print $\'\#!/bin/sh\necho HIJACKED\' > "$bindir/hijack_shell"
|
||||
+chmod +x "$bindir/hijack_shell"
|
||||
+rm "$bindir/hijack_sh"
|
||||
+cp "$bindir/hijack_shell" "$bindir/hijack_sh"
|
||||
+("$bindir/dummy.sh"); "$bindir/dummy.sh"; :')
|
||||
+rm -r "$bindir"
|
||||
+unset bindir
|
||||
+[[ $exp == $got ]] || err_exit 'ksh93 shebang-less scripts are vulnerable to being hijacked for arbitrary code execution' \
|
||||
+ "(exp $(printf %q "$exp"), got $(printf %q "$got"))"
|
||||
+
|
||||
# ======
|
||||
exit $((Errors<125?Errors:125))
|
||||
diff --git a/src/lib/libast/Mamfile b/src/lib/libast/Mamfile
|
||||
index 0a35576..047ab0c 100644
|
||||
--- a/src/lib/libast/Mamfile
|
||||
+++ b/src/lib/libast/Mamfile
|
||||
@@ -972,12 +972,6 @@ make install
|
||||
done path/pathbin.c
|
||||
exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -c path/pathbin.c
|
||||
done pathbin.o generated
|
||||
- make pathshell.o
|
||||
- make path/pathshell.c
|
||||
- prev include/ast.h
|
||||
- done path/pathshell.c
|
||||
- exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -c path/pathshell.c
|
||||
- done pathshell.o generated
|
||||
make pathcd.o
|
||||
make path/pathcd.c
|
||||
make include/stk.h implicit
|
||||
@@ -988,17 +982,6 @@ make install
|
||||
done path/pathcd.c
|
||||
exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -c path/pathcd.c
|
||||
done pathcd.o generated
|
||||
- make pathprog.o
|
||||
- make path/pathprog.c
|
||||
- make FEATURE/prog implicit
|
||||
- prev features/prog
|
||||
- exec - iffe ${IFFEFLAGS} -v -X ast -X std -c "${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS}" run features/prog
|
||||
- done FEATURE/prog generated
|
||||
- prev include/ast_windows.h
|
||||
- prev include/ast.h
|
||||
- done path/pathprog.c
|
||||
- exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -c path/pathprog.c
|
||||
- done pathprog.o generated
|
||||
make ftwalk.o
|
||||
make misc/ftwalk.c
|
||||
make include/ftwalk.h implicit
|
||||
@@ -2574,14 +2557,6 @@ make install
|
||||
done comp/mount.c
|
||||
exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -c comp/mount.c
|
||||
done mount.o generated
|
||||
- make system.o
|
||||
- make comp/system.c
|
||||
- prev ast_map.h
|
||||
- prev include/proc.h
|
||||
- prev include/ast.h
|
||||
- done comp/system.c
|
||||
- exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -c comp/system.c
|
||||
- done system.o generated
|
||||
make iblocks.o
|
||||
make port/iblocks.c
|
||||
prev include/ls.h
|
||||
@@ -4425,9 +4400,9 @@ make install
|
||||
exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -c vmalloc/vmgetmem.c
|
||||
done vmgetmem.o generated
|
||||
exec - ${AR} rc libast.a state.o opendir.o readdir.o rewinddir.o seekdir.o telldir.o getcwd.o fastfind.o hashalloc.o hashdump.o hashfree.o hashlast.o hashlook.o hashscan.o hashsize.o hashview.o hashwalk.o memhash.o memsum.o strhash.o strkey.o strsum.o stracmp.o strnacmp.o ccmap.o ccmapid.o ccnative.o chresc.o chrtoi.o
|
||||
- exec - ${AR} rc libast.a streval.o strexpr.o strmatch.o strcopy.o modei.o modex.o strmode.o strlcat.o strlcpy.o strlook.o strncopy.o strsearch.o strpsearch.o stresc.o stropt.o strtape.o strpcmp.o strnpcmp.o strvcmp.o strnvcmp.o tok.o tokline.o tokscan.o pathaccess.o pathcat.o pathcanon.o pathcheck.o pathpath.o pathexists.o pathfind.o pathicase.o pathkey.o pathprobe.o pathrepl.o pathnative.o pathposix.o pathtemp.o pathtmp.o pathstat.o pathgetlink.o pathsetlink.o pathbin.o pathshell.o pathcd.o pathprog.o ftwalk.o ftwflags.o fts.o astintercept.o conformance.o getenv.o setenviron.o optget.o optjoin.o optesc.o optctx.o strsort.o struniq.o magic.o mime.o mimetype.o signal.o sigflag.o systrace.o error.o errorf.o errormsg.o errorx.o localeconv.o setlocale.o translate.o catopen.o iconv.o lc.o lctab.o mc.o base64.o recfmt.o recstr.o reclen.o fmtrec.o fmtbase.o fmtbuf.o fmtclock.o fmtdev.o fmtelapsed.o fmterror.o fmtesc.o fmtfmt.o fmtfs.o fmtident.o fmtint.o fmtip4.o fmtip6.o fmtls.o fmtmatch.o fmtmode.o fmtnum.o fmtperm.o fmtre.o fmttime.o
|
||||
+ exec - ${AR} rc libast.a streval.o strexpr.o strmatch.o strcopy.o modei.o modex.o strmode.o strlcat.o strlcpy.o strlook.o strncopy.o strsearch.o strpsearch.o stresc.o stropt.o strtape.o strpcmp.o strnpcmp.o strvcmp.o strnvcmp.o tok.o tokline.o tokscan.o pathaccess.o pathcat.o pathcanon.o pathcheck.o pathpath.o pathexists.o pathfind.o pathicase.o pathkey.o pathprobe.o pathrepl.o pathnative.o pathposix.o pathtemp.o pathtmp.o pathstat.o pathgetlink.o pathsetlink.o pathbin.o pathcd.o ftwalk.o ftwflags.o fts.o astintercept.o conformance.o getenv.o setenviron.o optget.o optjoin.o optesc.o optctx.o strsort.o struniq.o magic.o mime.o mimetype.o signal.o sigflag.o systrace.o error.o errorf.o errormsg.o errorx.o localeconv.o setlocale.o translate.o catopen.o iconv.o lc.o lctab.o mc.o base64.o recfmt.o recstr.o reclen.o fmtrec.o fmtbase.o fmtbuf.o fmtclock.o fmtdev.o fmtelapsed.o fmterror.o fmtesc.o fmtfmt.o fmtfs.o fmtident.o fmtint.o fmtip4.o fmtip6.o fmtls.o fmtmatch.o fmtmode.o fmtnum.o fmtperm.o fmtre.o fmttime.o
|
||||
exec - ${AR} rc libast.a fmtuid.o fmtgid.o fmtsignal.o fmtscale.o fmttmx.o fmttv.o fmtversion.o strelapsed.o strperm.o struid.o strgid.o strtoip4.o strtoip6.o stack.o stk.o swapget.o swapmem.o swapop.o swapput.o sigdata.o sigcrit.o sigunblock.o procopen.o procclose.o procrun.o procfree.o tmdate.o tmequiv.o tmfix.o tmfmt.o tmform.o tmgoff.o tminit.o tmleap.o tmlex.o tmlocale.o tmmake.o tmpoff.o tmscan.o tmsleep.o tmtime.o tmtype.o tmweek.o tmword.o tmzone.o tmxdate.o tmxduration.o tmxfmt.o tmxgettime.o tmxleap.o tmxmake.o tmxscan.o tmxsettime.o tmxsleep.o tmxtime.o tmxtouch.o tvcmp.o tvgettime.o tvsettime.o tvsleep.o tvtouch.o cmdarg.o vecargs.o vecfile.o vecfree.o vecload.o vecstring.o univdata.o touch.o mnt.o debug.o memccpy.o memchr.o memcmp.o memcpy.o memdup.o memmove.o memset.o mkdir.o mkfifo.o mknod.o rmdir.o remove.o rename.o link.o unlink.o strdup.o strchr.o strrchr.o strstr.o strtod.o strtold.o strtol.o strtoll.o strtoul.o strtoull.o strton.o strtonll.o strntod.o strntold.o strnton.o
|
||||
- exec - ${AR} rc libast.a strntonll.o strntol.o strntoll.o strntoul.o strntoull.o strcasecmp.o strncasecmp.o strerror.o mktemp.o tmpnam.o fsync.o execlp.o execve.o execvp.o execvpe.o spawnveg.o killpg.o getlogin.o putenv.o setenv.o unsetenv.o lstat.o statvfs.o eaccess.o gross.o omitted.o readlink.o symlink.o getpgrp.o setpgid.o setsid.o fcntl.o open.o atexit.o getdents.o getwd.o dup2.o errno.o getgroups.o mount.o system.o iblocks.o modedata.o tmdata.o memfatal.o sfkeyprintf.o sfdcdio.o sfdcdos.o sfdcfilter.o sfdcseekable.o sfdcslow.o sfdcsubstr.o sfdctee.o sfdcunion.o sfdcmore.o sfdcprefix.o wc.o wc2utf8.o basename.o closelog.o dirname.o fmtmsglib.o fnmatch.o ftw.o getdate.o getsubopt.o glob.o nftw.o openlog.o re_comp.o resolvepath.o realpath.o regcmp.o regexp.o setlogmask.o strftime.o strptime.o swab.o syslog.o tempnam.o wordexp.o mktime.o regalloc.o regclass.o regcoll.o regcomp.o regcache.o regdecomp.o regerror.o regexec.o regfatal.o reginit.o
|
||||
+ exec - ${AR} rc libast.a strntonll.o strntol.o strntoll.o strntoul.o strntoull.o strcasecmp.o strncasecmp.o strerror.o mktemp.o tmpnam.o fsync.o execlp.o execve.o execvp.o execvpe.o spawnveg.o killpg.o getlogin.o putenv.o setenv.o unsetenv.o lstat.o statvfs.o eaccess.o gross.o omitted.o readlink.o symlink.o getpgrp.o setpgid.o setsid.o fcntl.o open.o atexit.o getdents.o getwd.o dup2.o errno.o getgroups.o mount.o iblocks.o modedata.o tmdata.o memfatal.o sfkeyprintf.o sfdcdio.o sfdcdos.o sfdcfilter.o sfdcseekable.o sfdcslow.o sfdcsubstr.o sfdctee.o sfdcunion.o sfdcmore.o sfdcprefix.o wc.o wc2utf8.o basename.o closelog.o dirname.o fmtmsglib.o fnmatch.o ftw.o getdate.o getsubopt.o glob.o nftw.o openlog.o re_comp.o resolvepath.o realpath.o regcmp.o regexp.o setlogmask.o strftime.o strptime.o swab.o syslog.o tempnam.o wordexp.o mktime.o regalloc.o regclass.o regcoll.o regcomp.o regcache.o regdecomp.o regerror.o regexec.o regfatal.o reginit.o
|
||||
exec - ${AR} rc libast.a regnexec.o regsubcomp.o regsubexec.o regsub.o regrecord.o regrexec.o regstat.o dtclose.o dtdisc.o dthash.o dtlist.o dtmethod.o dtopen.o dtstat.o dtstrhash.o dttree.o dtuser.o dtview.o dtwalk.o dtnew.o dtcomp.o sfclose.o sfclrlock.o sfdisc.o sfdlen.o sfexcept.o sfgetl.o sfgetu.o sfcvt.o sfecvt.o sffcvt.o sfextern.o sffilbuf.o sfflsbuf.o sfprints.o sfgetd.o sfgetr.o sfllen.o sfmode.o sfmove.o sfnew.o sfpkrd.o sfnotify.o sfnputc.o sfopen.o sfpeek.o sfpoll.o sfpool.o sfpopen.o sfprintf.o sfputd.o sfputl.o sfputr.o sfputu.o sfrd.o sfread.o sfreserve.o sfscanf.o sfseek.o sfset.o sfsetbuf.o sfsetfd.o sfsize.o sfsk.o sfstack.o sfstrtod.o sfsync.o sfswap.o sftable.o sftell.o sftmp.o sfungetc.o sfvprintf.o sfvscanf.o sfwr.o sfwrite.o sfpurge.o sfraise.o sfwalk.o sfgetm.o sfputm.o sfresize.o _sfclrerr.o _sfeof.o _sferror.o _sffileno.o _sfopen.o _sfstacked.o _sfvalue.o _sfgetc.o _sfgetl.o _sfgetl2.o _sfgetu.o _sfgetu2.o _sfdlen.o _sfllen.o _sfslen.o _sfulen.o _sfputc.o _sfputd.o _sfputl.o _sfputm.o
|
||||
exec - ${AR} rc libast.a _sfputu.o clearerr.o fclose.o fdopen.o fflush.o fgetc.o fgetpos.o fgets.o fopen.o fprintf.o fpurge.o fputs.o fread.o freopen.o fscanf.o fseek.o fseeko.o fsetpos.o ftell.o ftello.o fwrite.o getw.o pclose.o popen.o printf.o putchar.o puts.o putw.o rewind.o scanf.o setbuf.o setbuffer.o setlinebuf.o setvbuf.o snprintf.o sprintf.o sscanf.o asprintf.o vasprintf.o tmpfile.o ungetc.o vfprintf.o vfscanf.o vprintf.o vscanf.o vsnprintf.o vsprintf.o vsscanf.o _doprnt.o _doscan.o _filbuf.o _flsbuf.o _stdopen.o _stdprintf.o _stdscanf.o _stdsprnt.o _stdvbuf.o _stdvsnprnt.o _stdvsprnt.o _stdvsscn.o fgetwc.o fwprintf.o putwchar.o vfwscanf.o wprintf.o fgetws.o fwscanf.o swprintf.o vswprintf.o wscanf.o fputwc.o getwc.o swscanf.o vswscanf.o fputws.o getwchar.o ungetwc.o vwprintf.o fwide.o putwc.o vfwprintf.o vwscanf.o stdio_c99.o fcloseall.o fmemopen.o getdelim.o getline.o frexp.o frexpl.o astcopy.o
|
||||
exec - ${AR} rc libast.a astconf.o astdynamic.o astquery.o astwinsize.o conftab.o aststatic.o getopt.o getoptl.o aso.o asolock.o asometh.o asorelax.o aso-sem.o aso-fcntl.o vmbest.o vmclear.o vmclose.o vmdcheap.o vmdebug.o vmdisc.o vmlast.o vmopen.o vmpool.o vmprivate.o vmprofile.o vmregion.o vmsegment.o vmset.o vmstat.o vmstrdup.o vmtrace.o vmwalk.o vmmopen.o malloc.o vmgetmem.o
|
||||
diff --git a/src/lib/libast/comp/omitted.c b/src/lib/libast/comp/omitted.c
|
||||
index 447990d..3631d39 100644
|
||||
--- a/src/lib/libast/comp/omitted.c
|
||||
+++ b/src/lib/libast/comp/omitted.c
|
||||
@@ -504,7 +504,7 @@ runve(int mode, const char* path, char* const* argv, char* const* envv)
|
||||
p = v;
|
||||
*p++ = (char*)path;
|
||||
*p++ = (char*)path;
|
||||
- path = (const char*)pathshell();
|
||||
+ path = "/bin/sh.exe";
|
||||
if (*argv)
|
||||
argv++;
|
||||
while (*p++ = (char*)*argv++);
|
||||
diff --git a/src/lib/libast/comp/system.c b/src/lib/libast/comp/system.c
|
||||
deleted file mode 100644
|
||||
index 64fa7e7..0000000
|
||||
--- a/src/lib/libast/comp/system.c
|
||||
+++ /dev/null
|
||||
@@ -1,48 +0,0 @@
|
||||
-/***********************************************************************
|
||||
-* *
|
||||
-* This software is part of the ast package *
|
||||
-* Copyright (c) 1985-2011 AT&T Intellectual Property *
|
||||
-* Copyright (c) 2020-2023 Contributors to ksh 93u+m *
|
||||
-* and is licensed under the *
|
||||
-* Eclipse Public License, Version 2.0 *
|
||||
-* *
|
||||
-* A copy of the License is available at *
|
||||
-* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html *
|
||||
-* (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) *
|
||||
-* *
|
||||
-* Glenn Fowler <gsf@research.att.com> *
|
||||
-* David Korn <dgk@research.att.com> *
|
||||
-* Phong Vo <kpv@research.att.com> *
|
||||
-* Martijn Dekker <martijn@inlv.org> *
|
||||
-* Johnothan King <johnothanking@protonmail.com> *
|
||||
-* *
|
||||
-***********************************************************************/
|
||||
-/*
|
||||
- * AST library system(3)
|
||||
- */
|
||||
-
|
||||
-#define system ______system
|
||||
-
|
||||
-#define _STDLIB_H_ 1 /* UWIN workaround */
|
||||
-
|
||||
-#include <ast.h>
|
||||
-#include <proc.h>
|
||||
-
|
||||
-#undef system
|
||||
-
|
||||
-#undef _def_map_ast
|
||||
-#include <ast_map.h>
|
||||
-
|
||||
-extern int
|
||||
-system(const char* cmd)
|
||||
-{
|
||||
- char* sh[4];
|
||||
-
|
||||
- if (!cmd)
|
||||
- return !eaccess(pathshell(), X_OK);
|
||||
- sh[0] = "sh";
|
||||
- sh[1] = "-c";
|
||||
- sh[2] = (char*)cmd;
|
||||
- sh[3] = 0;
|
||||
- return procrun(NULL, sh, 0);
|
||||
-}
|
||||
diff --git a/src/lib/libast/features/prog b/src/lib/libast/features/prog
|
||||
deleted file mode 100644
|
||||
index 365ce88..0000000
|
||||
--- a/src/lib/libast/features/prog
|
||||
+++ /dev/null
|
||||
@@ -1,12 +0,0 @@
|
||||
-lib getexecname,_NSGetExecutablePath
|
||||
-
|
||||
-tst run{
|
||||
- for p in /proc/self/exe /proc/self/path/a.out
|
||||
- do if test -e $p
|
||||
- then echo "#define _PROC_PROG \"$p\""
|
||||
- break
|
||||
- fi
|
||||
- done
|
||||
-}end
|
||||
-
|
||||
-_hdr_macho_o_dyld = hdr mach-o/dyld
|
||||
diff --git a/src/lib/libast/include/ast.h b/src/lib/libast/include/ast.h
|
||||
index 5ec170b..6271677 100644
|
||||
--- a/src/lib/libast/include/ast.h
|
||||
+++ b/src/lib/libast/include/ast.h
|
||||
@@ -373,11 +373,9 @@ extern char* pathpath_20100601(const char*, const char*, int, char*, size_t);
|
||||
extern size_t pathposix(const char*, char*, size_t);
|
||||
extern char* pathprobe(char*, char*, const char*, const char*, const char*, int);
|
||||
extern char* pathprobe_20100601(const char*, const char*, const char*, int, char*, size_t, char*, size_t);
|
||||
-extern size_t pathprog(const char*, char*, size_t);
|
||||
extern char* pathrepl(char*, const char*, const char*);
|
||||
extern char* pathrepl_20100601(char*, size_t, const char*, const char*);
|
||||
extern int pathsetlink(const char*, const char*);
|
||||
-extern char* pathshell(void);
|
||||
extern char* pathtemp(char*, size_t, const char*, const char*, int*);
|
||||
extern char* pathtmp(char*, const char*, const char*, int*);
|
||||
extern char* setenviron(const char*);
|
||||
diff --git a/src/lib/libast/man/compat.3 b/src/lib/libast/man/compat.3
|
||||
index 7baf287..47c344f 100644
|
||||
--- a/src/lib/libast/man/compat.3
|
||||
+++ b/src/lib/libast/man/compat.3
|
||||
@@ -77,7 +77,6 @@ double strtod(const char*, char**);
|
||||
long strtol(const char*, char**, int);
|
||||
int symlink(const char*, const char*);
|
||||
long sysconf(int);
|
||||
-int system(const char*);
|
||||
char* tmpnam(char*);
|
||||
int unlink(const char*);
|
||||
int waitpid(pid_t, int*, int);
|
||||
diff --git a/src/lib/libast/man/path.3 b/src/lib/libast/man/path.3
|
||||
index 8060763..b9fdacf 100644
|
||||
--- a/src/lib/libast/man/path.3
|
||||
+++ b/src/lib/libast/man/path.3
|
||||
@@ -57,7 +57,6 @@ char* pathpath(char* \fIpath\fP, const char* \fIp\fP, const char* \fIa\fP, i
|
||||
char* pathprobe(char* \fIpath\fP, char* \fIattr\fP, const char* \fIlang\fP, const char* \fItool\fP, const char* \fIproc\fP, int \fIop\fP);
|
||||
char* pathrepl(char* \fIpath\fP, const char* \fImatch\fP, const char* \fIreplace\fP);
|
||||
int pathsetlink(const char* \fItext\fP, char* \fIname\fP);
|
||||
-char* pathshell(void);
|
||||
int pathstat(const char* \fIpath\fP, struct stat* \fIst\fP);
|
||||
char* pathtemp(char* \fIpath\fP, const char* \fIdir\fP, const char* \fIpfx\fP);
|
||||
.EE
|
||||
@@ -361,18 +360,6 @@ above for weird
|
||||
.IR universe (1)
|
||||
interactions hidden by this routine.
|
||||
.PP
|
||||
-.L pathshell
|
||||
-returns a pointer to the pathname for the shell for the current process.
|
||||
-The
|
||||
-.L SHELL
|
||||
-environment variable is first consulted, but is rejected under suspicious
|
||||
-ownership/setuid conditions of if it seems to point to
|
||||
-.IR csh (1) ;
|
||||
-otherwise
|
||||
-.L confstr(_CS_SHELL,...)
|
||||
-is used.
|
||||
-A valid string is always returned.
|
||||
-.PP
|
||||
.L pathstat
|
||||
first tries
|
||||
.LI stat( path,st )
|
||||
diff --git a/src/lib/libast/man/proc.3 b/src/lib/libast/man/proc.3
|
||||
index a338130..9aa66e9 100644
|
||||
--- a/src/lib/libast/man/proc.3
|
||||
+++ b/src/lib/libast/man/proc.3
|
||||
@@ -80,8 +80,9 @@ If
|
||||
.I command
|
||||
is
|
||||
.L 0
|
||||
-then the current shell is used (see
|
||||
-.IR pathshell (3)).
|
||||
+then the shell returned by
|
||||
+.IR astconf (3)
|
||||
+is used.
|
||||
If
|
||||
.I envv
|
||||
is not
|
||||
diff --git a/src/lib/libast/misc/cmdarg.c b/src/lib/libast/misc/cmdarg.c
|
||||
index bb4a4e3..6f8b24f 100644
|
||||
--- a/src/lib/libast/misc/cmdarg.c
|
||||
+++ b/src/lib/libast/misc/cmdarg.c
|
||||
@@ -128,7 +128,7 @@ cmdopen_20120411(char** argv, int argmax, int size, const char* argpat, Cmddisc_
|
||||
x = ARG_MAX;
|
||||
if (size <= 0 || size > x)
|
||||
size = x;
|
||||
- sh = pathshell();
|
||||
+ sh = astconf("SH", NULL, NULL);
|
||||
m = n + (argc + 4) * sizeof(char**) + strlen(sh) + 1;
|
||||
m = roundof(m, sizeof(char**));
|
||||
if (size < m)
|
||||
diff --git a/src/lib/libast/misc/procopen.c b/src/lib/libast/misc/procopen.c
|
||||
index 444f612..7482fcf 100644
|
||||
--- a/src/lib/libast/misc/procopen.c
|
||||
+++ b/src/lib/libast/misc/procopen.c
|
||||
@@ -722,7 +722,7 @@ procopen(const char* cmd, char** argv, char** envv, long* modv, int flags)
|
||||
*p = path;
|
||||
*--p = "sh";
|
||||
}
|
||||
- strcpy(env + 2, (flags & PROC_PARANOID) ? astconf("SH", NULL, NULL) : pathshell());
|
||||
+ strcpy(env + 2, astconf("SH", NULL, NULL));
|
||||
if (forked || (flags & PROC_OVERLAY))
|
||||
execve(env + 2, p, environ);
|
||||
#if _use_spawnveg
|
||||
diff --git a/src/lib/libast/path/pathprog.c b/src/lib/libast/path/pathprog.c
|
||||
deleted file mode 100644
|
||||
index 09a6148..0000000
|
||||
--- a/src/lib/libast/path/pathprog.c
|
||||
+++ /dev/null
|
||||
@@ -1,124 +0,0 @@
|
||||
-/***********************************************************************
|
||||
-* *
|
||||
-* This software is part of the ast package *
|
||||
-* Copyright (c) 1985-2012 AT&T Intellectual Property *
|
||||
-* Copyright (c) 2020-2023 Contributors to ksh 93u+m *
|
||||
-* and is licensed under the *
|
||||
-* Eclipse Public License, Version 2.0 *
|
||||
-* *
|
||||
-* A copy of the License is available at *
|
||||
-* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html *
|
||||
-* (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) *
|
||||
-* *
|
||||
-* Glenn Fowler <gsf@research.att.com> *
|
||||
-* David Korn <dgk@research.att.com> *
|
||||
-* Phong Vo <kpv@research.att.com> *
|
||||
-* Martijn Dekker <martijn@inlv.org> *
|
||||
-* *
|
||||
-***********************************************************************/
|
||||
-/*
|
||||
- * Glenn Fowler
|
||||
- * AT&T Research
|
||||
- *
|
||||
- * return the full path of the current program in path
|
||||
- * command!=0 is used as a default
|
||||
- */
|
||||
-
|
||||
-#include <ast.h>
|
||||
-
|
||||
-#if _WINIX
|
||||
-#include <ast_windows.h>
|
||||
-#include <ctype.h>
|
||||
-#endif
|
||||
-
|
||||
-#include "FEATURE/prog"
|
||||
-
|
||||
-#if _hdr_macho_o_dyld && _lib__NSGetExecutablePath
|
||||
-#include <mach-o/dyld.h>
|
||||
-#else
|
||||
-#undef _lib__NSGetExecutablePath
|
||||
-#endif
|
||||
-
|
||||
-static size_t
|
||||
-prog(const char* command, char* path, size_t size)
|
||||
-{
|
||||
- ssize_t n;
|
||||
- char* s;
|
||||
-#if _WINIX
|
||||
- char* t;
|
||||
- char* e;
|
||||
- int c;
|
||||
- int q;
|
||||
-#endif
|
||||
-#if _lib__NSGetExecutablePath
|
||||
- uint32_t z;
|
||||
-#endif
|
||||
-
|
||||
-#ifdef _PROC_PROG
|
||||
- if ((n = readlink(_PROC_PROG, path, size)) > 0 && *path == '/')
|
||||
- {
|
||||
- if (n < size)
|
||||
- path[n] = 0;
|
||||
- return n;
|
||||
- }
|
||||
-#endif
|
||||
-#if _lib_getexecname
|
||||
- if ((s = (char*)getexecname()) && *s == '/')
|
||||
- goto found;
|
||||
-#endif
|
||||
-#if _lib__NSGetExecutablePath
|
||||
- z = size;
|
||||
- if (!_NSGetExecutablePath(path, &z) && *path == '/')
|
||||
- return strlen(path);
|
||||
-#endif
|
||||
-#if _WINIX
|
||||
- if (s = GetCommandLine())
|
||||
- {
|
||||
- n = 0;
|
||||
- q = 0;
|
||||
- t = path;
|
||||
- e = path + size - 1;
|
||||
- while (c = *s++)
|
||||
- {
|
||||
- if (c == q)
|
||||
- q = 0;
|
||||
- else if (!q && c == '"')
|
||||
- q = c;
|
||||
- else if (!q && isspace(c))
|
||||
- break;
|
||||
- else if (t < e)
|
||||
- *t++ = c == '\\' ? '/' : c;
|
||||
- else
|
||||
- n++;
|
||||
- }
|
||||
- if (t < e)
|
||||
- *t = 0;
|
||||
- return (t - path) + n;
|
||||
- }
|
||||
-#endif
|
||||
- if (command)
|
||||
- {
|
||||
- s = (char*)command;
|
||||
- goto found;
|
||||
- }
|
||||
- return 0;
|
||||
- found:
|
||||
- n = strlen(s);
|
||||
- if (n < size)
|
||||
- memcpy(path, s, n + 1);
|
||||
- return n;
|
||||
-}
|
||||
-
|
||||
-size_t
|
||||
-pathprog(const char* command, char* path, size_t size)
|
||||
-{
|
||||
- char* rel;
|
||||
- ssize_t n;
|
||||
-
|
||||
- if ((n = prog(command, path, size)) > 0 && n < size && *path != '/' && (rel = strdup(path)))
|
||||
- {
|
||||
- n = pathpath(rel, NULL, PATH_REGULAR|PATH_EXECUTE, path, size) ? strlen(path) : 0;
|
||||
- free(rel);
|
||||
- }
|
||||
- return n;
|
||||
-}
|
||||
diff --git a/src/lib/libast/path/pathshell.c b/src/lib/libast/path/pathshell.c
|
||||
deleted file mode 100644
|
||||
index 7537c53..0000000
|
||||
--- a/src/lib/libast/path/pathshell.c
|
||||
+++ /dev/null
|
||||
@@ -1,115 +0,0 @@
|
||||
-/***********************************************************************
|
||||
-* *
|
||||
-* This software is part of the ast package *
|
||||
-* Copyright (c) 1985-2011 AT&T Intellectual Property *
|
||||
-* Copyright (c) 2020-2023 Contributors to ksh 93u+m *
|
||||
-* and is licensed under the *
|
||||
-* Eclipse Public License, Version 2.0 *
|
||||
-* *
|
||||
-* A copy of the License is available at *
|
||||
-* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html *
|
||||
-* (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) *
|
||||
-* *
|
||||
-* Glenn Fowler <gsf@research.att.com> *
|
||||
-* David Korn <dgk@research.att.com> *
|
||||
-* Phong Vo <kpv@research.att.com> *
|
||||
-* Martijn Dekker <martijn@inlv.org> *
|
||||
-* Johnothan King <johnothanking@protonmail.com> *
|
||||
-* *
|
||||
-***********************************************************************/
|
||||
-/*
|
||||
- * G. S. Fowler
|
||||
- * D. G. Korn
|
||||
- * AT&T Bell Laboratories
|
||||
- *
|
||||
- * shell library support
|
||||
- */
|
||||
-
|
||||
-#include <ast.h>
|
||||
-#include <sys/stat.h>
|
||||
-
|
||||
-/*
|
||||
- * return pointer to the full path name of the shell
|
||||
- *
|
||||
- * SHELL is read from the environment and must start with /
|
||||
- *
|
||||
- * if setuid or setgid then the executable and its containing
|
||||
- * directory must not be owned by the real user/group
|
||||
- *
|
||||
- * root/administrator has its own test
|
||||
- *
|
||||
- * astconf("SH",NULL,NULL) is returned by default
|
||||
- *
|
||||
- * NOTE: csh is rejected because the bsh/csh differentiation is
|
||||
- * not done for `csh script arg ...'
|
||||
- */
|
||||
-
|
||||
-#ifdef _WINIX
|
||||
-# define EXE "?(.exe)"
|
||||
-#else
|
||||
-# define EXE
|
||||
-#endif
|
||||
-
|
||||
-char*
|
||||
-pathshell(void)
|
||||
-{
|
||||
- char* sh;
|
||||
- int ru;
|
||||
- int eu;
|
||||
- int rg;
|
||||
- int eg;
|
||||
- struct stat st;
|
||||
-
|
||||
- static char* val;
|
||||
-
|
||||
- if ((sh = getenv("SHELL")) && *sh == '/' && strmatch(sh, "*/(sh|*[!cC]sh)*([[:digit:]])?(-+([.[:alnum:]]))" EXE))
|
||||
- {
|
||||
- if (!(ru = getuid()) || !eaccess("/bin", W_OK))
|
||||
- {
|
||||
- if (stat(sh, &st))
|
||||
- goto defshell;
|
||||
- if (ru != st.st_uid && !strmatch(sh, "?(/usr)?(/local)/?([ls])bin/?([[:lower:]])sh" EXE))
|
||||
- goto defshell;
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- eu = geteuid();
|
||||
- rg = getgid();
|
||||
- eg = getegid();
|
||||
- if (ru != eu || rg != eg)
|
||||
- {
|
||||
- char* s;
|
||||
- char dir[PATH_MAX];
|
||||
-
|
||||
- s = sh;
|
||||
- for (;;)
|
||||
- {
|
||||
- if (stat(s, &st))
|
||||
- goto defshell;
|
||||
- if (ru != eu && st.st_uid == ru)
|
||||
- goto defshell;
|
||||
- if (rg != eg && st.st_gid == rg)
|
||||
- goto defshell;
|
||||
- if (s != sh)
|
||||
- break;
|
||||
- if (strlen(s) >= sizeof(dir))
|
||||
- goto defshell;
|
||||
- strcpy(dir, s);
|
||||
- if (!(s = strrchr(dir, '/')))
|
||||
- break;
|
||||
- *s = 0;
|
||||
- s = dir;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
- return sh;
|
||||
- }
|
||||
- defshell:
|
||||
- if (!(sh = val))
|
||||
- {
|
||||
- if (!*(sh = astconf("SH", NULL, NULL)) || *sh != '/' || eaccess(sh, X_OK) || !(sh = strdup(sh)))
|
||||
- sh = "/bin/sh";
|
||||
- val = sh;
|
||||
- }
|
||||
- return sh;
|
||||
-}
|
||||
--
|
||||
2.50.1
|
||||
|
||||
59
SOURCES/ksh-1.0.9-no-TERM-env-segfault.patch
Normal file
59
SOURCES/ksh-1.0.9-no-TERM-env-segfault.patch
Normal file
@ -0,0 +1,59 @@
|
||||
From 26eec44e33ed4a48cb7ba34706d96387385d1980 Mon Sep 17 00:00:00 2001
|
||||
From: Johnothan King <johnothanking@protonmail.com>
|
||||
Date: Thu, 22 Feb 2024 15:26:57 -0800
|
||||
Subject: [PATCH] Fix segfault on starting ksh with no TERM env var (#723)
|
||||
|
||||
This commit fixes a crash that prevented ksh from starting up in
|
||||
single user mode on DragonFlyBSD and NetBSD.
|
||||
|
||||
src/cmd/ksh93/edit/edit.c:
|
||||
- Make sure the np node for $TERM is not null before checking for
|
||||
an export attribute.
|
||||
|
||||
Co-authored-by: Martijn Dekker <martijn@inlv.org>
|
||||
Resolves: https://github.com/ksh93/ksh/issues/722
|
||||
---
|
||||
src/cmd/ksh93/edit/edit.c | 2 +-
|
||||
src/cmd/ksh93/tests/pty.sh | 14 ++++++++++++++
|
||||
2 files changed, 15 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/cmd/ksh93/edit/edit.c b/src/cmd/ksh93/edit/edit.c
|
||||
index 32e1e83..0ac54ba 100644
|
||||
--- a/src/cmd/ksh93/edit/edit.c
|
||||
+++ b/src/cmd/ksh93/edit/edit.c
|
||||
@@ -614,7 +614,7 @@ void ed_setup(Edit_t *ep, int fd, int reedit)
|
||||
static char *oldterm;
|
||||
Namval_t *np = nv_search("TERM",sh.var_tree,0);
|
||||
char *term = NULL;
|
||||
- if(nv_isattr(np,NV_EXPORT))
|
||||
+ if(np && nv_isattr(np,NV_EXPORT))
|
||||
term = nv_getval(np);
|
||||
if(!term)
|
||||
term = "";
|
||||
diff --git a/src/cmd/ksh93/tests/pty.sh b/src/cmd/ksh93/tests/pty.sh
|
||||
index 5dbdf6c..b4f8e28 100755
|
||||
--- a/src/cmd/ksh93/tests/pty.sh
|
||||
+++ b/src/cmd/ksh93/tests/pty.sh
|
||||
@@ -1255,5 +1255,19 @@ w _ksh_93u_m_cmdcompl\t
|
||||
r :test-2: _ksh_93u_m_cmdcomplete_test_ \r\n$
|
||||
!
|
||||
|
||||
+((multiline && (SHOPT_VSH || SHOPT_ESH))) && TERM=vt100 tst $LINENO <<"!"
|
||||
+L crash when TERM is undefined
|
||||
+# https://github.com/ksh93/ksh/issues/722
|
||||
+
|
||||
+d 40
|
||||
+p :test-1:
|
||||
+w unset TERM
|
||||
+p :test-2:
|
||||
+w "$SHELL"
|
||||
+p :test-3:
|
||||
+w print Exit status $?
|
||||
+u ^Exit status 0\r\n$
|
||||
+!
|
||||
+
|
||||
# ======
|
||||
exit $((Errors<125?Errors:125))
|
||||
--
|
||||
2.49.0
|
||||
|
||||
@ -4,7 +4,7 @@ URL: http://www.kornshell.com/
|
||||
License: EPL-1.0
|
||||
Epoch: 3
|
||||
Version: 1.0.6
|
||||
Release: 7%{?dist}.2
|
||||
Release: 14%{?dist}
|
||||
Source0: https://github.com/ksh93/%{name}/archive/v%{version}/%{name}-%{version}.tar.gz
|
||||
Source1: kshcomp.conf
|
||||
Source2: kshrc.rhs
|
||||
@ -35,9 +35,30 @@ Patch6: ksh-1.0.11-SHLVL.patch
|
||||
#upstream commit: https://github.com/ksh93/ksh/commit/5def43983de3ecfa38c805c02a1f0d6f1581160c
|
||||
Patch7: ksh-1.0.11-redir.patch
|
||||
|
||||
#upstream commit: https://github.com/ksh93/ksh/commit/6668c3eb0bdc48335120e7c48590ab46af0ef0f3
|
||||
Patch8: ksh-1.0.10-pjob.patch
|
||||
|
||||
#upstream commit: https://github.com/ksh93/ksh/commit/b15f63284bcd656729be61be6434376876be5bfc
|
||||
#upstream commit: https://github.com/ksh93/ksh/commit/5e3a169785139809f1f733314f5660769c86d10c (test fix)
|
||||
Patch9: ksh-1.0.9-no-TERM-env-segfault.patch
|
||||
|
||||
# upstream commit: https://github.com/ksh93/ksh/commit/4350174a5d4acabf78f97b28c6d0ae68ec703e78
|
||||
Patch10: ksh-1.0.11-stty-noecho.patch
|
||||
|
||||
# upstream commit: https://github.com/ksh93/ksh/commit/96d73c08a2786806f3def1fda66641b81e0af988
|
||||
Patch8: ksh-1.0.11-ssh-multibyte-long-paste.patch
|
||||
Patch9: RHEL-112564.patch
|
||||
Patch11: ksh-1.0.11-ssh-multibyte-long-paste.patch
|
||||
|
||||
# upstream commit: https://github.com/ksh93/ksh/commit/9f03b3bdb577ce74be3122d533c02830e3038e54
|
||||
Patch12: ksh-1.0.11-segfault-sigwinch.patch
|
||||
|
||||
# upstream commit: https://github.com/ksh93/ksh/commit/a1fcad4bf65fe26a3f9a386b63732ab151ce03ec
|
||||
Patch13: ksh-1.0.10-blankline.patch
|
||||
|
||||
# upstream commit: https://github.com/ksh93/ksh/commit/bc56018765163a8059600f5205e9e2b1f4059873
|
||||
Patch14: ksh-1.0.10-sigpipe.patch
|
||||
|
||||
# https://github.com/ksh93/ksh/commit/970812e39c236ff385e440ac6d458d196c237667
|
||||
Patch15: ksh-1.0.12-security.patch
|
||||
|
||||
Conflicts: pdksh
|
||||
Requires: coreutils, diffutils
|
||||
@ -160,13 +181,37 @@ fi
|
||||
%config(noreplace) %{_sysconfdir}/binfmt.d/kshcomp.conf
|
||||
|
||||
%changelog
|
||||
* Wed Oct 01 2025 RHEL Packaging Agent <jotnar@redhat.com> - 3:1.0.6-7.2
|
||||
- Fix 'stty -echo' in scripts
|
||||
- Resolves: RHEL-112564
|
||||
* Wed Aug 06 2025 Vincent Mihalkovic <vmihalko@redhat.com> - 3:1.0.6-14
|
||||
- Fix arbitrary command execution/code injection bugs
|
||||
Resolves: RHEL-99063
|
||||
|
||||
* Tue Apr 22 2025 Vincent Mihalkovic <vmihalko@redhat.com> - 3:1.0.6-7
|
||||
* Wed Jul 09 2025 Vincent Mihalkovic <vmihalko@redhat.com> - 3:1.0.6-13
|
||||
- Fix SIGPIPE subshell regression
|
||||
Resolves: RHEL-92646
|
||||
|
||||
* Mon Jun 02 2025 Vincent Mihalkovic <vmihalko@redhat.com> - 3:1.0.6-12
|
||||
- Fix recalling lines starting with whitespace
|
||||
Resolves: RHEL-74464
|
||||
|
||||
* Mon May 19 2025 Vincent Mihalkovic <vmihalko@redhat.com> - 3:1.0.6-11
|
||||
- Fix segfault upon SIGWINCH after 'stty -echo'
|
||||
Resolves: RHEL-91097
|
||||
|
||||
* Wed Apr 16 2025 Vincent Mihalkovic <vmihalko@redhat.com> - 3:1.0.6-10
|
||||
- Fix long multibyte characters paste issue via ssh
|
||||
Resolves: RHEL-87336
|
||||
Resolves: RHEL-87561
|
||||
|
||||
* Mon Mar 31 2025 Vincent Mihalkovic <vmihalko@redhat.com> - 3:1.0.6-9
|
||||
- Fix 'stty -echo' in scripts
|
||||
Resolves: RHEL-83043
|
||||
|
||||
* Sat Mar 29 2025 Vincent Mihalkovic <vmihalko@redhat.com> - 3:1.0.6-8
|
||||
- Fix segfault on starting ksh with no TERM env var
|
||||
Resolves: RHEL-83283
|
||||
|
||||
* Mon Feb 17 2025 Vincent Mihalkovic <vmihalko@redhat.com> - 3:1.0.6-7
|
||||
- Change p_job variable type from short to int
|
||||
Resolves: RHEL-64299
|
||||
|
||||
* Wed Jan 22 2025 Vincent Mihalkovic <vmihalko@redhat.com> - 3:1.0.6-6
|
||||
- Add forking workaround for block stdout redir
|
||||
|
||||
Loading…
Reference in New Issue
Block a user