Skip to content

Commit

Permalink
Fix TMOUT integer overflows (#720)
Browse files Browse the repository at this point in the history
This commit fixes two instances where an integer overflow could
occur if sh.st.tmout exceeded INT_MAX after being multiplied by
1000. This was first patched in Solaris[*], although the Solaris
patch fails to address the overflow in xec.c.

This approach only works on 64-bit architectures, as on 32-bit,
long isn't 64 bits in length. Fixing that will require
transitioning sh_timeradd and all related functions to Sflong_t.
For now, this commit makes the TMOUT fix friendlier to 32-bit long.

[*] https://github.com/oracle/solaris-userland/blob/e478b48/components/ksh93/patches/36096724.patch
  • Loading branch information
JohnoKing authored and McDutchie committed Feb 23, 2024
1 parent 5ca0dca commit 20fd6a4
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 11 deletions.
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ Uppercase BUG_* IDs are shell bug IDs as used by the Modernish shell library.
'exit' with no arguments to assume the before-trap exit status instead of
that of the last-run command. This broke the shipped 'autocd' function.

- Fixed some integer overflows that could occur when using TMOUT.

2024-02-17:

- Fixed a crash that could occur when using 'typeset -T' typed variables
Expand Down
18 changes: 9 additions & 9 deletions src/cmd/ksh93/bltins/read.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,13 @@

struct read_save
{
char **argv;
char *prompt;
int fd;
int plen;
int flags;
ssize_t len;
long timeout;
char **argv;
char *prompt;
int fd;
int plen;
int flags;
ssize_t len;
Sflong_t timeout;
};

int b_read(int argc,char *argv[], Shbltin_t *context)
Expand All @@ -66,7 +66,7 @@ int b_read(int argc,char *argv[], Shbltin_t *context)
const char *msg = e_file+4;
int r, flags=0, fd=0;
ssize_t len=0;
long timeout = 1000*sh.st.tmout;
Sflong_t timeout = 1000*(Sflong_t)sh.st.tmout;
int save_prompt, fixargs=context->invariant;
struct read_save *rp;
static char default_prompt[3] = {ESC,ESC};
Expand Down Expand Up @@ -212,7 +212,7 @@ static void timedout(void *handle)
* <flags> is union of -A, -r, -s, and contains delimiter if not '\n'
* <timeout> is the number of milliseconds until timeout
*/
int sh_readline(char **names, volatile int fd, int flags, ssize_t size, long timeout)
int sh_readline(char **names, volatile int fd, int flags, ssize_t size, Sflong_t timeout)
{
ssize_t c;
unsigned char *cp;
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/ksh93/include/defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ extern int sh_outtype(Sfio_t*);
extern char *sh_mactry(char*);
extern int sh_mathstd(const char*);
extern void sh_printopts(Shopt_t,int,Shopt_t*);
extern int sh_readline(char**,volatile int,int,ssize_t,long);
extern int sh_readline(char**,volatile int,int,ssize_t,Sflong_t);
extern Sfio_t *sh_sfeval(char*[]);
extern void sh_setmatch(const char*,int,int,int[],int);
extern void sh_scope(struct argnod*, int);
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/ksh93/sh/xec.c
Original file line number Diff line number Diff line change
Expand Up @@ -1976,7 +1976,7 @@ int sh_exec(const Shnode_t *t, int flags)
save_prompt = sh.nextprompt;
sh.nextprompt = 3;
sh.timeout = 0;
sh.exitval=sh_readline(&null_pointer,0,1,0,1000*sh.st.tmout);
sh.exitval=sh_readline(&null_pointer,0,1,0,1000*(Sflong_t)sh.st.tmout);
sh.nextprompt = save_prompt;
if(sh.exitval||sfeof(sfstdin)||sferror(sfstdin))
{
Expand Down

0 comments on commit 20fd6a4

Please sign in to comment.