aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2020-02-17 15:27:41 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2020-02-17 15:59:44 +0100
commitb0d2dc7d62f6dea67b82e451510fa77243b4c60c (patch)
tree163ee1a1459a707e0a678e7e5dcb853405413138
parentc55847fedbc3cbc10f2558c5449d8635f318ce49 (diff)
downloadbusybox-w32-b0d2dc7d62f6dea67b82e451510fa77243b4c60c.tar.gz
busybox-w32-b0d2dc7d62f6dea67b82e451510fa77243b4c60c.tar.bz2
busybox-w32-b0d2dc7d62f6dea67b82e451510fa77243b4c60c.zip
ash: exec: Do not allocate stack string in padvance
Upstream commit: Date: Sat, 19 May 2018 02:39:48 +0800 exec: Do not allocate stack string in padvance Many callers of padvance immediately free the allocated string so this patch moves the stalloc call to the caller. Instead of returning the allocated string, padvance now returns the length to allocate (this may be longer than the actual string length, even including the NUL). For the case where we would previously return NULL, we now return -1. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--shell/ash.c74
1 files changed, 38 insertions, 36 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 6505f4984..e89cecf0b 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -2560,17 +2560,17 @@ listvars(int on, int off, struct strlist *lp, char ***end)
2560/* ============ Path search helper 2560/* ============ Path search helper
2561 * 2561 *
2562 * The variable path (passed by reference) should be set to the start 2562 * The variable path (passed by reference) should be set to the start
2563 * of the path before the first call; path_advance will update 2563 * of the path before the first call; padvance will update
2564 * this value as it proceeds. Successive calls to path_advance will return 2564 * this value as it proceeds. Successive calls to padvance will return
2565 * the possible path expansions in sequence. If an option (indicated by 2565 * the possible path expansions in sequence. If an option (indicated by
2566 * a percent sign) appears in the path entry then the global variable 2566 * a percent sign) appears in the path entry then the global variable
2567 * pathopt will be set to point to it; otherwise pathopt will be set to 2567 * pathopt will be set to point to it; otherwise pathopt will be set to
2568 * NULL. 2568 * NULL.
2569 */ 2569 */
2570static const char *pathopt; /* set by path_advance */ 2570static const char *pathopt; /* set by padvance */
2571 2571
2572static char * 2572static int
2573path_advance(const char **path, const char *name) 2573padvance(const char **path, const char *name)
2574{ 2574{
2575 const char *p; 2575 const char *p;
2576 char *q; 2576 char *q;
@@ -2578,7 +2578,7 @@ path_advance(const char **path, const char *name)
2578 size_t len; 2578 size_t len;
2579 2579
2580 if (*path == NULL) 2580 if (*path == NULL)
2581 return NULL; 2581 return -1;
2582 start = *path; 2582 start = *path;
2583 for (p = start; *p && *p != ':' && *p != '%'; p++) 2583 for (p = start; *p && *p != ':' && *p != '%'; p++)
2584 continue; 2584 continue;
@@ -2599,7 +2599,7 @@ path_advance(const char **path, const char *name)
2599 *path = p + 1; 2599 *path = p + 1;
2600 else 2600 else
2601 *path = NULL; 2601 *path = NULL;
2602 return stalloc(len); 2602 return len;
2603} 2603}
2604 2604
2605 2605
@@ -2840,6 +2840,7 @@ cdcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
2840 char c; 2840 char c;
2841 struct stat statb; 2841 struct stat statb;
2842 int flags; 2842 int flags;
2843 int len;
2843 2844
2844 flags = cdopt(); 2845 flags = cdopt();
2845 dest = *argptr; 2846 dest = *argptr;
@@ -2869,9 +2870,10 @@ cdcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
2869 if (!*dest) 2870 if (!*dest)
2870 dest = "."; 2871 dest = ".";
2871 path = bltinlookup("CDPATH"); 2872 path = bltinlookup("CDPATH");
2872 while (path) { 2873 while (p = path, (len = padvance(&path, dest)) >= 0) {
2873 c = *path; 2874 c = *p;
2874 p = path_advance(&path, dest); 2875 p = stalloc(len);
2876
2875 if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) { 2877 if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) {
2876 if (c && c != ':') 2878 if (c && c != ':')
2877 flags |= CD_PRINT; 2879 flags |= CD_PRINT;
@@ -8169,13 +8171,13 @@ static void shellexec(char *prog, char **argv, const char *path, int idx)
8169 } else { 8171 } else {
8170 try_PATH: 8172 try_PATH:
8171 e = ENOENT; 8173 e = ENOENT;
8172 while ((cmdname = path_advance(&path, prog)) != NULL) { 8174 while (padvance(&path, argv[0]) >= 0) {
8175 cmdname = stackblock();
8173 if (--idx < 0 && pathopt == NULL) { 8176 if (--idx < 0 && pathopt == NULL) {
8174 tryexec(IF_FEATURE_SH_STANDALONE(-1,) cmdname, argv, envp); 8177 tryexec(IF_FEATURE_SH_STANDALONE(-1,) cmdname, argv, envp);
8175 if (errno != ENOENT && errno != ENOTDIR) 8178 if (errno != ENOENT && errno != ENOTDIR)
8176 e = errno; 8179 e = errno;
8177 } 8180 }
8178 stunalloc(cmdname);
8179 } 8181 }
8180 } 8182 }
8181 8183
@@ -8208,9 +8210,9 @@ printentry(struct tblentry *cmdp)
8208 idx = cmdp->param.index; 8210 idx = cmdp->param.index;
8209 path = pathval(); 8211 path = pathval();
8210 do { 8212 do {
8211 name = path_advance(&path, cmdp->cmdname); 8213 padvance(&path, cmdp->cmdname);
8212 stunalloc(name);
8213 } while (--idx >= 0); 8214 } while (--idx >= 0);
8215 name = stackblock();
8214 out1fmt("%s%s\n", name, (cmdp->rehash ? "*" : nullstr)); 8216 out1fmt("%s%s\n", name, (cmdp->rehash ? "*" : nullstr));
8215} 8217}
8216 8218
@@ -8603,9 +8605,9 @@ describe_command(char *command, const char *path, int describe_command_verbose)
8603 p = command; 8605 p = command;
8604 } else { 8606 } else {
8605 do { 8607 do {
8606 p = path_advance(&path, command); 8608 padvance(&path, command);
8607 stunalloc(p);
8608 } while (--j >= 0); 8609 } while (--j >= 0);
8610 p = stackblock();
8609 } 8611 }
8610 if (describe_command_verbose) { 8612 if (describe_command_verbose) {
8611 out1fmt(" is %s", p); 8613 out1fmt(" is %s", p);
@@ -11020,8 +11022,12 @@ chkmail(void)
11020 mpath = mpathset() ? mpathval() : mailval(); 11022 mpath = mpathset() ? mpathval() : mailval();
11021 new_hash = 0; 11023 new_hash = 0;
11022 for (;;) { 11024 for (;;) {
11023 p = path_advance(&mpath, nullstr); 11025 int len;
11024 if (p == NULL) 11026
11027 len = padvance(&mpath, nullstr);
11028 if (!len)
11029 break;
11030 p = stackblock();
11025 break; 11031 break;
11026 if (*p == '\0') 11032 if (*p == '\0')
11027 continue; 11033 continue;
@@ -13341,33 +13347,30 @@ cmdloop(int top)
13341 * search for the file, which is necessary to find sub-commands. 13347 * search for the file, which is necessary to find sub-commands.
13342 */ 13348 */
13343static char * 13349static char *
13344find_dot_file(char *name) 13350find_dot_file(char *basename)
13345{ 13351{
13346 char *fullname; 13352 char *fullname;
13347 const char *path = pathval(); 13353 const char *path = pathval();
13348 struct stat statb; 13354 struct stat statb;
13355 int len;
13349 13356
13350 /* don't try this for absolute or relative paths */ 13357 /* don't try this for absolute or relative paths */
13351 if (strchr(name, '/')) 13358 if (strchr(basename, '/'))
13352 return name; 13359 return basename;
13353 13360
13354 while ((fullname = path_advance(&path, name)) != NULL) { 13361 while ((len = padvance(&path, basename)) >= 0) {
13362 fullname = stackblock();
13355 if ((stat(fullname, &statb) == 0) && S_ISREG(statb.st_mode)) { 13363 if ((stat(fullname, &statb) == 0) && S_ISREG(statb.st_mode)) {
13356 /* 13364 /* This will be freed by the caller. */
13357 * Don't bother freeing here, since it will 13365 return stalloc(len);
13358 * be freed by the caller.
13359 */
13360 return fullname;
13361 } 13366 }
13362 if (fullname != name)
13363 stunalloc(fullname);
13364 } 13367 }
13365 /* not found in PATH */ 13368 /* not found in PATH */
13366 13369
13367#if ENABLE_ASH_BASH_SOURCE_CURDIR 13370#if ENABLE_ASH_BASH_SOURCE_CURDIR
13368 return name; 13371 return basename;
13369#else 13372#else
13370 ash_msg_and_raise_error("%s: not found", name); 13373 ash_msg_and_raise_error("%s: not found", basename);
13371 /* NOTREACHED */ 13374 /* NOTREACHED */
13372#endif 13375#endif
13373} 13376}
@@ -13470,6 +13473,7 @@ find_command(char *name, struct cmdentry *entry, int act, const char *path)
13470 int e; 13473 int e;
13471 int updatetbl; 13474 int updatetbl;
13472 struct builtincmd *bcmd; 13475 struct builtincmd *bcmd;
13476 int len;
13473 13477
13474 /* If name contains a slash, don't use PATH or hash table */ 13478 /* If name contains a slash, don't use PATH or hash table */
13475 if (strchr(name, '/') != NULL) { 13479 if (strchr(name, '/') != NULL) {
@@ -13561,10 +13565,8 @@ find_command(char *name, struct cmdentry *entry, int act, const char *path)
13561 e = ENOENT; 13565 e = ENOENT;
13562 idx = -1; 13566 idx = -1;
13563 loop: 13567 loop:
13564 while ((fullname = path_advance(&path, name)) != NULL) { 13568 while ((len = padvance(&path, name)) >= 0) {
13565 stunalloc(fullname); 13569 fullname = stackblock();
13566 /* NB: code below will still use fullname
13567 * despite it being "unallocated" */
13568 idx++; 13570 idx++;
13569 if (pathopt) { 13571 if (pathopt) {
13570 if (prefix(pathopt, "builtin")) { 13572 if (prefix(pathopt, "builtin")) {
@@ -13598,7 +13600,7 @@ find_command(char *name, struct cmdentry *entry, int act, const char *path)
13598 if (!S_ISREG(statb.st_mode)) 13600 if (!S_ISREG(statb.st_mode))
13599 continue; 13601 continue;
13600 if (pathopt) { /* this is a %func directory */ 13602 if (pathopt) { /* this is a %func directory */
13601 stalloc(strlen(fullname) + 1); 13603 stalloc(len);
13602 /* NB: stalloc will return space pointed by fullname 13604 /* NB: stalloc will return space pointed by fullname
13603 * (because we don't have any intervening allocations 13605 * (because we don't have any intervening allocations
13604 * between stunalloc above and this stalloc) */ 13606 * between stunalloc above and this stalloc) */