summary refs log tree commit diff
path: root/Src/Builtins/rlimits.c
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 /Src/Builtins/rlimits.c
parenta4fbfa38beec7a6e1ad9dab2e3562a8c61bae5bf (diff)
downloadzsh-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.c52
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++;