about summary refs log tree commit diff
diff options
context:
space:
mode:
-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++;