summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2010-01-05 15:58:15 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2010-01-05 15:58:15 +0000
commitde4dac88749fbfefe7b78b0d747893c28c414abb (patch)
tree59eb6451786f324c3a76bc149e9ece5865597b83
parenta4fbfa38beec7a6e1ad9dab2e3562a8c61bae5bf (diff)
downloadzsh-de4dac88749fbfefe7b78b0d747893c28c414abb.tar.gz
zsh-de4dac88749fbfefe7b78b0d747893c28c414abb.zip
27565: sanity check numeric arguments to ulimit
-rw-r--r--ChangeLog7
-rw-r--r--Src/Builtins/rlimits.c52
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++;