From: Jeff King <peff@peff.net>
To: git@vger.kernel.org
Subject: [PATCH 56/67] avoid sprintf and strcpy with flex arrays
Date: Tue, 15 Sep 2015 12:09:56 -0400 [thread overview]
Message-ID: <20150915160956.GD29753@sigill.intra.peff.net> (raw)
In-Reply-To: <20150915152125.GA27504@sigill.intra.peff.net>
When we are allocating a struct with a FLEX_ARRAY member, we
generally compute the size of the array and then sprintf or
strcpy into it. Normally we could improve a dynamic allocation
like this by using xstrfmt, but it doesn't work here; we
have to account for the size of the rest of the struct.
But we can improve things a bit by storing the length that
we use for the allocation, and then feeding it to xsnprintf
or memcpy, which makes it more obvious that we are not
writing more than the allocated number of bytes.
It would be nice if we had some kind of helper for
allocating generic flex arrays, but it doesn't work that
well:
- the call signature is a little bit unwieldy:
d = flex_struct(sizeof(*d), offsetof(d, path), fmt, ...);
You need offsetof here instead of just writing to the
end of the base size, because we don't know how the
struct is packed (partially this is because FLEX_ARRAY
might not be zero, though we can account for that; but
the size of the struct may actually be rounded up for
alignment, and we can't know that).
- some sites do clever things, like over-allocating because
they know they will write larger things into the buffer
later (e.g., struct packed_git here).
So we're better off to just write out each allocation (or
add type-specific helpers, though many of these are one-off
allocations anyway).
Signed-off-by: Jeff King <peff@peff.net>
---
Actually, I have a malloc-hardening series (which I'll post after this),
in which I _do_ break down and add a FLEX_ALLOC() macro. But we still
cannot use it for these cases anyway, because we don't assume all
platforms support variadic macros.
archive.c | 5 +++--
builtin/blame.c | 5 +++--
fast-import.c | 6 ++++--
refs.c | 8 ++++----
sha1_file.c | 5 +++--
submodule.c | 6 ++++--
6 files changed, 21 insertions(+), 14 deletions(-)
diff --git a/archive.c b/archive.c
index 01b0899..4ac86c8 100644
--- a/archive.c
+++ b/archive.c
@@ -171,13 +171,14 @@ static void queue_directory(const unsigned char *sha1,
unsigned mode, int stage, struct archiver_context *c)
{
struct directory *d;
- d = xmallocz(sizeof(*d) + base->len + 1 + strlen(filename));
+ size_t len = base->len + 1 + strlen(filename) + 1;
+ d = xmalloc(sizeof(*d) + len);
d->up = c->bottom;
d->baselen = base->len;
d->mode = mode;
d->stage = stage;
c->bottom = d;
- d->len = sprintf(d->path, "%.*s%s/", (int)base->len, base->buf, filename);
+ d->len = xsnprintf(d->path, len, "%.*s%s/", (int)base->len, base->buf, filename);
hashcpy(d->oid.hash, sha1);
}
diff --git a/builtin/blame.c b/builtin/blame.c
index f8ec7ff..dbec516 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -459,12 +459,13 @@ static void queue_blames(struct scoreboard *sb, struct origin *porigin,
static struct origin *make_origin(struct commit *commit, const char *path)
{
struct origin *o;
- o = xcalloc(1, sizeof(*o) + strlen(path) + 1);
+ size_t pathlen = strlen(path) + 1;
+ o = xcalloc(1, sizeof(*o) + pathlen);
o->commit = commit;
o->refcnt = 1;
o->next = commit->util;
commit->util = o;
- strcpy(o->path, path);
+ memcpy(o->path, path, pathlen); /* includes NUL */
return o;
}
diff --git a/fast-import.c b/fast-import.c
index d0c2502..895c6b4 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -863,13 +863,15 @@ static void start_packfile(void)
{
static char tmp_file[PATH_MAX];
struct packed_git *p;
+ int namelen;
struct pack_header hdr;
int pack_fd;
pack_fd = odb_mkstemp(tmp_file, sizeof(tmp_file),
"pack/tmp_pack_XXXXXX");
- p = xcalloc(1, sizeof(*p) + strlen(tmp_file) + 2);
- strcpy(p->pack_name, tmp_file);
+ namelen = strlen(tmp_file) + 2;
+ p = xcalloc(1, sizeof(*p) + namelen);
+ xsnprintf(p->pack_name, namelen, "%s", tmp_file);
p->pack_fd = pack_fd;
p->do_not_close = 1;
pack_file = sha1fd(pack_fd, p->pack_name);
diff --git a/refs.c b/refs.c
index c2709de..df6c41a 100644
--- a/refs.c
+++ b/refs.c
@@ -2695,7 +2695,7 @@ static int pack_if_possible_fn(struct ref_entry *entry, void *cb_data)
int namelen = strlen(entry->name) + 1;
struct ref_to_prune *n = xcalloc(1, sizeof(*n) + namelen);
hashcpy(n->sha1, entry->u.value.oid.hash);
- strcpy(n->name, entry->name);
+ memcpy(n->name, entry->name, namelen); /* includes NUL */
n->next = cb->ref_to_prune;
cb->ref_to_prune = n;
}
@@ -3984,10 +3984,10 @@ void ref_transaction_free(struct ref_transaction *transaction)
static struct ref_update *add_update(struct ref_transaction *transaction,
const char *refname)
{
- size_t len = strlen(refname);
- struct ref_update *update = xcalloc(1, sizeof(*update) + len + 1);
+ size_t len = strlen(refname) + 1;
+ struct ref_update *update = xcalloc(1, sizeof(*update) + len);
- strcpy((char *)update->refname, refname);
+ memcpy((char *)update->refname, refname, len); /* includese NUL */
ALLOC_GROW(transaction->updates, transaction->nr + 1, transaction->alloc);
transaction->updates[transaction->nr++] = update;
return update;
diff --git a/sha1_file.c b/sha1_file.c
index 374a996..efcfcff 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -1176,9 +1176,10 @@ struct packed_git *add_packed_git(const char *path, size_t path_len, int local)
struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path)
{
const char *path = sha1_pack_name(sha1);
- struct packed_git *p = alloc_packed_git(strlen(path) + 1);
+ int alloc = strlen(path) + 1;
+ struct packed_git *p = alloc_packed_git(alloc);
- strcpy(p->pack_name, path);
+ memcpy(p->pack_name, path, alloc); /* includes NUL */
hashcpy(p->sha1, sha1);
if (check_packed_git_idx(idx_path, p)) {
free(p);
diff --git a/submodule.c b/submodule.c
index 245ed4d..c480ed5 100644
--- a/submodule.c
+++ b/submodule.c
@@ -122,6 +122,7 @@ static int add_submodule_odb(const char *path)
struct strbuf objects_directory = STRBUF_INIT;
struct alternate_object_database *alt_odb;
int ret = 0;
+ int alloc;
const char *git_dir;
strbuf_addf(&objects_directory, "%s/.git", path);
@@ -142,9 +143,10 @@ static int add_submodule_odb(const char *path)
objects_directory.len))
goto done;
- alt_odb = xmalloc(objects_directory.len + 42 + sizeof(*alt_odb));
+ alloc = objects_directory.len + 42; /* for "12/345..." sha1 */
+ alt_odb = xmalloc(sizeof(*alt_odb) + alloc);
alt_odb->next = alt_odb_list;
- strcpy(alt_odb->base, objects_directory.buf);
+ xsnprintf(alt_odb->base, alloc, "%s", objects_directory.buf);
alt_odb->name = alt_odb->base + objects_directory.len;
alt_odb->name[2] = '/';
alt_odb->name[40] = '\0';
--
2.6.0.rc2.408.ga2926b9
next prev parent reply other threads:[~2015-09-15 16:10 UTC|newest]
Thread overview: 154+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-09-15 15:21 [PATCH 0/67] war on sprintf, strcpy, etc Jeff King
2015-09-15 15:23 ` [PATCH 01/67] show-branch: avoid segfault with --reflog of unborn branch Jeff King
2015-09-15 15:23 ` [PATCH 02/67] mailsplit: fix FILE* leak in split_maildir Jeff King
2015-09-15 15:23 ` [PATCH 03/67] archive-tar: fix minor indentation violation Jeff King
2015-09-15 15:24 ` [PATCH 04/67] fsck: don't fsck alternates for connectivity-only check Jeff King
2015-09-15 17:55 ` Johannes Schindelin
2015-09-16 18:04 ` Junio C Hamano
2015-09-16 18:12 ` Jeff King
2015-09-16 19:12 ` Junio C Hamano
2015-09-16 19:14 ` Eric Sunshine
2015-09-16 20:00 ` Jeff King
2015-09-15 15:24 ` [PATCH 05/67] add xsnprintf helper function Jeff King
2015-09-15 15:25 ` [PATCH 06/67] add git_path_buf " Jeff King
2015-09-15 15:25 ` [PATCH 07/67] strbuf: make strbuf_complete_line more generic Jeff King
2015-09-16 0:45 ` Eric Sunshine
2015-09-16 1:27 ` Junio C Hamano
2015-09-16 9:57 ` Jeff King
2015-09-16 15:11 ` Eric Sunshine
2015-09-15 15:26 ` [PATCH 08/67] add reentrant variants of sha1_to_hex and find_unique_abbrev Jeff King
2015-09-15 16:55 ` Ramsay Jones
2015-09-15 17:50 ` Jeff King
2015-09-16 1:32 ` Junio C Hamano
2015-09-16 8:15 ` Johannes Schindelin
2015-09-16 10:33 ` Jeff King
2015-09-16 17:06 ` Junio C Hamano
2015-09-16 17:23 ` Jeff King
2015-09-15 15:26 ` [PATCH 09/67] fsck: use strbuf to generate alternate directories Jeff King
2015-09-15 15:28 ` [PATCH 10/67] mailsplit: make PATH_MAX buffers dynamic Jeff King
2015-09-16 0:51 ` Eric Sunshine
2015-09-16 10:14 ` Jeff King
2015-09-16 10:25 ` Jeff King
2015-09-16 18:13 ` Junio C Hamano
2015-09-16 20:22 ` Jeff King
2015-09-15 15:28 ` [PATCH 11/67] trace: use strbuf for quote_crnl output Jeff King
2015-09-16 0:55 ` Eric Sunshine
2015-09-16 10:31 ` Jeff King
2015-09-16 15:16 ` Eric Sunshine
2015-09-15 15:29 ` [PATCH 12/67] progress: store throughput display in a strbuf Jeff King
2015-09-15 15:30 ` [PATCH 13/67] test-dump-cache-tree: avoid overflow of cache-tree name Jeff King
2015-09-15 15:31 ` [PATCH 14/67] compat/inet_ntop: fix off-by-one in inet_ntop4 Jeff King
2015-09-15 15:36 ` [PATCH 15/67] convert trivial sprintf / strcpy calls to xsnprintf Jeff King
2015-09-15 18:32 ` Ramsay Jones
2015-09-15 18:42 ` Jeff King
2015-09-15 19:15 ` Ramsay Jones
2015-09-15 20:38 ` Stefan Beller
2015-09-16 9:45 ` Jeff King
2015-09-16 18:20 ` Junio C Hamano
2015-09-16 1:34 ` Junio C Hamano
2015-09-16 3:19 ` Eric Sunshine
2015-09-16 9:48 ` Jeff King
2015-09-16 18:24 ` Junio C Hamano
2015-09-16 18:52 ` Jeff King
2015-09-16 19:07 ` Junio C Hamano
2015-09-16 19:19 ` Stefan Beller
2015-09-16 20:35 ` Jeff King
2015-09-16 20:32 ` Jeff King
2015-09-15 15:37 ` [PATCH 16/67] archive-tar: use xsnprintf for trivial formatting Jeff King
2015-09-15 15:38 ` [PATCH 17/67] use xsnprintf for generating git object headers Jeff King
2015-09-16 18:30 ` Junio C Hamano
2015-09-15 15:38 ` [PATCH 18/67] find_short_object_filename: convert sprintf to xsnprintf Jeff King
2015-09-15 15:39 ` [PATCH 19/67] stop_progress_msg: " Jeff King
2015-09-15 15:39 ` [PATCH 20/67] compat/hstrerror: convert sprintf to snprintf Jeff King
2015-09-15 15:39 ` [PATCH 21/67] grep: use xsnprintf to format failure message Jeff King
2015-09-15 15:40 ` [PATCH 22/67] entry.c: convert strcpy to xsnprintf Jeff King
2015-09-15 19:01 ` Ramsay Jones
2015-09-15 21:04 ` Stefan Beller
2015-09-15 15:41 ` [PATCH 23/67] add_packed_git: convert strcpy into xsnprintf Jeff King
2015-09-16 18:43 ` Junio C Hamano
2015-09-16 20:24 ` Jeff King
2015-09-15 15:42 ` [PATCH 24/67] http-push: replace strcat with xsnprintf Jeff King
2015-09-15 15:43 ` [PATCH 25/67] receive-pack: convert strncpy to xsnprintf Jeff King
2015-09-15 15:45 ` [PATCH 26/67] replace trivial malloc + sprintf /strcpy calls to xstrfmt Jeff King
2015-09-16 4:24 ` Eric Sunshine
2015-09-16 10:43 ` Jeff King
2015-09-15 15:45 ` [PATCH 27/67] config: use xstrfmt in normalize_value Jeff King
2015-09-15 15:46 ` [PATCH 28/67] fetch: replace static buffer with xstrfmt Jeff King
2015-09-15 15:47 ` [PATCH 29/67] use strip_suffix and xstrfmt to replace suffix Jeff King
2015-09-16 4:38 ` Eric Sunshine
2015-09-16 10:50 ` Jeff King
2015-09-16 15:20 ` Eric Sunshine
2015-09-15 15:48 ` [PATCH 30/67] ref-filter: drop sprintf and strcpy calls Jeff King
2015-09-16 19:33 ` Junio C Hamano
2015-09-15 15:48 ` [PATCH 31/67] help: drop prepend function in favor of xstrfmt Jeff King
2015-09-15 15:49 ` [PATCH 32/67] mailmap: replace strcpy with xstrdup Jeff King
2015-09-15 15:49 ` [PATCH 33/67] read_branches_file: " Jeff King
2015-09-16 19:52 ` Junio C Hamano
2015-09-16 20:42 ` Jeff King
2015-09-17 11:28 ` Jeff King
2015-09-17 11:32 ` Jeff King
2015-09-17 11:36 ` Jeff King
2015-09-17 15:38 ` Junio C Hamano
2015-09-17 16:24 ` Jeff King
2015-09-17 16:53 ` Junio C Hamano
2015-09-15 15:50 ` [PATCH 34/67] resolve_ref: use strbufs for internal buffers Jeff King
2015-09-15 15:51 ` [PATCH 35/67] upload-archive: convert sprintf to strbuf Jeff King
2015-09-15 15:52 ` [PATCH 36/67] remote-ext: simplify git pkt-line generation Jeff King
2015-09-16 20:18 ` Junio C Hamano
2015-09-16 21:23 ` Jeff King
2015-09-15 15:52 ` [PATCH 37/67] http-push: use strbuf instead of fwrite_buffer Jeff King
2015-09-15 15:53 ` [PATCH 38/67] http-walker: store url in a strbuf Jeff King
2015-09-15 15:54 ` [PATCH 39/67] sha1_get_pack_name: use " Jeff King
2015-09-15 15:56 ` [PATCH 40/67] init: use strbufs to store paths Jeff King
2015-09-15 15:57 ` [PATCH 41/67] apply: convert root string to strbuf Jeff King
2015-09-15 15:57 ` [PATCH 42/67] transport: use strbufs for status table "quickref" strings Jeff King
2015-09-15 15:58 ` [PATCH 43/67] merge-recursive: convert malloc / strcpy to strbuf Jeff King
2015-09-15 15:59 ` [PATCH 44/67] enter_repo: convert fixed-size buffers to strbufs Jeff King
2015-09-15 15:59 ` [PATCH 45/67] remove_leading_path: use a strbuf for internal storage Jeff King
2015-09-15 16:00 ` [PATCH 46/67] write_loose_object: convert to strbuf Jeff King
2015-09-16 21:27 ` Junio C Hamano
2015-09-16 21:39 ` Jeff King
2015-09-15 16:01 ` [PATCH 47/67] diagnose_invalid_index_path: use strbuf to avoid strcpy/strcat Jeff King
2015-09-15 16:02 ` [PATCH 48/67] fetch-pack: use argv_array for index-pack / unpack-objects Jeff King
2015-09-15 16:02 ` [PATCH 49/67] http-push: use an argv_array for setup_revisions Jeff King
2015-09-15 16:03 ` [PATCH 50/67] stat_tracking_info: convert to argv_array Jeff King
2015-09-15 16:04 ` [PATCH 51/67] daemon: use cld->env_array when re-spawning Jeff King
2015-09-15 16:05 ` [PATCH 52/67] use sha1_to_hex_to() instead of strcpy Jeff King
2015-09-16 21:51 ` Junio C Hamano
2015-09-16 21:54 ` Jeff King
2015-09-16 21:59 ` Junio C Hamano
2015-09-15 16:06 ` [PATCH 53/67] drop strcpy in favor of raw sha1_to_hex Jeff King
2015-09-18 19:24 ` Eric Sunshine
2015-09-18 19:29 ` Jeff King
2015-09-15 16:07 ` [PATCH 54/67] color: add overflow checks for parsing colors Jeff King
2015-09-18 18:54 ` Eric Sunshine
2015-09-18 19:01 ` Jeff King
2015-09-21 16:56 ` Junio C Hamano
2015-09-15 16:07 ` [PATCH 55/67] use alloc_ref rather than hand-allocating "struct ref" Jeff King
2015-09-15 16:09 ` Jeff King [this message]
2015-09-20 22:48 ` [PATCH 56/67] avoid sprintf and strcpy with flex arrays Eric Sunshine
2015-09-21 15:15 ` Jeff King
2015-09-21 17:11 ` Eric Sunshine
2015-09-21 17:19 ` Jeff King
2015-09-15 16:10 ` [PATCH 57/67] receive-pack: simplify keep_arg computation Jeff King
2015-09-18 18:43 ` Eric Sunshine
2015-09-18 18:49 ` Jeff King
2015-09-15 16:11 ` [PATCH 58/67] help: clean up kfmclient munging Jeff King
2015-09-15 16:11 ` [PATCH 59/67] prefer memcpy to strcpy Jeff King
2015-09-15 16:12 ` [PATCH 60/67] color: add color_set helper for copying raw colors Jeff King
2015-09-15 16:13 ` [PATCH 61/67] notes: document length of fanout path with a constant Jeff King
2015-09-15 16:13 ` [PATCH 62/67] convert strncpy to memcpy Jeff King
2015-09-15 16:14 ` [PATCH 63/67] fsck: drop inode-sorting code Jeff King
2015-09-15 16:14 ` [PATCH 64/67] Makefile: drop D_INO_IN_DIRENT build knob Jeff King
2015-09-15 16:15 ` [PATCH 65/67] fsck: use for_each_loose_file_in_objdir Jeff King
2015-09-15 16:16 ` [PATCH 66/67] use strbuf_complete to conditionally append slash Jeff King
2015-09-16 22:18 ` Junio C Hamano
2015-09-16 22:39 ` Jeff King
2015-09-16 22:54 ` Junio C Hamano
2015-09-16 22:57 ` Jeff King
2015-09-17 15:45 ` Junio C Hamano
2015-09-21 1:50 ` Eric Sunshine
2015-09-21 15:17 ` Jeff King
2015-09-15 16:16 ` [PATCH 67/67] name-rev: use strip_suffix to avoid magic numbers Jeff King
2015-09-16 1:54 ` [PATCH 0/67] war on sprintf, strcpy, etc Junio C Hamano
2015-09-16 10:35 ` Jeff King
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20150915160956.GD29753@sigill.intra.peff.net \
--to=peff@peff.net \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).