diff options
author | Peter Stephenson <pws@users.sourceforge.net> | 2010-01-05 15:58:15 +0000 |
---|---|---|
committer | Peter Stephenson <pws@users.sourceforge.net> | 2010-01-05 15:58:15 +0000 |
commit | de4dac88749fbfefe7b78b0d747893c28c414abb (patch) | |
tree | 59eb6451786f324c3a76bc149e9ece5865597b83 /Src/Builtins/rlimits.c | |
parent | a4fbfa38beec7a6e1ad9dab2e3562a8c61bae5bf (diff) | |
download | zsh-de4dac88749fbfefe7b78b0d747893c28c414abb.tar.gz zsh-de4dac88749fbfefe7b78b0d747893c28c414abb.tar.xz zsh-de4dac88749fbfefe7b78b0d747893c28c414abb.zip |
27565: sanity check numeric arguments to ulimit
Diffstat (limited to 'Src/Builtins/rlimits.c')
-rw-r--r-- | Src/Builtins/rlimits.c | 52 |
1 files changed, 31 insertions, 21 deletions
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++; |