summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2019-09-01 21:29:52 +0300
committerArnold D. Robbins <arnold@skeeve.com>2019-09-01 21:29:52 +0300
commit0d7384c6db25f830ac8710b3046375fee930c4d6 (patch)
treefc54efe363f2bb0807c5b45009112dfd90ce34db
parent5c41849e0e78e45db0dc4421f1779ef7bec726da (diff)
downloadgawk-0d7384c6db25f830ac8710b3046375fee930c4d6.tar.gz
Fix use-after-free issues in profile.c.
-rw-r--r--ChangeLog5
-rw-r--r--profile.c49
2 files changed, 31 insertions, 23 deletions
diff --git a/ChangeLog b/ChangeLog
index 54bc721d..081f07db 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2019-09-01 Arnold D. Robbins <arnold@skeeve.com>
+
+ * profile.c (pp_list, pp_concat): Fix use-after-free errors
+ in both routines. Thanks to valgrind and Andy's MEMDEBUG code.
+
2019-09-01 Andrew J. Schorr <aschorr@telemetry-investments.com>
* awk.h (block_header): Add cnt field even when MEMDEBUG is not
diff --git a/profile.c b/profile.c
index 910a821d..8cc19f18 100644
--- a/profile.c
+++ b/profile.c
@@ -1786,30 +1786,31 @@ pp_list(int nargs, const char *paren, const char *delim)
s = str;
if (paren != NULL)
*s++ = paren[0];
- if (nargs > 0) {
- r = pp_args[nargs];
+
+ for (i = nargs; i > 0; i--) {
+ // argument
+ r = pp_args[i];
memcpy(s, r->pp_str, r->pp_len);
s += r->pp_len;
- pp_free(r);
- for (i = nargs - 1; i > 0; i--) {
- if (delimlen > 0) {
- memcpy(s, delim, delimlen);
- s += delimlen;
- }
- if (r->pp_comment != NULL) {
- check_indent_level();
- comment = (INSTRUCTION *) r->pp_comment;
- memcpy(s, comment->memory->stptr, comment->memory->stlen);
- s += comment->memory->stlen;
- memcpy(s, tabs, indent_level + 1);
- s += indent_level + 1;
- }
- r = pp_args[i];
- memcpy(s, r->pp_str, r->pp_len);
- s += r->pp_len;
- pp_free(r);
+
+ // delimiter
+ if (i > 1 && delimlen > 0) {
+ memcpy(s, delim, delimlen);
+ s += delimlen;
+ }
+
+ // comment if any
+ if (r->pp_comment != NULL) {
+ check_indent_level();
+ comment = (INSTRUCTION *) r->pp_comment;
+ memcpy(s, comment->memory->stptr, comment->memory->stlen);
+ s += comment->memory->stlen;
+ memcpy(s, tabs, indent_level + 1);
+ s += indent_level + 1;
}
+ pp_free(r);
}
+
if (paren != NULL)
*s++ = paren[1];
*s = '\0';
@@ -1846,7 +1847,7 @@ pp_concat(int nargs)
/*
* items are on the stack in reverse order that they
- * will be printed to pop them off backwards.
+ * will be printed so pop them off backwards.
*/
len = -delimlen;
@@ -1887,7 +1888,6 @@ pp_concat(int nargs)
memcpy(s, r->pp_str, r->pp_len);
s += r->pp_len;
}
- pp_free(r);
if (i < nargs) {
*s++ = ' ';
@@ -1909,7 +1909,10 @@ pp_concat(int nargs)
memcpy(s, r->pp_str, r->pp_len);
s += r->pp_len;
}
- pp_free(r);
+
+ for (i = nargs; i >= 1; i--) {
+ pp_free(pp_args[i]);
+ }
*s = '\0';
return str;