diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | Src/Builtins/rlimits.c | 52 |
2 files changed, 37 insertions, 22 deletions
diff --git a/ChangeLog b/ChangeLog index 8bf9aa741..8254e9647 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-01-05 Peter Stephenson <pws@csr.com> + + * 27565: Src/Builtins/rlimits.c: ulimit didn't sanity check + numeric arguments. + 2010-01-04 Clint Adams <clint@zsh.org> * 27559: Completion/Unix/Command/_espeak: espeak language @@ -12537,5 +12542,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.4852 $ +* $Revision: 1.4853 $ ***************************************************** diff --git a/Src/Builtins/rlimits.c b/Src/Builtins/rlimits.c index 16ef276f2..8843fb1db 100644 --- a/Src/Builtins/rlimits.c +++ b/Src/Builtins/rlimits.c @@ -680,7 +680,7 @@ static int bin_ulimit(char *name, char **argv, UNUSED(Options ops), UNUSED(int func)) { int res, resmask = 0, hard = 0, soft = 0, nres = 0, all = 0, ret = 0; - char *options; + char *options, *eptr, *number; do { options = *argv; @@ -704,13 +704,18 @@ bin_ulimit(char *name, char **argv, UNUSED(Options ops), UNUSED(int func)) continue; case 'N': if (options[1]) { - res = (int)zstrtol(options+1, NULL, 10); + number = options + 1; } else if (*argv) { - res = (int)zstrtol(*argv++, NULL, 10); + number = *argv++; } else { zwarnnam(name, "number required after -N"); return 1; } + res = (int)zstrtol(number, &eptr, 10); + if (*eptr) { + zwarnnam(name, "invalid number: %s", number); + return 1; + } /* * fake it so it looks like we just finished an option... */ @@ -831,38 +836,43 @@ bin_ulimit(char *name, char **argv, UNUSED(Options ops), UNUSED(int func)) /* set limit to specified value */ rlim_t limit; - limit = zstrtorlimt(*argv, NULL, 10); - /* scale appropriately */ - switch (res) { - case RLIMIT_FSIZE: - case RLIMIT_CORE: - limit *= 512; - break; - case RLIMIT_DATA: - case RLIMIT_STACK: + limit = zstrtorlimt(*argv, &eptr, 10); + if (*eptr) { + zwarnnam(name, "invalid number: %s", *argv); + ret++; + } else { + /* scale appropriately */ + switch (res) { + case RLIMIT_FSIZE: + case RLIMIT_CORE: + limit *= 512; + break; + case RLIMIT_DATA: + case RLIMIT_STACK: # ifdef HAVE_RLIMIT_RSS - case RLIMIT_RSS: + case RLIMIT_RSS: # endif /* HAVE_RLIMIT_RSS */ # ifdef HAVE_RLIMIT_MEMLOCK - case RLIMIT_MEMLOCK: + case RLIMIT_MEMLOCK: # endif /* HAVE_RLIMIT_MEMLOCK */ /* If RLIMIT_VMEM and RLIMIT_RSS are defined and equal, avoid * * duplicate case statement. Observed on QNX Neutrino 6.1.0. */ # if defined(HAVE_RLIMIT_VMEM) && !defined(RLIMIT_VMEM_IS_RSS) - case RLIMIT_VMEM: + case RLIMIT_VMEM: # endif /* HAVE_RLIMIT_VMEM */ /* ditto RLIMIT_VMEM and RLIMIT_AS */ # if defined(HAVE_RLIMIT_AS) && !defined(RLIMIT_VMEM_IS_AS) && !defined(RLIMIT_RSS_IS_AS) - case RLIMIT_AS: + case RLIMIT_AS: # endif /* HAVE_RLIMIT_AS */ # ifdef HAVE_RLIMIT_AIO_MEM - case RLIMIT_AIO_MEM: + case RLIMIT_AIO_MEM: # endif /* HAVE_RLIMIT_AIO_MEM */ - limit *= 1024; - break; + limit *= 1024; + break; + } + if (do_limit(name, res, limit, hard, soft, 1)) + ret++; } - if (do_limit(name, res, limit, hard, soft, 1)) - ret++; } else { if (do_unlimit(name, res, hard, soft, 1, geteuid())) ret++; |