[CRIU] [PATCH] criu-util: do not double free and simplify xvstrcat
Dmitry Safonov
dsafonov at virtuozzo.com
Fri Jul 15 11:46:53 PDT 2016
There is a bug, that if vsnprintf() wrote nothing to buffer:
that may be xstrcat(0, "%s", "") or something like that,
than vsnprintf's return value is 0, which will be lesser than
delta. The code before would do following:
o first cycle:
1. relocate str to new (str is not allocated anymore)
2. vsnprintf() retured 0, delta is greater.
o second cycle:
1. relocate previously freed str to new..^C ^C
Segmentation fault (core dumped)
Weeell, I do think, we can do better job here.
Signed-off-by: Dmitry Safonov <dsafonov at virtuozzo.com>
---
criu/util.c | 28 +++++++++++++++-------------
1 file changed, 15 insertions(+), 13 deletions(-)
diff --git a/criu/util.c b/criu/util.c
index b20c77bbff13..ec38a5ddc33f 100644
--- a/criu/util.c
+++ b/criu/util.c
@@ -74,21 +74,23 @@ static char *xvstrcat(char *str, const char *fmt, va_list args)
delta = strlen(fmt) * 2;
do {
- ret = -ENOMEM;
new = xrealloc(str, offset + delta);
- if (new) {
- va_copy(tmp, args);
- ret = vsnprintf(new + offset, delta, fmt, tmp);
- va_end(tmp);
- if (ret >= delta) {
- /* NOTE: vsnprintf returns the amount of bytes
- * to allocate. */
- delta = ret +1;
- str = new;
- ret = 0;
- }
+ if (!new) {
+ ret = -ENOMEM;
+ break;
}
- } while (ret == 0);
+
+ va_copy(tmp, args);
+ ret = vsnprintf(new + offset, delta, fmt, tmp);
+ va_end(tmp);
+ if (ret < delta) /* an error, or all was written */
+ break;
+
+ /* NOTE: vsnprintf returns the amount of bytes
+ * to allocate. */
+ delta = ret + 1;
+ str = new;
+ } while (1);
if (ret == -ENOMEM) {
/* realloc failed. We must release former string */
--
2.9.0
More information about the CRIU
mailing list