From 18529b88c631fce94461809b0740410c173b9791 Mon Sep 17 00:00:00 2001 From: Martijn Dekker Date: Sun, 21 Feb 2021 22:27:28 +0000 Subject: [PATCH] Add lots of checks for out of memory (re: 0ce0b671) Huge typeset -L/-R adjustment length values were still causing crashses on sytems with not enough memory. They should error out gracefully instead of crashing. This commit adds out of memory checks to all malloc/calloc/realloc calls that didn't have them (which is all but two or three). The stkalloc/stakalloc calls don't need the checks; it has automatic checking, which is done by passing a pointer to the outofspace() function to the stakinstall() call in init.c. src/lib/libast/include/error.h: - Change the ERROR_PANIC exit status value from ERROR_LEVEL (255) to 77, which is what it is supposed to be according to the libast error.3 manual page. Exit statuses > 128 for anything else than signals are not POSIX compliant and may cause misbehaviour. src/cmd/ksh93/include/defs.h, src/cmd/ksh93/sh/init.c: - To facilitate consistency, add a simple extern sh_outofmemory() function that throws an ERROR_PANIC "out of memory". src/cmd/ksh93/include/shell.h, src/cmd/ksh93/data/builtins.c: - Remove now-redundant e_nospace[] extern message; it is now only used in one place so it might as well be a string literal in sh_outofmemory(). All other changed files: - Verify the result of all malloc/calloc/realloc calls and call sh_outofmemory() if they fail. --- src/cmd/ksh93/bltins/alarm.c | 2 +- src/cmd/ksh93/bltins/misc.c | 2 ++ src/cmd/ksh93/bltins/read.c | 4 +++- src/cmd/ksh93/data/builtins.c | 1 - src/cmd/ksh93/edit/edit.c | 4 ++++ src/cmd/ksh93/edit/emacs.c | 2 ++ src/cmd/ksh93/edit/history.c | 2 ++ src/cmd/ksh93/edit/vi.c | 10 ++++++++++ src/cmd/ksh93/include/defs.h | 1 + src/cmd/ksh93/include/shell.h | 1 - src/cmd/ksh93/sh/args.c | 2 +- src/cmd/ksh93/sh/array.c | 8 ++++++++ src/cmd/ksh93/sh/fault.c | 2 ++ src/cmd/ksh93/sh/init.c | 23 ++++++++++++++++++++++- src/cmd/ksh93/sh/io.c | 10 +++++++++- src/cmd/ksh93/sh/jobs.c | 4 ++++ src/cmd/ksh93/sh/lex.c | 6 +++++- src/cmd/ksh93/sh/macro.c | 9 ++++++++- src/cmd/ksh93/sh/main.c | 3 ++- src/cmd/ksh93/sh/name.c | 21 ++++++++++++++++++++- src/cmd/ksh93/sh/nvdisc.c | 2 +- src/cmd/ksh93/sh/nvtype.c | 6 ++++++ src/cmd/ksh93/sh/parse.c | 2 ++ src/cmd/ksh93/sh/path.c | 10 ++++++++++ src/cmd/ksh93/sh/subshell.c | 4 ++++ src/cmd/ksh93/sh/suid_exec.c | 2 ++ src/cmd/ksh93/sh/xec.c | 7 ++++++- src/lib/libast/include/error.h | 2 +- 28 files changed, 138 insertions(+), 14 deletions(-) diff --git a/src/cmd/ksh93/bltins/alarm.c b/src/cmd/ksh93/bltins/alarm.c index 40e008776..769bd2553 100644 --- a/src/cmd/ksh93/bltins/alarm.c +++ b/src/cmd/ksh93/bltins/alarm.c @@ -274,7 +274,7 @@ int b_alarm(int argc,char *argv[],Shbltin_t *context) nv_unset(np); nv_setattr(np, NV_DOUBLE); if(!(tp = newof(NIL(struct tevent*),struct tevent,1,0))) - errormsg(SH_DICT,ERROR_exit(1),e_nospace); + sh_outofmemory(); tp->fun.disc = &alarmdisc; tp->flags = rflag; tp->node = np; diff --git a/src/cmd/ksh93/bltins/misc.c b/src/cmd/ksh93/bltins/misc.c index 8cdde266e..ea9e9221a 100644 --- a/src/cmd/ksh93/bltins/misc.c +++ b/src/cmd/ksh93/bltins/misc.c @@ -292,6 +292,8 @@ int b_dot_cmd(register int n,char *argv[],Shbltin_t *context) else { buffer = malloc(IOBSIZE+1); + if(!buffer) + sh_outofmemory(); iop = sfnew(NIL(Sfio_t*),buffer,IOBSIZE,fd,SF_READ); sh_offstate(SH_NOFORK); sh_eval(iop,sh_isstate(SH_PROFILE)?SH_FUNEVAL:0); diff --git a/src/cmd/ksh93/bltins/read.c b/src/cmd/ksh93/bltins/read.c index a2428c432..7d52adb61 100644 --- a/src/cmd/ksh93/bltins/read.c +++ b/src/cmd/ksh93/bltins/read.c @@ -349,7 +349,7 @@ int sh_readline(register Shell_t *shp,char **names, volatile int fd, int flags,s if((c=size)>=sizeof(buf)) { if(!(var = (char*)malloc(c+1))) - sh_exit(1); + sh_outofmemory(); end = var + c; } else @@ -412,6 +412,8 @@ int sh_readline(register Shell_t *shp,char **names, volatile int fd, int flags,s if (var == buf) { v = (char*)malloc(m+1); + if(!v) + sh_outofmemory(); var = memcpy(v, var, cur - var); } else diff --git a/src/cmd/ksh93/data/builtins.c b/src/cmd/ksh93/data/builtins.c index 9fece3acb..148e91ae3 100644 --- a/src/cmd/ksh93/data/builtins.c +++ b/src/cmd/ksh93/data/builtins.c @@ -2081,7 +2081,6 @@ const char sh_optwhence[] = const char e_alrm1[] = "alarm -r %s +%.3g\n"; const char e_alrm2[] = "alarm %s %.3f\n"; const char e_baddisc[] = "%s: invalid discipline function"; -const char e_nospace[] = "out of memory"; const char e_nofork[] = "cannot fork"; const char e_nosignal[] = "%s: unknown signal name"; const char e_condition[] = "condition(s) required"; diff --git a/src/cmd/ksh93/edit/edit.c b/src/cmd/ksh93/edit/edit.c index 1b720650c..f89c6ff7b 100644 --- a/src/cmd/ksh93/edit/edit.c +++ b/src/cmd/ksh93/edit/edit.c @@ -760,7 +760,11 @@ void ed_setup(register Edit_t *ep, int fd, int reedit) /* can't use output buffer when reading from stderr */ static char *buff; if(!buff) + { buff = (char*)malloc(MAXLINE); + if(!buff) + sh_outofmemory(); + } ep->e_outbase = ep->e_outptr = buff; ep->e_outlast = ep->e_outptr + MAXLINE; return; diff --git a/src/cmd/ksh93/edit/emacs.c b/src/cmd/ksh93/edit/emacs.c index 195259835..aba510468 100644 --- a/src/cmd/ksh93/edit/emacs.c +++ b/src/cmd/ksh93/edit/emacs.c @@ -221,6 +221,8 @@ int ed_emacsread(void *context, int fd,char *buff,int scend, int reedit) if(!kstack) { kstack = (genchar*)malloc(CHARSIZE*MAXLINE); + if(!kstack) + sh_outofmemory(); kstack[0] = '\0'; } drawbuff = out; diff --git a/src/cmd/ksh93/edit/history.c b/src/cmd/ksh93/edit/history.c index 24d9ffb07..45b5a78e8 100644 --- a/src/cmd/ksh93/edit/history.c +++ b/src/cmd/ksh93/edit/history.c @@ -472,6 +472,8 @@ static History_t* hist_trim(History_t *hp, int n) char *last, *name=hist_old->histname; close(sffileno(hist_old->histfp)); tmpname = (char*)malloc(strlen(name)+14); + if(!tmpname) + sh_outofmemory(); if(last = strrchr(name,'/')) { *last = 0; diff --git a/src/cmd/ksh93/edit/vi.c b/src/cmd/ksh93/edit/vi.c index cb6d7dea7..afa1ffb1b 100644 --- a/src/cmd/ksh93/edit/vi.c +++ b/src/cmd/ksh93/edit/vi.c @@ -237,6 +237,8 @@ int ed_viread(void *context, int fd, register char *shbuf, int nchar, int reedit { ed->e_vi = vp = newof(0,Vi_t,1,0); vp->lastline = (genchar*)malloc(MAXLINE*CHARSIZE); + if(!vp->lastline) + sh_outofmemory(); vp->direction = -1; vp->ed = ed; } @@ -385,9 +387,17 @@ int ed_viread(void *context, int fd, register char *shbuf, int nchar, int reedit window[0] = '\0'; if(!yankbuf) + { yankbuf = (genchar*)malloc(MAXLINE*CHARSIZE); + if(!yankbuf) + sh_outofmemory(); + } if(!vp->lastline) + { vp->lastline = (genchar*)malloc(MAXLINE*CHARSIZE); + if(!vp->lastline) + sh_outofmemory(); + } if( vp->last_cmd == '\0' ) { /*** first time for this shell ***/ diff --git a/src/cmd/ksh93/include/defs.h b/src/cmd/ksh93/include/defs.h index 2a16e6a52..2318b167c 100644 --- a/src/cmd/ksh93/include/defs.h +++ b/src/cmd/ksh93/include/defs.h @@ -367,6 +367,7 @@ extern Sfdouble_t sh_mathfun(Shell_t*, void*, int, Sfdouble_t*); extern int sh_outtype(Shell_t*, Sfio_t*); extern char *sh_mactry(Shell_t*,char*); extern int sh_mathstd(const char*); +extern void sh_outofmemory(void); extern void sh_printopts(Shopt_t,int,Shopt_t*); extern int sh_readline(Shell_t*,char**,volatile int,int,ssize_t,long); extern Sfio_t *sh_sfeval(char*[]); diff --git a/src/cmd/ksh93/include/shell.h b/src/cmd/ksh93/include/shell.h index b1db8d9ae..c6d9adb2d 100644 --- a/src/cmd/ksh93/include/shell.h +++ b/src/cmd/ksh93/include/shell.h @@ -147,7 +147,6 @@ typedef union Shnode_u Shnode_t; /* error messages */ extern const char e_found[]; -extern const char e_nospace[]; extern const char e_format[]; extern const char e_number[]; extern const char e_restricted[]; diff --git a/src/cmd/ksh93/sh/args.c b/src/cmd/ksh93/sh/args.c index 002d5a7f6..f14cf796c 100644 --- a/src/cmd/ksh93/sh/args.c +++ b/src/cmd/ksh93/sh/args.c @@ -735,7 +735,7 @@ struct argnod *sh_argprocsub(Shell_t *shp,struct argnod *argp) break; } if(!shp->fifo) - errormsg(SH_DICT,ERROR_system(128),"process substitution: FIFO creation failed"); + errormsg(SH_DICT,ERROR_PANIC,"process substitution: FIFO creation failed"); chmod(shp->fifo,S_IRUSR|S_IWUSR); /* mkfifo + chmod works regardless of umask */ sfputr(shp->stk,shp->fifo,0); #endif /* SHOPT_DEVFD */ diff --git a/src/cmd/ksh93/sh/array.c b/src/cmd/ksh93/sh/array.c index 9adefe927..77bc0b8e1 100644 --- a/src/cmd/ksh93/sh/array.c +++ b/src/cmd/ksh93/sh/array.c @@ -347,6 +347,8 @@ static Namval_t *array_find(Namval_t *np,Namarr_t *arp, int flag) if(data) { fp->data = (char*)malloc(fp->nelem*fp->size); + if(!fp->data) + sh_outofmemory(); memcpy(fp->data,data,fp->nelem*fp->size); } else @@ -900,6 +902,8 @@ int nv_atypeindex(Namval_t *np, const char *tname) if(!ap) ap = array_grow(np,ap,1); ap->xp = calloc(NV_MINSZ,1); + if(!ap->xp) + sh_outofmemory(); np = nv_namptr(ap->xp,0); np->nvname = tp->nvname; nv_onattr(np,NV_MINIMAL); @@ -1365,6 +1369,8 @@ static void array_fixed_setdata(Namval_t *np,Namarr_t* ap,struct fixed_array* fp fp->size = fp->ptr?sizeof(void*):nv_datasize(np,0); ap->nelem = n; fp->data = (char*)calloc(fp->nelem,fp->size); + if(!fp->data) + sh_outofmemory(); if(fp->ptr) { char **cp = (char**)fp->data; @@ -1660,6 +1666,8 @@ void *nv_associative(register Namval_t *np,const char *sp,int mode) ap->header.hdr.dsize = sizeof(struct assoc_array); ap->header.hdr.nofree &= ~1; } + else + sh_outofmemory(); return((void*)ap); case NV_ADELETE: if(ap->cur) diff --git a/src/cmd/ksh93/sh/fault.c b/src/cmd/ksh93/sh/fault.c index f138d3ce5..5832a3ff6 100644 --- a/src/cmd/ksh93/sh/fault.c +++ b/src/cmd/ksh93/sh/fault.c @@ -253,6 +253,8 @@ void sh_siginit(void *ptr) shp->st.trapcom = (char**)calloc(n,sizeof(char*)); shp->sigflag = (unsigned char*)calloc(n,1); shp->gd->sigmsg = (char**)calloc(n,sizeof(char*)); + if(!shp->st.trapcom || !shp->sigflag || !shp->gd->sigmsg) + sh_outofmemory(); for(tp=shtab_signals; sig=tp->sh_number; tp++) { n = (sig>>SH_SIGBITS); diff --git a/src/cmd/ksh93/sh/init.c b/src/cmd/ksh93/sh/init.c index f874e513c..755da47ec 100644 --- a/src/cmd/ksh93/sh/init.c +++ b/src/cmd/ksh93/sh/init.c @@ -219,13 +219,18 @@ static int shlvl; static int rand_shift; +void sh_outofmemory(void) +{ + errormsg(SH_DICT,ERROR_PANIC,"out of memory"); +} + /* * out of memory routine for stak routines */ static char *nospace(int unused) { NOT_USED(unused); - errormsg(SH_DICT,ERROR_exit(3),e_nospace); + sh_outofmemory(); return(NIL(char*)); } @@ -313,6 +318,8 @@ static Sfdouble_t nget_optindex(register Namval_t* np, Namfun_t *fp) static Namfun_t *clone_optindex(Namval_t* np, Namval_t *mp, int flags, Namfun_t *fp) { Namfun_t *dp = (Namfun_t*)malloc(sizeof(Namfun_t)); + if(!dp) + sh_outofmemory(); memcpy((void*)dp,(void*)fp,sizeof(Namfun_t)); mp->nvalue.lp = np->nvalue.lp; dp->nofree = 0; @@ -440,6 +447,8 @@ static void put_cdpath(register Namval_t* np,const char *val,int flags,Namfun_t register int c; char *state[4]; sh_lexstates[ST_BEGIN] = state[0] = (char*)malloc(4*(1<match = (int*)realloc(mp->match,i+vsize+1); else mp->match = (int*)malloc(i+vsize+1); + if(!mp->match) + sh_outofmemory(); mp->vsize = i+vsize+1; } mp->val = ((char*)mp->match)+i; @@ -862,6 +873,8 @@ static char* get_match(register Namval_t* np, Namfun_t *fp) mp->rval[i] = 0; } mp->rval[i] = (char*)malloc(n+1); + if(!mp->rval[i]) + sh_outofmemory(); mp->lastsub[i] = sub; memcpy(mp->rval[i],val,n); mp->rval[i][n] = 0; @@ -934,6 +947,8 @@ static void math_init(Shell_t *shp) char *name; int i; shp->mathnodes = (char*)calloc(1,MAX_MATH_ARGS*(NV_MINSZ+5)); + if(!shp->mathnodes) + sh_outofmemory(); name = shp->mathnodes+MAX_MATH_ARGS*NV_MINSZ; for(i=0; i < MAX_MATH_ARGS; i++) { @@ -1064,6 +1079,8 @@ static int newconf(const char *name, const char *path, const char *value) { int i; char *cp = (char*)malloc(ST_NONE*(1<numnodes = nstat; sp->nodes = (char*)(sp+1); shgd->stats = (int*)calloc(sizeof(int),nstat); + if(!shgd->stats) + sh_outofmemory(); sp->sh = shp; for(i=0; i < nstat; i++) { @@ -1878,6 +1897,8 @@ Dt_t *sh_inittree(Shell_t *shp,const struct shtable2 *name_vals) for(tp=name_vals;*tp->sh_name;tp++) n++; np = (Namval_t*)calloc(n,sizeof(Namval_t)); + if(!np) + sh_outofmemory(); if(!shgd->bltin_nodes) { shgd->bltin_nodes = np; diff --git a/src/cmd/ksh93/sh/io.c b/src/cmd/ksh93/sh/io.c index 9071a9d0f..0665df7d8 100644 --- a/src/cmd/ksh93/sh/io.c +++ b/src/cmd/ksh93/sh/io.c @@ -422,6 +422,8 @@ int sh_iovalidfd(Shell_t *shp, int fd) n = max; max = shp->gd->lim.open_max; shp->sftable = (Sfio_t**)calloc((n+1)*(sizeof(int*)+sizeof(Sfio_t*)+1),1); + if(!shp->sftable) + sh_outofmemory(); if(max) memcpy(shp->sftable,sftable,max*sizeof(Sfio_t*)); shp->fdptrs = (int**)(&shp->sftable[n]); @@ -469,6 +471,8 @@ void sh_ioinit(Shell_t *shp) { filemapsize = 8; filemap = (struct fdsave*)malloc(filemapsize*sizeof(struct fdsave)); + if(!filemap) + sh_outofmemory(); sh_iovalidfd(shp,16); shp->sftable[0] = sfstdin; shp->sftable[1] = sfstdout; @@ -480,6 +484,8 @@ void sh_ioinit(Shell_t *shp) shp->outpool = sfopen(NIL(Sfio_t*),NIL(char*),"sw"); /* pool identifier */ shp->outbuff = (char*)malloc(IOBSIZE+4); shp->errbuff = (char*)malloc(IOBSIZE/4); + if(!shp->outbuff || !shp->errbuff) + sh_outofmemory(); sfsetbuf(sfstderr,shp->errbuff,IOBSIZE/4); sfsetbuf(sfstdout,shp->outbuff,IOBSIZE); sfpool(sfstdout,shp->outpool,SF_WRITE); @@ -1576,6 +1582,8 @@ static int io_heredoc(Shell_t *shp,register struct ionod *iop, const char *name, if(sffileno(tmp)>0) { sfsetbuf(tmp,malloc(IOBSIZE+1),IOBSIZE); + if(!tmp) + sh_outofmemory(); sfset(tmp,SF_MALLOC,1); } sfseek(shp->heredocs,off,SEEK_SET); @@ -1640,7 +1648,7 @@ void sh_iosave(Shell_t *shp, register int origfd, int oldtop, char *name) long moved; filemapsize += 8; if(!(filemap = (struct fdsave*)realloc(filemap,filemapsize*sizeof(struct fdsave)))) - errormsg(SH_DICT,ERROR_exit(4),e_nospace); + sh_outofmemory(); if(moved = (char*)filemap - oldptr) { for(savefd=shp->gd->lim.open_max; --savefd>=0; ) diff --git a/src/cmd/ksh93/sh/jobs.c b/src/cmd/ksh93/sh/jobs.c index a4251a923..49bebd5f3 100644 --- a/src/cmd/ksh93/sh/jobs.c +++ b/src/cmd/ksh93/sh/jobs.c @@ -1206,7 +1206,11 @@ void job_clear(void) job.curpgid = 0; job.toclear = 0; if(!job.freejobs) + { job.freejobs = (unsigned char*)malloc((unsigned)(j+1)); + if(!job.freejobs) + sh_outofmemory(); + } while(j >=0) job.freejobs[j--] = 0; job_unlock(); diff --git a/src/cmd/ksh93/sh/lex.c b/src/cmd/ksh93/sh/lex.c index 64487b421..8e50bbe73 100644 --- a/src/cmd/ksh93/sh/lex.c +++ b/src/cmd/ksh93/sh/lex.c @@ -2486,6 +2486,8 @@ static void setupalias(Lex_t *lp, const char *string,Namval_t *np) { register Sfio_t *iop, *base; struct alias *ap = (struct alias*)malloc(sizeof(struct alias)); + if(!ap) + sh_outofmemory(); ap->disc = alias_disc; ap->lp = lp; ap->buf[1] = 0; @@ -2525,6 +2527,8 @@ static int stack_grow(Lex_t *lp) lp->lexd.lex_match = (int*)realloc((char*)lp->lexd.lex_match,sizeof(int)*lp->lexd.lex_max); else lp->lexd.lex_match = (int*)malloc(sizeof(int)*STACK_ARRAY); - return(lp->lexd.lex_match!=0); + if(!lp->lexd.lex_match) + sh_outofmemory(); + return(1); } diff --git a/src/cmd/ksh93/sh/macro.c b/src/cmd/ksh93/sh/macro.c index 89ada195a..bc0e0ff22 100644 --- a/src/cmd/ksh93/sh/macro.c +++ b/src/cmd/ksh93/sh/macro.c @@ -972,6 +972,8 @@ static char *prefix(Shell_t *shp, char *id) nv_putsub(np,sub,0L); } id = (char*)malloc(strlen(cp)+1+(n=strlen(sp=nv_name(np)))+ (sub?strlen(sub)+3:1)); + if(!id) + sh_outofmemory(); memcpy(id,sp,n); if(sub) { @@ -2162,7 +2164,12 @@ static void comsubst(Mac_t *mp,register Shnode_t* t, int type) goto out_offset; } if(!(sp=mp->shp->sftable[fd])) - sp = sfnew(NIL(Sfio_t*),(char*)malloc(IOBSIZE+1),IOBSIZE,fd,SF_READ|SF_MALLOC); + { + char *cp = (char*)malloc(IOBSIZE+1); + if(!cp) + sh_outofmemory(); + sp = sfnew(NIL(Sfio_t*),cp,IOBSIZE,fd,SF_READ|SF_MALLOC); + } type = 3; } else diff --git a/src/cmd/ksh93/sh/main.c b/src/cmd/ksh93/sh/main.c index 4217ea09c..38952c203 100644 --- a/src/cmd/ksh93/sh/main.c +++ b/src/cmd/ksh93/sh/main.c @@ -127,7 +127,6 @@ int sh_main(int ac, char *av[], Shinit_f userinit) struct stat statb; int i, rshflag; /* set for restricted shell */ char *command; - free(malloc(64*1024)); #ifdef _lib_sigvec /* This is to clear mask that may be left on by rlogin */ clearsigmask(SIGALRM); @@ -322,6 +321,8 @@ int sh_main(int ac, char *av[], Shinit_f userinit) /* try sh -c 'name "$@"' */ sh_onoption(SH_CFLAG); shp->comdiv = (char*)malloc(strlen(name)+7); + if(!shp->comdiv) + sh_outofmemory(); name = strcopy(shp->comdiv,name); if(shp->st.dolc) strcopy(name," \"$@\""); diff --git a/src/cmd/ksh93/sh/name.c b/src/cmd/ksh93/sh/name.c index 919253831..4ba66ad41 100644 --- a/src/cmd/ksh93/sh/name.c +++ b/src/cmd/ksh93/sh/name.c @@ -127,6 +127,8 @@ static char *getbuf(size_t len) buf = (char*)malloc(len); else buf = (char*)realloc(buf,len); + if(!buf) + sh_outofmemory(); buflen = len; } return(buf); @@ -229,6 +231,8 @@ Namval_t *nv_addnode(Namval_t* np, int remove) { sp->maxnodes += 20; sp->nodes = (Namval_t**)realloc(sp->nodes,sizeof(Namval_t*)*sp->maxnodes); + if(!sp->nodes) + sh_outofmemory(); } sp->nodes[sp->numnodes++] = np; return(np); @@ -282,6 +286,8 @@ void nv_setlist(register struct argnod *arg,register int flags, Namval_t *typ) shtp.maxnodes = 20; shtp.rp = 0; shtp.nodes =(Namval_t**)malloc(shtp.maxnodes*sizeof(Namval_t*)); + if(!shtp.nodes) + sh_outofmemory(); } #endif /* SHOPT_TYPEDEF*/ #if SHOPT_NAMESPACE @@ -1428,6 +1434,8 @@ Namval_t *nv_open(const char *name, Dt_t *root, int flags) xp->name = malloc(c); else xp->name = realloc(xp->name,c); + if(!xp->name) + sh_outofmemory(); xp->size = c; } memcpy(xp->name,name,xp->len); @@ -1897,7 +1905,10 @@ void nv_putval(register Namval_t *np, const char *string, int flags) size = nv_size(np); if(size==0) size = oldsize + (3*dot/4); - *(cp = (char*)malloc(size+1)) = 0; + cp = (char*)malloc(size+1); + if(!cp) + sh_outofmemory(); + *cp = 0; nv_offattr(np,NV_NOFREE); if(oldsize) memcpy((void*)cp,(void*)up->cp,oldsize); @@ -1960,6 +1971,8 @@ void nv_putval(register Namval_t *np, const char *string, int flags) } else cp = (char*)malloc(dot+append+1); + if(!cp) + sh_outofmemory(); cp[dot+append] = 0; nv_offattr(np,NV_NOFREE); } @@ -3037,18 +3050,24 @@ void nv_newattr (register Namval_t *np, unsigned newatts, int size) { /* allocate to match existing value for numerics and auto length assignment for -L/R/Z */ cp = (char*)malloc((size_t)n + 1); + if(!cp) + sh_outofmemory(); strcpy(cp, sp); } else if(size>=n) { /* growing string */ cp = (char*)malloc((size_t)size + 1); + if(!cp) + sh_outofmemory(); strcpy(cp, sp); } else { /* shrinking string */ cp = (char*)malloc((size_t)size + 1); + if(!cp) + sh_outofmemory(); if(newatts&NV_RJUST) strncpy(cp, n - size + sp, size); else diff --git a/src/cmd/ksh93/sh/nvdisc.c b/src/cmd/ksh93/sh/nvdisc.c index 8de284f78..7db4a17fb 100644 --- a/src/cmd/ksh93/sh/nvdisc.c +++ b/src/cmd/ksh93/sh/nvdisc.c @@ -878,7 +878,7 @@ static void *num_clone(register Namval_t *np, void *val) size = sizeof(int32_t); } if(!(nval = malloc(size))) - return(0); + sh_outofmemory(); memcpy(nval,val,size); return(nval); } diff --git a/src/cmd/ksh93/sh/nvtype.c b/src/cmd/ksh93/sh/nvtype.c index 4b1c24e9d..1e35a2900 100644 --- a/src/cmd/ksh93/sh/nvtype.c +++ b/src/cmd/ksh93/sh/nvtype.c @@ -327,6 +327,8 @@ static int fixnode(Namtype_t *dp, Namtype_t *pp, int i, struct Namref *nrp,int f { const char *cp = nq->nvalue.cp; nq->nvalue.cp = (char*)malloc(i); + if(!nq->nvalue.cp) + sh_outofmemory(); memcpy((char*)nq->nvalue.cp,cp,i); } else @@ -366,6 +368,8 @@ static Namfun_t *clone_type(Namval_t* np, Namval_t *mp, int flags, Namfun_t *fp) if(size==0 && (!fp->disc || (size=fp->disc->dsize)==0)) size = sizeof(Namfun_t); dp = (Namtype_t*)malloc(size+pp->nref*sizeof(struct Namref)); + if(!dp) + sh_outofmemory(); if(pp->nref) { nrp = (struct Namref*)((char*)dp + size); @@ -576,6 +580,8 @@ static Namval_t *next_type(register Namval_t* np, Dt_t *root,Namfun_t *fp) static Namfun_t *clone_inttype(Namval_t* np, Namval_t *mp, int flags, Namfun_t *fp) { Namfun_t *pp= (Namfun_t*)malloc(fp->dsize); + if(!pp) + sh_outofmemory(); memcpy((void*)pp, (void*)fp, fp->dsize); fp->nofree &= ~1; if(nv_isattr(mp,NV_NOFREE) && mp->nvalue.cp) diff --git a/src/cmd/ksh93/sh/parse.c b/src/cmd/ksh93/sh/parse.c index 85546e5ed..dff8d35d8 100644 --- a/src/cmd/ksh93/sh/parse.c +++ b/src/cmd/ksh93/sh/parse.c @@ -173,6 +173,8 @@ static void typeset_order(const char *str,int line) if(!table) { table = calloc(1,256); + if(!table) + sh_outofmemory(); for(cp=(unsigned char*)"bflmnprstuxACHS";c = *cp; cp++) table[c] = 1; for(cp=(unsigned char*)"aiEFLRXhTZ";c = *cp; cp++) diff --git a/src/cmd/ksh93/sh/path.c b/src/cmd/ksh93/sh/path.c index 5a72de943..ef632d590 100644 --- a/src/cmd/ksh93/sh/path.c +++ b/src/cmd/ksh93/sh/path.c @@ -186,6 +186,8 @@ static pid_t path_xargs(Shell_t *shp,const char *path, char *argv[],char *const { n = nlast*sizeof(char*); saveargs = (char**)malloc(n); + if(!saveargs) + sh_outofmemory(); memcpy((void*)saveargs, (void*)av, n); memcpy((void*)av,(void*)avlast,n); } @@ -566,6 +568,8 @@ char *path_fullname(Shell_t *shp,const char *name) dirlen = strlen(pwd)+1; } path = (char*)malloc(len+dirlen); + if(!path) + sh_outofmemory(); if(dirlen) { memcpy((void*)path,(void*)pwd,dirlen); @@ -1177,6 +1181,8 @@ pid_t path_spawn(Shell_t *shp,const char *opath,register char **argv, char **env * may not yield the same results */ char *sp = (char*)malloc(strlen(path)+3); + if(!sp) + sh_outofmemory(); sp[0] = '.'; sp[1] = '/'; strcpy(sp+2,path); @@ -1505,6 +1511,8 @@ static Pathcomp_t *path_addcomp(Shell_t *shp,Pathcomp_t *first, Pathcomp_t *old, pp->dev = 1; pp->flags |= PATH_BUILTIN_LIB; pp->blib = pp->bbuf = malloc(sizeof(LIBCMD)); + if(!pp->blib) + sh_outofmemory(); strcpy(pp->blib,LIBCMD); return(first); } @@ -1575,6 +1583,8 @@ static int path_chkpaths(Shell_t *shp,Pathcomp_t *first, Pathcomp_t* old,Pathcom else if(m) { pp->lib = (char*)malloc(cp-sp+pp->len+2); + if(!pp->lib) + sh_outofmemory(); memcpy((void*)pp->lib,(void*)sp,m); memcpy((void*)&pp->lib[m],stakptr(offset),pp->len); pp->lib[k=m+pp->len] = '/'; diff --git a/src/cmd/ksh93/sh/subshell.c b/src/cmd/ksh93/sh/subshell.c index 7c157aae1..a199e3c37 100644 --- a/src/cmd/ksh93/sh/subshell.c +++ b/src/cmd/ksh93/sh/subshell.c @@ -308,6 +308,8 @@ Namval_t *sh_assignok(register Namval_t *np,int add) } /* first two pointers use linkage from np */ lp = (struct Link*)malloc(sizeof(*np)+2*sizeof(void*)); + if(!lp) + sh_outofmemory(); memset(lp,0, sizeof(*mp)+2*sizeof(void*)); lp->node = np; if(!add && nv_isvtree(np)) @@ -614,6 +616,8 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub) if((nsig=shp->st.trapmax)>0 || shp->st.trapcom[0]) { savsig = malloc(nsig * sizeof(char*)); + if(!savsig) + sh_outofmemory(); /* * the data is, usually, modified in code like: * tmp = buf[i]; buf[i] = strdup(tmp); free(tmp); diff --git a/src/cmd/ksh93/sh/suid_exec.c b/src/cmd/ksh93/sh/suid_exec.c index 19812c83e..7ea2df1fc 100644 --- a/src/cmd/ksh93/sh/suid_exec.c +++ b/src/cmd/ksh93/sh/suid_exec.c @@ -330,6 +330,8 @@ int eaccess(register const char *name, register int mode) } } groups = (gid_t*)malloc((maxgroups+1)*sizeof(gid_t)); + if(!groups) + error(ERROR_PANIC,"out of memory"); n = getgroups(maxgroups,groups); while(--n >= 0) { diff --git a/src/cmd/ksh93/sh/xec.c b/src/cmd/ksh93/sh/xec.c index 47a3790a8..6e7c7781a 100644 --- a/src/cmd/ksh93/sh/xec.c +++ b/src/cmd/ksh93/sh/xec.c @@ -1869,7 +1869,10 @@ int sh_exec(register const Shnode_t *t, int flags) if((nsig=shp->st.trapmax*sizeof(char*))>0 || shp->st.trapcom[0]) { nsig += sizeof(char*); - memcpy(savsig=malloc(nsig),(char*)&shp->st.trapcom[0],nsig); + savsig = malloc(nsig); + if(!savsig) + sh_outofmemory(); + memcpy(savsig,(char*)&shp->st.trapcom[0],nsig); shp->st.otrapcom = (char**)savsig; } sh_sigreset(0); @@ -3113,6 +3116,8 @@ int sh_funscope(int argn, char *argv[],int(*fun)(void*),void *arg,int execflg) if((nsig=shp->st.trapmax)>0 || shp->st.trapcom[0]) { savsig = malloc(nsig * sizeof(char*)); + if(!savsig) + sh_outofmemory(); /* * the data is, usually, modified in code like: * tmp = buf[i]; buf[i] = strdup(tmp); free(tmp); diff --git a/src/lib/libast/include/error.h b/src/lib/libast/include/error.h index 6baaf0d32..14a636df6 100644 --- a/src/lib/libast/include/error.h +++ b/src/lib/libast/include/error.h @@ -64,7 +64,7 @@ #define ERROR_FATAL 3 /* error message with err_exit */ #define ERROR_NOEXEC EXIT_NOEXEC /* shell convention */ #define ERROR_NOENT EXIT_NOTFOUND /* shell convention */ -#define ERROR_PANIC ERROR_LEVEL /* panic message with err_exit */ +#define ERROR_PANIC 77 /* panic message with err_exit */ #define ERROR_LEVEL 0x00ff /* level portion of status */ #define ERROR_SYSTEM 0x0100 /* report system errno message */