Tim Rühsen wrote:
> I could invite you (or anybody else) to view the detected defects. Just
> give me an OK and/or your email address before I do so.
>
> From what I can quickly see, some defects might be quite serious.
What I can see (in the limited set of gnulib modules that wget uses):
1) Coverity suggests to use 'memmove' instead of 'memcpy' in a couple
of places where it cannot prove that the source and destination memory
regions don't overlap.
I don't know what could make the coverity warnings disappear, but at least
we can add comments that help us verify that there is no issue. Invariants,
as usual.
2) A false warning at
len >> 31 >> 31 >> 2
because the code is prepared for 128-bit integers but coverity "knows" that
'len' is at most 64 bits wide.
3) malloc/free related warnings in glob.c.
Please review the three attached patches.
From 3e7178b337e3a83df9e4f36a4aef516f089e3796 Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Fri, 31 Mar 2017 22:03:49 +0200
Subject: [PATCH 1/3] md5, sha1, sha256, sha512: Add comments regarding
correctness.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* lib/md5.h (buflen): Add comments regarding range.
* lib/sha1.h (buflen): Likewise.
* lib/sha256.h (buflen): Likewise.
* lib/sha512.h (buflen): Likewise.
* lib/md5.c (md5_process_bytes): Add comment why memmove is not needed.
* lib/sha1.c (sha1_process_bytes): Likewise.
* lib/sha256.c (sha256_process_bytes): Likewise.
* lib/sha512.c (sha512_process_bytes): Likewise.
Reported by Coverity via Tim Rühsen.
---
ChangeLog | 13 +++++++++++++
lib/md5.c | 5 ++++-
lib/md5.h | 4 ++--
lib/sha1.c | 5 ++++-
lib/sha1.h | 4 ++--
lib/sha256.c | 5 ++++-
lib/sha256.h | 4 ++--
lib/sha512.c | 5 ++++-
lib/sha512.h | 4 ++--
9 files changed, 37 insertions(+), 12 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index ad7ae9e..7c15292 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2017-03-31 Bruno Haible <[email protected]>
+
+ md5, sha1, sha256, sha512: Add comments regarding correctness.
+ * lib/md5.h (buflen): Add comments regarding range.
+ * lib/sha1.h (buflen): Likewise.
+ * lib/sha256.h (buflen): Likewise.
+ * lib/sha512.h (buflen): Likewise.
+ * lib/md5.c (md5_process_bytes): Add comment why memmove is not needed.
+ * lib/sha1.c (sha1_process_bytes): Likewise.
+ * lib/sha256.c (sha256_process_bytes): Likewise.
+ * lib/sha512.c (sha512_process_bytes): Likewise.
+ Reported by Coverity via Tim Rühsen.
+
2017-03-22 Paul Eggert <[email protected]>
getopt: merge from glibc
diff --git a/lib/md5.c b/lib/md5.c
index 9f5237e..8650957 100644
--- a/lib/md5.c
+++ b/lib/md5.c
@@ -246,7 +246,8 @@ md5_process_bytes (const void *buffer, size_t len, struct md5_ctx *ctx)
md5_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
ctx->buflen &= 63;
- /* The regions in the following copy operation cannot overlap. */
+ /* The regions in the following copy operation cannot overlap,
+ because ctx->buflen < 64 ≤ (left_over + add) & ~63. */
memcpy (ctx->buffer,
&((char *) ctx->buffer)[(left_over + add) & ~63],
ctx->buflen);
@@ -288,6 +289,8 @@ md5_process_bytes (const void *buffer, size_t len, struct md5_ctx *ctx)
{
md5_process_block (ctx->buffer, 64, ctx);
left_over -= 64;
+ /* The regions in the following copy operation cannot overlap,
+ because left_over ≤ 64. */
memcpy (ctx->buffer, &ctx->buffer[16], left_over);
}
ctx->buflen = left_over;
diff --git a/lib/md5.h b/lib/md5.h
index 9c2c098..543a366 100644
--- a/lib/md5.h
+++ b/lib/md5.h
@@ -74,8 +74,8 @@ struct md5_ctx
uint32_t D;
uint32_t total[2];
- uint32_t buflen;
- uint32_t buffer[32];
+ uint32_t buflen; /* ≥ 0, ≤ 128 */
+ uint32_t buffer[32]; /* 128 bytes; the first buflen bytes are in use */
};
/*
diff --git a/lib/sha1.c b/lib/sha1.c
index 87c5771..6908650 100644
--- a/lib/sha1.c
+++ b/lib/sha1.c
@@ -233,7 +233,8 @@ sha1_process_bytes (const void *buffer, size_t len, struct sha1_ctx *ctx)
sha1_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
ctx->buflen &= 63;
- /* The regions in the following copy operation cannot overlap. */
+ /* The regions in the following copy operation cannot overlap,
+ because ctx->buflen < 64 ≤ (left_over + add) & ~63. */
memcpy (ctx->buffer,
&((char *) ctx->buffer)[(left_over + add) & ~63],
ctx->buflen);
@@ -275,6 +276,8 @@ sha1_process_bytes (const void *buffer, size_t len, struct sha1_ctx *ctx)
{
sha1_process_block (ctx->buffer, 64, ctx);
left_over -= 64;
+ /* The regions in the following copy operation cannot overlap,
+ because left_over ≤ 64. */
memcpy (ctx->buffer, &ctx->buffer[16], left_over);
}
ctx->buflen = left_over;
diff --git a/lib/sha1.h b/lib/sha1.h
index 38e82f3..0deb7ba 100644
--- a/lib/sha1.h
+++ b/lib/sha1.h
@@ -46,8 +46,8 @@ struct sha1_ctx
uint32_t E;
uint32_t total[2];
- uint32_t buflen;
- uint32_t buffer[32];
+ uint32_t buflen; /* ≥ 0, ≤ 128 */
+ uint32_t buffer[32]; /* 128 bytes; the first buflen bytes are in use */
};
/* Initialize structure containing state of computation. */
diff --git a/lib/sha256.c b/lib/sha256.c
index 03d3899..c0fb8be 100644
--- a/lib/sha256.c
+++ b/lib/sha256.c
@@ -366,7 +366,8 @@ sha256_process_bytes (const void *buffer, size_t len, struct sha256_ctx *ctx)
sha256_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
ctx->buflen &= 63;
- /* The regions in the following copy operation cannot overlap. */
+ /* The regions in the following copy operation cannot overlap,
+ because ctx->buflen < 64 ≤ (left_over + add) & ~63. */
memcpy (ctx->buffer,
&((char *) ctx->buffer)[(left_over + add) & ~63],
ctx->buflen);
@@ -408,6 +409,8 @@ sha256_process_bytes (const void *buffer, size_t len, struct sha256_ctx *ctx)
{
sha256_process_block (ctx->buffer, 64, ctx);
left_over -= 64;
+ /* The regions in the following copy operation cannot overlap,
+ because left_over ≤ 64. */
memcpy (ctx->buffer, &ctx->buffer[16], left_over);
}
ctx->buflen = left_over;
diff --git a/lib/sha256.h b/lib/sha256.h
index ffb91fa..348b76e 100644
--- a/lib/sha256.h
+++ b/lib/sha256.h
@@ -44,8 +44,8 @@ struct sha256_ctx
uint32_t state[8];
uint32_t total[2];
- size_t buflen;
- uint32_t buffer[32];
+ size_t buflen; /* ≥ 0, ≤ 128 */
+ uint32_t buffer[32]; /* 128 bytes; the first buflen bytes are in use */
};
/* Initialize structure containing state of computation. */
diff --git a/lib/sha512.c b/lib/sha512.c
index 6876bfd..dbde671 100644
--- a/lib/sha512.c
+++ b/lib/sha512.c
@@ -374,7 +374,8 @@ sha512_process_bytes (const void *buffer, size_t len, struct sha512_ctx *ctx)
sha512_process_block (ctx->buffer, ctx->buflen & ~127, ctx);
ctx->buflen &= 127;
- /* The regions in the following copy operation cannot overlap. */
+ /* The regions in the following copy operation cannot overlap,
+ because ctx->buflen < 128 ≤ (left_over + add) & ~127. */
memcpy (ctx->buffer,
&((char *) ctx->buffer)[(left_over + add) & ~127],
ctx->buflen);
@@ -416,6 +417,8 @@ sha512_process_bytes (const void *buffer, size_t len, struct sha512_ctx *ctx)
{
sha512_process_block (ctx->buffer, 128, ctx);
left_over -= 128;
+ /* The regions in the following copy operation cannot overlap,
+ because left_over ≤ 128. */
memcpy (ctx->buffer, &ctx->buffer[16], left_over);
}
ctx->buflen = left_over;
diff --git a/lib/sha512.h b/lib/sha512.h
index 121e6c3..4460e6c 100644
--- a/lib/sha512.h
+++ b/lib/sha512.h
@@ -44,8 +44,8 @@ struct sha512_ctx
u64 state[8];
u64 total[2];
- size_t buflen;
- u64 buffer[32];
+ size_t buflen; /* ≥ 0, ≤ 256 */
+ u64 buffer[32]; /* 256 bytes; the first buflen bytes are in use */
};
/* Initialize structure containing state of computation. */
--
2.7.4
From 0eee3ccaae5bb3d0016a0da8b8e5108767c02748 Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Fri, 31 Mar 2017 22:41:38 +0200
Subject: [PATCH 2/3] glob: Fix memory leaks.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* lib/glob.c (glob): Free allocated memory before returning.
Reported by Coverity via Tim Rühsen.
---
ChangeLog | 6 ++++++
lib/glob.c | 13 +++++++++++--
2 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 7c15292..cca7542 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2017-03-31 Bruno Haible <[email protected]>
+ glob: Fix memory leaks.
+ * lib/glob.c (glob): Free allocated memory before returning.
+ Reported by Coverity via Tim Rühsen.
+
+2017-03-31 Bruno Haible <[email protected]>
+
md5, sha1, sha256, sha512: Add comments regarding correctness.
* lib/md5.h (buflen): Add comments regarding range.
* lib/sha1.h (buflen): Likewise.
diff --git a/lib/glob.c b/lib/glob.c
index e69a96e..1337817 100644
--- a/lib/glob.c
+++ b/lib/glob.c
@@ -789,10 +789,14 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
malloc_home_dir = 1;
}
memcpy (home_dir, p->pw_dir, home_dir_len);
-
- free (pwtmpbuf);
}
}
+ free (malloc_pwtmpbuf);
+ }
+ else
+ {
+ if (__glibc_unlikely (malloc_name))
+ free (name);
}
}
if (home_dir == NULL || home_dir[0] == '\0')
@@ -847,6 +851,9 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
dirname = newp;
dirlen += home_len - 1;
malloc_dirname = !use_alloca;
+
+ if (__glibc_unlikely (malloc_home_dir))
+ free (home_dir);
}
dirname_modified = 1;
}
@@ -1048,6 +1055,8 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
if (newcount > SIZE_MAX / sizeof (char *) - 2)
{
nospace:
+ if (__glibc_unlikely (malloc_dirname))
+ free (dirname);
free (pglob->gl_pathv);
pglob->gl_pathv = NULL;
pglob->gl_pathc = 0;
--
2.7.4
From b1d7f3165ba1c7a44a29017eb80491094aa240ba Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Fri, 31 Mar 2017 22:43:35 +0200
Subject: [PATCH 3/3] glob: Fix invalid free() call.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* lib/glob.c (glob): Reset malloc_home_dir when assigning a pointer to
static storage to home_dir.
Reported by Coverity via Tim Rühsen.
---
ChangeLog | 7 +++++++
lib/glob.c | 5 ++++-
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/ChangeLog b/ChangeLog
index cca7542..2e01161 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
2017-03-31 Bruno Haible <[email protected]>
+ glob: Fix invalid free() call.
+ * lib/glob.c (glob): Reset malloc_home_dir when assigning a pointer to
+ static storage to home_dir.
+ Reported by Coverity via Tim Rühsen.
+
+2017-03-31 Bruno Haible <[email protected]>
+
glob: Fix memory leaks.
* lib/glob.c (glob): Free allocated memory before returning.
Reported by Coverity via Tim Rühsen.
diff --git a/lib/glob.c b/lib/glob.c
index 1337817..9305038 100644
--- a/lib/glob.c
+++ b/lib/glob.c
@@ -809,7 +809,10 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
goto out;
}
else
- home_dir = (char *) "~"; /* No luck. */
+ {
+ home_dir = (char *) "~"; /* No luck. */
+ malloc_home_dir = 0;
+ }
}
# endif /* WINDOWS32 */
# endif
--
2.7.4