* [PATCH 0/3] hash-object crash fix and new doc and tests
@ 2015-05-04 7:25 Eric Sunshine
2015-05-04 7:25 ` [PATCH 1/3] git-hash-object.txt: document --literally option Eric Sunshine
` (3 more replies)
0 siblings, 4 replies; 15+ messages in thread
From: Eric Sunshine @ 2015-05-04 7:25 UTC (permalink / raw)
To: git; +Cc: Eric Sunshine, Junio C Hamano, Karthik Nayak
This patch series fixes a buffer overrun triggered by an extra-long
bogus object type specified via hash-object --literally.
It also adds documentation and tests which were missing from the initial
series which introduced "hash-object --literally".
Eric Sunshine (3):
git-hash-object.txt: document --literally option
t1007: add hash-object --literally tests
write_sha1_file_prepare: fix buffer overrun with extra-long object
type
Documentation/git-hash-object.txt | 10 ++++++++--
sha1_file.c | 21 ++++++++++-----------
t/t1007-hash-object.sh | 11 +++++++++++
3 files changed, 29 insertions(+), 13 deletions(-)
--
2.4.0.319.g7a04823
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 1/3] git-hash-object.txt: document --literally option
2015-05-04 7:25 [PATCH 0/3] hash-object crash fix and new doc and tests Eric Sunshine
@ 2015-05-04 7:25 ` Eric Sunshine
2015-05-04 7:25 ` [PATCH 2/3] t1007: add hash-object --literally tests Eric Sunshine
` (2 subsequent siblings)
3 siblings, 0 replies; 15+ messages in thread
From: Eric Sunshine @ 2015-05-04 7:25 UTC (permalink / raw)
To: git; +Cc: Eric Sunshine, Junio C Hamano, Karthik Nayak
Document the git-hash-object --literally option added by 5ba9a93
(hash-object: add --literally option, 2014-09-11).
While here, also correct a minor typesetting oversight.
Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
---
I used Junio's commit message from 5ba9a93 as the basis of the
documentation for --literally and then expanded upon it.
Documentation/git-hash-object.txt | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/Documentation/git-hash-object.txt b/Documentation/git-hash-object.txt
index 02c1f12..0c75f3b 100644
--- a/Documentation/git-hash-object.txt
+++ b/Documentation/git-hash-object.txt
@@ -9,7 +9,7 @@ git-hash-object - Compute object ID and optionally creates a blob from a file
SYNOPSIS
--------
[verse]
-'git hash-object' [-t <type>] [-w] [--path=<file>|--no-filters] [--stdin] [--] <file>...
+'git hash-object' [-t <type>] [-w] [--path=<file>|--no-filters] [--stdin [--literally]] [--] <file>...
'git hash-object' [-t <type>] [-w] --stdin-paths [--no-filters] < <list-of-paths>
DESCRIPTION
@@ -51,7 +51,13 @@ OPTIONS
Hash the contents as is, ignoring any input filter that would
have been chosen by the attributes mechanism, including the end-of-line
conversion. If the file is read from standard input then this
- is always implied, unless the --path option is given.
+ is always implied, unless the `--path` option is given.
+
+--literally::
+ Allow `--stdin` to hash any garbage into a loose object which might not
+ otherwise pass standard object parsing or git-fsck checks. Useful for
+ stress-testing Git itself or reproducing characteristics of corrupt or
+ bogus objects encountered in the wild.
GIT
---
--
2.4.0.319.g7a04823
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 2/3] t1007: add hash-object --literally tests
2015-05-04 7:25 [PATCH 0/3] hash-object crash fix and new doc and tests Eric Sunshine
2015-05-04 7:25 ` [PATCH 1/3] git-hash-object.txt: document --literally option Eric Sunshine
@ 2015-05-04 7:25 ` Eric Sunshine
2015-05-04 7:25 ` [PATCH 3/3] write_sha1_file_prepare: fix buffer overrun with extra-long object type Eric Sunshine
2015-05-04 21:37 ` [PATCH 0/4] "hash-object --literally" fixes Junio C Hamano
3 siblings, 0 replies; 15+ messages in thread
From: Eric Sunshine @ 2015-05-04 7:25 UTC (permalink / raw)
To: git; +Cc: Eric Sunshine, Junio C Hamano, Karthik Nayak
git-hash-object learned a --literally option in 5ba9a93 (hash-object:
add --literally option, 2014-09-11). Check that --literally allows
object creation with a bogus type.
Also add a failing test demonstrating a crash (buffer overflow leading
to stack corruption) when the bogus type is lengthy.
Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
---
Although the crash seems to have manifested[1] only on Mac OS X when
testing Karthik's "cat-file --allow-unknown-type" series, I made the
bogus object type extremely long in the failing test included here in
order to ensure that it manifests (hopefully) everywhere. At this
length, the crash manifest on Linux as well.
[1]: http://thread.gmane.org/gmane.comp.version-control.git/268262/focus=268304
t/t1007-hash-object.sh | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/t/t1007-hash-object.sh b/t/t1007-hash-object.sh
index f83df8e..0e65577 100755
--- a/t/t1007-hash-object.sh
+++ b/t/t1007-hash-object.sh
@@ -201,4 +201,15 @@ test_expect_success 'corrupt tag' '
test_must_fail git hash-object -t tag --stdin </dev/null
'
+test_expect_success '--literally' '
+ t=1234567890 &&
+ echo example | git hash-object -t $t --literally --stdin
+'
+
+test_expect_failure '--literally with extra-long type' '
+ t=12345678901234567890123456789012345678901234567890 &&
+ t="$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t" &&
+ echo example | git hash-object -t $t --literally --stdin
+'
+
test_done
--
2.4.0.319.g7a04823
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 3/3] write_sha1_file_prepare: fix buffer overrun with extra-long object type
2015-05-04 7:25 [PATCH 0/3] hash-object crash fix and new doc and tests Eric Sunshine
2015-05-04 7:25 ` [PATCH 1/3] git-hash-object.txt: document --literally option Eric Sunshine
2015-05-04 7:25 ` [PATCH 2/3] t1007: add hash-object --literally tests Eric Sunshine
@ 2015-05-04 7:25 ` Eric Sunshine
2015-05-04 17:58 ` Junio C Hamano
2015-05-04 21:37 ` [PATCH 0/4] "hash-object --literally" fixes Junio C Hamano
3 siblings, 1 reply; 15+ messages in thread
From: Eric Sunshine @ 2015-05-04 7:25 UTC (permalink / raw)
To: git; +Cc: Eric Sunshine, Junio C Hamano, Karthik Nayak
git-hash-object learned --literally in 5ba9a93 (hash-object: add
--literally option, 2014-09-11) which can be used to craft a
corrupt/broken object of unknown type. When the user-provided type is
particularly long, it can overflow the relatively small stack-based
character array handed to write_sha1_file_prepare() by hash_sha1_file()
and write_sha1_file(), leading to stack corruption (and crash).
Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
---
The composed 'hdr' is supposed to be NUL-terminated, and code which
accesses 'hdr' expects the NUL to be included as part of its length.
Although strbuf ensures that a NUL byte follows the string content, I
took the precaution of explicitly adding NUL when formulating 'hdr'
strbuf_addf(hdr, "%s %lu%c", type, len, '\0');
so that callers can just say hdr.len when the length is needed, rather
than having to remember to say hdr.len+1.
I haven't fully convinced myself that this fix is appropriate since it
penalizes _all_ callers of hash_sha1_file() and write_sha1_file() with
an extra heap allocation (via strbuf), even though "hash-object
--literally" is the only mechanism by which an overly-long object type
can arrive.
sha1_file.c | 21 ++++++++++-----------
t/t1007-hash-object.sh | 2 +-
2 files changed, 11 insertions(+), 12 deletions(-)
diff --git a/sha1_file.c b/sha1_file.c
index 88f06ba..6d3fa26 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -2795,16 +2795,16 @@ void *read_object_with_reference(const unsigned char *sha1,
static void write_sha1_file_prepare(const void *buf, unsigned long len,
const char *type, unsigned char *sha1,
- char *hdr, int *hdrlen)
+ struct strbuf *hdr)
{
git_SHA_CTX c;
/* Generate the header */
- *hdrlen = sprintf(hdr, "%s %lu", type, len)+1;
+ strbuf_addf(hdr, "%s %lu%c", type, len, '\0');
/* Sha1.. */
git_SHA1_Init(&c);
- git_SHA1_Update(&c, hdr, *hdrlen);
+ git_SHA1_Update(&c, hdr->buf, hdr->len);
git_SHA1_Update(&c, buf, len);
git_SHA1_Final(sha1, &c);
}
@@ -2865,9 +2865,8 @@ static int write_buffer(int fd, const void *buf, size_t len)
int hash_sha1_file(const void *buf, unsigned long len, const char *type,
unsigned char *sha1)
{
- char hdr[32];
- int hdrlen;
- write_sha1_file_prepare(buf, len, type, sha1, hdr, &hdrlen);
+ struct strbuf hdr = STRBUF_INIT;
+ write_sha1_file_prepare(buf, len, type, sha1, &hdr);
return 0;
}
@@ -3005,18 +3004,18 @@ static int freshen_packed_object(const unsigned char *sha1)
int write_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *returnsha1)
{
unsigned char sha1[20];
- char hdr[32];
- int hdrlen;
+ struct strbuf hdr = STRBUF_INIT;
- /* Normally if we have it in the pack then we do not bother writing
+ /*
+ * Normally if we have it in the pack then we do not bother writing
* it out into .git/objects/??/?{38} file.
*/
- write_sha1_file_prepare(buf, len, type, sha1, hdr, &hdrlen);
+ write_sha1_file_prepare(buf, len, type, sha1, &hdr);
if (returnsha1)
hashcpy(returnsha1, sha1);
if (freshen_loose_object(sha1) || freshen_packed_object(sha1))
return 0;
- return write_loose_object(sha1, hdr, hdrlen, buf, len, 0);
+ return write_loose_object(sha1, hdr.buf, hdr.len, buf, len, 0);
}
int force_object_loose(const unsigned char *sha1, time_t mtime)
diff --git a/t/t1007-hash-object.sh b/t/t1007-hash-object.sh
index 0e65577..7c3dcfb 100755
--- a/t/t1007-hash-object.sh
+++ b/t/t1007-hash-object.sh
@@ -206,7 +206,7 @@ test_expect_success '--literally' '
echo example | git hash-object -t $t --literally --stdin
'
-test_expect_failure '--literally with extra-long type' '
+test_expect_success '--literally with extra-long type' '
t=12345678901234567890123456789012345678901234567890 &&
t="$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t" &&
echo example | git hash-object -t $t --literally --stdin
--
2.4.0.319.g7a04823
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH 3/3] write_sha1_file_prepare: fix buffer overrun with extra-long object type
2015-05-04 7:25 ` [PATCH 3/3] write_sha1_file_prepare: fix buffer overrun with extra-long object type Eric Sunshine
@ 2015-05-04 17:58 ` Junio C Hamano
2015-05-04 17:59 ` Junio C Hamano
0 siblings, 1 reply; 15+ messages in thread
From: Junio C Hamano @ 2015-05-04 17:58 UTC (permalink / raw)
To: Eric Sunshine; +Cc: git, Karthik Nayak
Eric Sunshine <sunshine@sunshineco.com> writes:
> git-hash-object learned --literally in 5ba9a93 (hash-object: add
> --literally option, 2014-09-11) which can be used to craft a
> corrupt/broken object of unknown type. When the user-provided type is
> particularly long, it can overflow the relatively small stack-based
> character array handed to write_sha1_file_prepare() by hash_sha1_file()
> and write_sha1_file(), leading to stack corruption (and crash).
>
> Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
Thanks.
> ---
>
> The composed 'hdr' is supposed to be NUL-terminated, and code which
> accesses 'hdr' expects the NUL to be included as part of its length.
> Although strbuf ensures that a NUL byte follows the string content, I
> took the precaution of explicitly adding NUL when formulating 'hdr'
>
> strbuf_addf(hdr, "%s %lu%c", type, len, '\0');
>
> so that callers can just say hdr.len when the length is needed, rather
> than having to remember to say hdr.len+1.
That is unnecessary and may turn out to be more confusing than it is
worth in the long run; though I do not think it matters too much.
> I haven't fully convinced myself that this fix is appropriate since it
> penalizes _all_ callers of hash_sha1_file() and write_sha1_file() with
> an extra heap allocation (via strbuf), even though "hash-object
> --literally" is the only mechanism by which an overly-long object type
> can arrive.
I am moderately unhappy about fixing it this way for the exact
reason you stated aboe.
write_sha1_file_prepare() can stay the same as before, and we can
use a variant of hash_sha1_file() only when doing the --literally
thing to use a special allocation. Perhaps like this?
The patch was done on top of yours; it reverts the change to
write_sha1_file_prepare() and its callers, and instead adds a
separate helper. We may want to restructure the latter half of
write_sha1_file() that does the freshen-or-write into a helper
function to share more logic, though.
diff --git a/builtin/hash-object.c b/builtin/hash-object.c
index 207b90c..ef383e1 100644
--- a/builtin/hash-object.c
+++ b/builtin/hash-object.c
@@ -22,10 +22,8 @@ static int hash_literally(unsigned char *sha1, int fd, const char *type, unsigne
if (strbuf_read(&buf, fd, 4096) < 0)
ret = -1;
- else if (flags & HASH_WRITE_OBJECT)
- ret = write_sha1_file(buf.buf, buf.len, type, sha1);
else
- ret = hash_sha1_file(buf.buf, buf.len, type, sha1);
+ ret = hash_sha1_file_literally(&buf, type, sha1, flags);
strbuf_release(&buf);
return ret;
}
diff --git a/cache.h b/cache.h
index 3d3244b..a37423e 100644
--- a/cache.h
+++ b/cache.h
@@ -874,6 +874,7 @@ static inline const unsigned char *lookup_replace_object_extended(const unsigned
extern int sha1_object_info(const unsigned char *, unsigned long *);
extern int hash_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *sha1);
extern int write_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *return_sha1);
+extern int hash_sha1_file_literally(struct strbuf *buf, const char *type, unsigned char *return_sha1, unsigned flags);
extern int pretend_sha1_file(void *, unsigned long, enum object_type, unsigned char *);
extern int force_object_loose(const unsigned char *sha1, time_t mtime);
extern int git_open_noatime(const char *name);
diff --git a/sha1_file.c b/sha1_file.c
index 6d3fa26..c8ab069 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -2795,16 +2795,16 @@ void *read_object_with_reference(const unsigned char *sha1,
static void write_sha1_file_prepare(const void *buf, unsigned long len,
const char *type, unsigned char *sha1,
- struct strbuf *hdr)
+ char *hdr, int *hdrlen)
{
git_SHA_CTX c;
/* Generate the header */
- strbuf_addf(hdr, "%s %lu%c", type, len, '\0');
+ *hdrlen = sprintf(hdr, "%s %lu", type, len)+1;
/* Sha1.. */
git_SHA1_Init(&c);
- git_SHA1_Update(&c, hdr->buf, hdr->len);
+ git_SHA1_Update(&c, hdr, *hdrlen);
git_SHA1_Update(&c, buf, len);
git_SHA1_Final(sha1, &c);
}
@@ -2865,8 +2865,9 @@ static int write_buffer(int fd, const void *buf, size_t len)
int hash_sha1_file(const void *buf, unsigned long len, const char *type,
unsigned char *sha1)
{
- struct strbuf hdr = STRBUF_INIT;
- write_sha1_file_prepare(buf, len, type, sha1, &hdr);
+ char hdr[32];
+ int hdrlen;
+ write_sha1_file_prepare(buf, len, type, sha1, hdr, &hdrlen);
return 0;
}
@@ -3004,18 +3005,43 @@ static int freshen_packed_object(const unsigned char *sha1)
int write_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *returnsha1)
{
unsigned char sha1[20];
- struct strbuf hdr = STRBUF_INIT;
+ char hdr[32];
+ int hdrlen;
- /*
- * Normally if we have it in the pack then we do not bother writing
+ /* Normally if we have it in the pack then we do not bother writing
* it out into .git/objects/??/?{38} file.
*/
- write_sha1_file_prepare(buf, len, type, sha1, &hdr);
+ write_sha1_file_prepare(buf, len, type, sha1, hdr, &hdrlen);
if (returnsha1)
hashcpy(returnsha1, sha1);
if (freshen_loose_object(sha1) || freshen_packed_object(sha1))
return 0;
- return write_loose_object(sha1, hdr.buf, hdr.len, buf, len, 0);
+ return write_loose_object(sha1, hdr, hdrlen, buf, len, 0);
+}
+
+int hash_sha1_file_literally(struct strbuf *buf, const char *type,
+ unsigned char *sha1, unsigned flags)
+{
+ struct strbuf header = STRBUF_INIT;
+ int hdrlen, status = 0;
+
+ /* type string, SP, %lu of the length plus NUL must fit this */
+ strbuf_grow(&header, strlen(type) + 20);
+
+ write_sha1_file_prepare(buf->buf, buf->len, type, sha1,
+ header.buf, &hdrlen);
+
+ if (!(flags & HASH_WRITE_OBJECT))
+ goto cleanup;
+
+ if (freshen_loose_object(sha1) || freshen_packed_object(sha1))
+ goto cleanup;
+ status = write_loose_object(sha1, header.buf, hdrlen,
+ buf->buf, buf->len, 0);
+
+cleanup:
+ strbuf_release(&header);
+ return status;
}
int force_object_loose(const unsigned char *sha1, time_t mtime)
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH 3/3] write_sha1_file_prepare: fix buffer overrun with extra-long object type
2015-05-04 17:58 ` Junio C Hamano
@ 2015-05-04 17:59 ` Junio C Hamano
0 siblings, 0 replies; 15+ messages in thread
From: Junio C Hamano @ 2015-05-04 17:59 UTC (permalink / raw)
To: Eric Sunshine; +Cc: git, Karthik Nayak
By the way, you would notice that "if we have returnsha1, then copy
that in" bit is not in the new literally codepath but still is in
write_sha1_file().
I do not think any caller passes a NULL as return_sha1 in today's
code, which made me curious.
It turns out to be a remnant of d6d3f9d0 (This implements the new
"recursive tree" write-tree., 2005-04-09); before that change,
write_sha1_file() did not have an ability to tell the caller what
object it wrote, and Linus made it optional for the callers when he
added the return_sha1[] out parameter, but all of its callers did
want the resulting object name.
So I think it is safe and sensible to do the following change
regardless of "hash-object --literally" fix.
sha1_file.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/sha1_file.c b/sha1_file.c
index c8ab069..96e813f 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -3002,9 +3002,8 @@ static int freshen_packed_object(const unsigned char *sha1)
return find_pack_entry(sha1, &e) && freshen_file(e.p->pack_name);
}
-int write_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *returnsha1)
+int write_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *sha1)
{
- unsigned char sha1[20];
char hdr[32];
int hdrlen;
@@ -3012,8 +3011,6 @@ int write_sha1_file(const void *buf, unsigned long len, const char *type, unsign
* it out into .git/objects/??/?{38} file.
*/
write_sha1_file_prepare(buf, len, type, sha1, hdr, &hdrlen);
- if (returnsha1)
- hashcpy(returnsha1, sha1);
if (freshen_loose_object(sha1) || freshen_packed_object(sha1))
return 0;
return write_loose_object(sha1, hdr, hdrlen, buf, len, 0);
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 0/4] "hash-object --literally" fixes
2015-05-04 7:25 [PATCH 0/3] hash-object crash fix and new doc and tests Eric Sunshine
` (2 preceding siblings ...)
2015-05-04 7:25 ` [PATCH 3/3] write_sha1_file_prepare: fix buffer overrun with extra-long object type Eric Sunshine
@ 2015-05-04 21:37 ` Junio C Hamano
2015-05-04 21:37 ` [PATCH 1/4] git-hash-object.txt: document --literally option Junio C Hamano
` (3 more replies)
3 siblings, 4 replies; 15+ messages in thread
From: Junio C Hamano @ 2015-05-04 21:37 UTC (permalink / raw)
To: git; +Cc: Eric Sunshine
This is a rework of Eric's fix (Thanks!), to avoid using strbuf all
the time, even when we are not doing "hash-object --literally".
Eric Sunshine (3):
git-hash-object.txt: document --literally option
write_sha1_file_prepare: fix buffer overrun with extra-long object type
t1007: add hash-object --literally tests
Junio C Hamano (1):
write_sha1_file(): do not use a separate sha1[] array
Documentation/git-hash-object.txt | 10 ++++++++--
builtin/hash-object.c | 4 +---
cache.h | 1 +
sha1_file.c | 32 +++++++++++++++++++++++++++-----
t/t1007-hash-object.sh | 11 +++++++++++
5 files changed, 48 insertions(+), 10 deletions(-)
--
2.4.0-302-g6743426
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 1/4] git-hash-object.txt: document --literally option
2015-05-04 21:37 ` [PATCH 0/4] "hash-object --literally" fixes Junio C Hamano
@ 2015-05-04 21:37 ` Junio C Hamano
2015-05-04 21:37 ` [PATCH 2/4] write_sha1_file_prepare: fix buffer overrun with extra-long object type Junio C Hamano
` (2 subsequent siblings)
3 siblings, 0 replies; 15+ messages in thread
From: Junio C Hamano @ 2015-05-04 21:37 UTC (permalink / raw)
To: git; +Cc: Eric Sunshine
From: Eric Sunshine <sunshine@sunshineco.com>
Document the git-hash-object --literally option added by 5ba9a93
(hash-object: add --literally option, 2014-09-11).
While here, also correct a minor typesetting oversight.
Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
* As posted by Eric
Documentation/git-hash-object.txt | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/Documentation/git-hash-object.txt b/Documentation/git-hash-object.txt
index 02c1f12..0c75f3b 100644
--- a/Documentation/git-hash-object.txt
+++ b/Documentation/git-hash-object.txt
@@ -9,7 +9,7 @@ git-hash-object - Compute object ID and optionally creates a blob from a file
SYNOPSIS
--------
[verse]
-'git hash-object' [-t <type>] [-w] [--path=<file>|--no-filters] [--stdin] [--] <file>...
+'git hash-object' [-t <type>] [-w] [--path=<file>|--no-filters] [--stdin [--literally]] [--] <file>...
'git hash-object' [-t <type>] [-w] --stdin-paths [--no-filters] < <list-of-paths>
DESCRIPTION
@@ -51,7 +51,13 @@ OPTIONS
Hash the contents as is, ignoring any input filter that would
have been chosen by the attributes mechanism, including the end-of-line
conversion. If the file is read from standard input then this
- is always implied, unless the --path option is given.
+ is always implied, unless the `--path` option is given.
+
+--literally::
+ Allow `--stdin` to hash any garbage into a loose object which might not
+ otherwise pass standard object parsing or git-fsck checks. Useful for
+ stress-testing Git itself or reproducing characteristics of corrupt or
+ bogus objects encountered in the wild.
GIT
---
--
2.4.0-302-g6743426
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 2/4] write_sha1_file_prepare: fix buffer overrun with extra-long object type
2015-05-04 21:37 ` [PATCH 0/4] "hash-object --literally" fixes Junio C Hamano
2015-05-04 21:37 ` [PATCH 1/4] git-hash-object.txt: document --literally option Junio C Hamano
@ 2015-05-04 21:37 ` Junio C Hamano
2015-05-05 0:13 ` Eric Sunshine
2015-05-04 21:37 ` [PATCH 3/4] t1007: add hash-object --literally tests Junio C Hamano
2015-05-04 21:37 ` [PATCH 4/4] write_sha1_file(): do not use a separate sha1[] array Junio C Hamano
3 siblings, 1 reply; 15+ messages in thread
From: Junio C Hamano @ 2015-05-04 21:37 UTC (permalink / raw)
To: git; +Cc: Eric Sunshine
From: Eric Sunshine <sunshine@sunshineco.com>
git-hash-object learned --literally in 5ba9a93 (hash-object: add
--literally option, 2014-09-11) which can be used to craft a
corrupt/broken object of unknown type.
When the user-provided type is particularly long, however, it can
overflow the relatively small stack-based character array handed to
write_sha1_file_prepare() by hash_sha1_file() and write_sha1_file(),
leading to stack corruption (and crash).
Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
* Tweaked and backported directly on top of 5ba9a93b (hash-object:
add --literally option, 2014-09-11) which is v2.2.0-rc0~88^2
builtin/hash-object.c | 4 +---
cache.h | 1 +
sha1_file.c | 27 ++++++++++++++++++++++++++-
3 files changed, 28 insertions(+), 4 deletions(-)
diff --git a/builtin/hash-object.c b/builtin/hash-object.c
index 6158363..887a8ea 100644
--- a/builtin/hash-object.c
+++ b/builtin/hash-object.c
@@ -22,10 +22,8 @@ static int hash_literally(unsigned char *sha1, int fd, const char *type, unsigne
if (strbuf_read(&buf, fd, 4096) < 0)
ret = -1;
- else if (flags & HASH_WRITE_OBJECT)
- ret = write_sha1_file(buf.buf, buf.len, type, sha1);
else
- ret = hash_sha1_file(buf.buf, buf.len, type, sha1);
+ ret = hash_sha1_file_literally(&buf, type, sha1, flags);
strbuf_release(&buf);
return ret;
}
diff --git a/cache.h b/cache.h
index dfa1a56..2da7740 100644
--- a/cache.h
+++ b/cache.h
@@ -888,6 +888,7 @@ static inline const unsigned char *lookup_replace_object_extended(const unsigned
extern int sha1_object_info(const unsigned char *, unsigned long *);
extern int hash_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *sha1);
extern int write_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *return_sha1);
+extern int hash_sha1_file_literally(struct strbuf *buf, const char *type, unsigned char *return_sha1, unsigned flags);
extern int pretend_sha1_file(void *, unsigned long, enum object_type, unsigned char *);
extern int force_object_loose(const unsigned char *sha1, time_t mtime);
extern int git_open_noatime(const char *name);
diff --git a/sha1_file.c b/sha1_file.c
index c08c0cb..0fe3f29 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -2962,6 +2962,31 @@ int write_sha1_file(const void *buf, unsigned long len, const char *type, unsign
return write_loose_object(sha1, hdr, hdrlen, buf, len, 0);
}
+int hash_sha1_file_literally(struct strbuf *buf, const char *type,
+ unsigned char *sha1, unsigned flags)
+{
+ struct strbuf header = STRBUF_INIT;
+ int hdrlen, status = 0;
+
+ /* type string, SP, %lu of the length plus NUL must fit this */
+ strbuf_grow(&header, strlen(type) + 20);
+
+ write_sha1_file_prepare(buf->buf, buf->len, type, sha1,
+ header.buf, &hdrlen);
+
+ if (!(flags & HASH_WRITE_OBJECT))
+ goto cleanup;
+
+ if (has_sha1_file(sha1))
+ goto cleanup;
+ status = write_loose_object(sha1, header.buf, hdrlen,
+ buf->buf, buf->len, 0);
+
+cleanup:
+ strbuf_release(&header);
+ return status;
+}
+
int force_object_loose(const unsigned char *sha1, time_t mtime)
{
void *buf;
--
2.4.0-302-g6743426
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 3/4] t1007: add hash-object --literally tests
2015-05-04 21:37 ` [PATCH 0/4] "hash-object --literally" fixes Junio C Hamano
2015-05-04 21:37 ` [PATCH 1/4] git-hash-object.txt: document --literally option Junio C Hamano
2015-05-04 21:37 ` [PATCH 2/4] write_sha1_file_prepare: fix buffer overrun with extra-long object type Junio C Hamano
@ 2015-05-04 21:37 ` Junio C Hamano
2015-05-04 21:37 ` [PATCH 4/4] write_sha1_file(): do not use a separate sha1[] array Junio C Hamano
3 siblings, 0 replies; 15+ messages in thread
From: Junio C Hamano @ 2015-05-04 21:37 UTC (permalink / raw)
To: git; +Cc: Eric Sunshine
From: Eric Sunshine <sunshine@sunshineco.com>
git-hash-object learned a --literally option in 5ba9a93
(hash-object: add --literally option, 2014-09-11). Check that
--literally allows object creation with a bogus type, with two
type strings whose length is reasonably short and very long.
Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
* Almost as posted by Eric, but the fix happens earlier in the
series so both tests expect to succeed.
t/t1007-hash-object.sh | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/t/t1007-hash-object.sh b/t/t1007-hash-object.sh
index f83df8e..7c3dcfb 100755
--- a/t/t1007-hash-object.sh
+++ b/t/t1007-hash-object.sh
@@ -201,4 +201,15 @@ test_expect_success 'corrupt tag' '
test_must_fail git hash-object -t tag --stdin </dev/null
'
+test_expect_success '--literally' '
+ t=1234567890 &&
+ echo example | git hash-object -t $t --literally --stdin
+'
+
+test_expect_success '--literally with extra-long type' '
+ t=12345678901234567890123456789012345678901234567890 &&
+ t="$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t" &&
+ echo example | git hash-object -t $t --literally --stdin
+'
+
test_done
--
2.4.0-302-g6743426
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 4/4] write_sha1_file(): do not use a separate sha1[] array
2015-05-04 21:37 ` [PATCH 0/4] "hash-object --literally" fixes Junio C Hamano
` (2 preceding siblings ...)
2015-05-04 21:37 ` [PATCH 3/4] t1007: add hash-object --literally tests Junio C Hamano
@ 2015-05-04 21:37 ` Junio C Hamano
3 siblings, 0 replies; 15+ messages in thread
From: Junio C Hamano @ 2015-05-04 21:37 UTC (permalink / raw)
To: git
In the beginning, write_sha1_file() did not have a way to tell the
caller the name of the object it wrote to the caller. This was
changed in d6d3f9d0 (This implements the new "recursive tree"
write-tree., 2005-04-09) by adding the "returnsha1" parameter to the
function so that the callers who are interested in the value can
optionally pass a pointer to receive it.
It turns out that all callers do want to know the name of the object
it just has written. Nobody passes a NULL to this parameter, hence
it is not necessary to use a separate sha1[] array to receive the
result from write_sha1_file_prepare(), and copy the result to the
returnsha1 supplied by the caller.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
* This is something I noticed while in the vicinity.
sha1_file.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/sha1_file.c b/sha1_file.c
index 0fe3f29..cec0ef2 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -2945,9 +2945,8 @@ static int write_loose_object(const unsigned char *sha1, char *hdr, int hdrlen,
return move_temp_to_file(tmp_file, filename);
}
-int write_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *returnsha1)
+int write_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *sha1)
{
- unsigned char sha1[20];
char hdr[32];
int hdrlen;
@@ -2955,8 +2954,6 @@ int write_sha1_file(const void *buf, unsigned long len, const char *type, unsign
* it out into .git/objects/??/?{38} file.
*/
write_sha1_file_prepare(buf, len, type, sha1, hdr, &hdrlen);
- if (returnsha1)
- hashcpy(returnsha1, sha1);
if (has_sha1_file(sha1))
return 0;
return write_loose_object(sha1, hdr, hdrlen, buf, len, 0);
--
2.4.0-302-g6743426
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH 2/4] write_sha1_file_prepare: fix buffer overrun with extra-long object type
2015-05-04 21:37 ` [PATCH 2/4] write_sha1_file_prepare: fix buffer overrun with extra-long object type Junio C Hamano
@ 2015-05-05 0:13 ` Eric Sunshine
2015-05-05 0:28 ` Junio C Hamano
2015-05-05 17:30 ` Junio C Hamano
0 siblings, 2 replies; 15+ messages in thread
From: Eric Sunshine @ 2015-05-05 0:13 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Git List
On Mon, May 4, 2015 at 5:37 PM, Junio C Hamano <gitster@pobox.com> wrote:
> From: Eric Sunshine <sunshine@sunshineco.com>
Thanks for re-rerolling this series. Considering that the only bits
left from me are the diagnosis and the (mostly intact) commit message,
perhaps the authorship should be changed, or at the very least a big
"Helped-by: Junio" added? Anyhow, a few minor comments below...
> write_sha1_file_prepare: fix buffer overrun with extra-long object type
Although the overrun happened in write_sha1_file_prepare(), that
function is no longer the focus of the patch. Would make sense to
rephrase the subject more generally as:
sha1_file: fix buffer overrun with extra-long object type
or something.
More below.
> git-hash-object learned --literally in 5ba9a93 (hash-object: add
> --literally option, 2014-09-11) which can be used to craft a
> corrupt/broken object of unknown type.
>
> When the user-provided type is particularly long, however, it can
> overflow the relatively small stack-based character array handed to
> write_sha1_file_prepare() by hash_sha1_file() and write_sha1_file(),
> leading to stack corruption (and crash).
>
> Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
> Signed-off-by: Junio C Hamano <gitster@pobox.com>
> ---
> diff --git a/cache.h b/cache.h
> index dfa1a56..2da7740 100644
> --- a/cache.h
> +++ b/cache.h
> @@ -888,6 +888,7 @@ static inline const unsigned char *lookup_replace_object_extended(const unsigned
> extern int sha1_object_info(const unsigned char *, unsigned long *);
> extern int hash_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *sha1);
> extern int write_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *return_sha1);
> +extern int hash_sha1_file_literally(struct strbuf *buf, const char *type, unsigned char *return_sha1, unsigned flags);
A few questions:
What's the value of making the first argument of
hash_sha1_file_literally() a strbuf rather than the two-argument buf &
len accepted by hash_sha1_file() and write_sha1_file()? Is the
inconsistency warranted?
Would it make sense to name the third argument "sha1" instead of
"return_sha1" to match the argument name of hash_sha1_file()?
And, as an aside, should your new patch 4/4 rename "return_sha1" to
"sha1" in the write_sha1_file() prototype also?
> extern int pretend_sha1_file(void *, unsigned long, enum object_type, unsigned char *);
> extern int force_object_loose(const unsigned char *sha1, time_t mtime);
> extern int git_open_noatime(const char *name);
> diff --git a/sha1_file.c b/sha1_file.c
> index c08c0cb..0fe3f29 100644
> --- a/sha1_file.c
> +++ b/sha1_file.c
> @@ -2962,6 +2962,31 @@ int write_sha1_file(const void *buf, unsigned long len, const char *type, unsign
> return write_loose_object(sha1, hdr, hdrlen, buf, len, 0);
> }
>
> +int hash_sha1_file_literally(struct strbuf *buf, const char *type,
> + unsigned char *sha1, unsigned flags)
> +{
> + struct strbuf header = STRBUF_INIT;
> + int hdrlen, status = 0;
> +
> + /* type string, SP, %lu of the length plus NUL must fit this */
> + strbuf_grow(&header, strlen(type) + 20);
A couple comments:
First, given that the largest 64-bit unsigned long value
(18,446,744,073,709,551,615) is 20 characters, do we want to be really
pedantic and add 22 instead of 20?
Second, is strbuf overkill in this situation when a simple
xmalloc()/free() would do?
> + write_sha1_file_prepare(buf->buf, buf->len, type, sha1,
> + header.buf, &hdrlen);
> +
> + if (!(flags & HASH_WRITE_OBJECT))
> + goto cleanup;
> +
> + if (has_sha1_file(sha1))
> + goto cleanup;
> + status = write_loose_object(sha1, header.buf, hdrlen,
> + buf->buf, buf->len, 0);
> +
> +cleanup:
> + strbuf_release(&header);
> + return status;
> +}
> +
> int force_object_loose(const unsigned char *sha1, time_t mtime)
> {
> void *buf;
> --
> 2.4.0-302-g6743426
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 2/4] write_sha1_file_prepare: fix buffer overrun with extra-long object type
2015-05-05 0:13 ` Eric Sunshine
@ 2015-05-05 0:28 ` Junio C Hamano
2015-05-05 17:30 ` Junio C Hamano
1 sibling, 0 replies; 15+ messages in thread
From: Junio C Hamano @ 2015-05-05 0:28 UTC (permalink / raw)
To: Eric Sunshine; +Cc: Git List
Eric Sunshine <sunshine@sunshineco.com> writes:
>> +extern int hash_sha1_file_literally(struct strbuf *buf, const char
>> *type, unsigned char *return_sha1, unsigned flags);
>
> A few questions:
>
> What's the value of making the first argument of
> hash_sha1_file_literally() a strbuf rather than the two-argument
> buf & len accepted by hash_sha1_file() and write_sha1_file()? Is
> the inconsistency warranted?
I do not care either way, as this is really meant to be a
single-purpose wrapper for a single caller.
> Would it make sense to name the third argument "sha1" instead of
> "return_sha1" to match the argument name of hash_sha1_file()?
>
> And, as an aside, should your new patch 4/4 rename "return_sha1" to
> "sha1" in the write_sha1_file() prototype also?
Because most of the read-cache.c functions take object name and do
something about it, but these small number of functions compute and
return object name, I actually think it is a good way to keep
"return" in the name to remind those who are writing or reading
callers.
>> + /* type string, SP, %lu of the length plus NUL must fit this */
>> + strbuf_grow(&header, strlen(type) + 20);
>
> A couple comments:
>
> First, given that the largest 64-bit unsigned long value
> (18,446,744,073,709,551,615) is 20 characters, do we want to be really
> pedantic and add 22 instead of 20?
32 is fine ;-)
> Second, is strbuf overkill in this situation when a simple
> xmalloc()/free() would do?
I think underneath the number of xmalloc()/free() calls are the
same. The code that uses strbuf abstraction is easier to read, I
would think.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 2/4] write_sha1_file_prepare: fix buffer overrun with extra-long object type
2015-05-05 0:13 ` Eric Sunshine
2015-05-05 0:28 ` Junio C Hamano
@ 2015-05-05 17:30 ` Junio C Hamano
2015-05-05 18:49 ` Eric Sunshine
1 sibling, 1 reply; 15+ messages in thread
From: Junio C Hamano @ 2015-05-05 17:30 UTC (permalink / raw)
To: Eric Sunshine; +Cc: Git List
Eric Sunshine <sunshine@sunshineco.com> writes:
> On Mon, May 4, 2015 at 5:37 PM, Junio C Hamano <gitster@pobox.com> wrote:
>> From: Eric Sunshine <sunshine@sunshineco.com>
>
> Thanks for re-rerolling this series. Considering that the only bits
> left from me are the diagnosis and the (mostly intact) commit message,
> perhaps the authorship should be changed, or at the very least a big
> "Helped-by: Junio" added? Anyhow, a few minor comments below...
I am a bit too lazy to take the ownership, so I decided only to take
the blame ;-)
Here is a replacement; all the other patches stay the same.
-- >8 --
From: Eric Sunshine <sunshine@sunshineco.com>
Date: Mon, 4 May 2015 03:25:15 -0400
Subject: [PATCH] hash-object --literally: fix buffer overrun with extra-long object type
"hash-object" learned in 5ba9a93 (hash-object: add --literally
option, 2014-09-11) to allow crafting a corrupt/broken object of
unknown type.
When the user-provided type is particularly long, however, it can
overflow the relatively small stack-based character array handed to
write_sha1_file_prepare() by hash_sha1_file() and write_sha1_file(),
leading to stack corruption (and crash). Introduce a custom helper
to allow arbitrarily long typenames just for "hash-object --literally".
[jc: Eric's original used a strbuf in the more common codepaths, and
I rewrote it to avoid penalizing the non-literally code. Bugs are mine]
Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
builtin/hash-object.c | 4 +---
cache.h | 1 +
sha1_file.c | 21 +++++++++++++++++++++
3 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/builtin/hash-object.c b/builtin/hash-object.c
index 6158363..17e8bfdc 100644
--- a/builtin/hash-object.c
+++ b/builtin/hash-object.c
@@ -22,10 +22,8 @@ static int hash_literally(unsigned char *sha1, int fd, const char *type, unsigne
if (strbuf_read(&buf, fd, 4096) < 0)
ret = -1;
- else if (flags & HASH_WRITE_OBJECT)
- ret = write_sha1_file(buf.buf, buf.len, type, sha1);
else
- ret = hash_sha1_file(buf.buf, buf.len, type, sha1);
+ ret = hash_sha1_file_literally(buf.buf, buf.len, type, sha1, flags);
strbuf_release(&buf);
return ret;
}
diff --git a/cache.h b/cache.h
index dfa1a56..e037cad 100644
--- a/cache.h
+++ b/cache.h
@@ -888,6 +888,7 @@ static inline const unsigned char *lookup_replace_object_extended(const unsigned
extern int sha1_object_info(const unsigned char *, unsigned long *);
extern int hash_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *sha1);
extern int write_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *return_sha1);
+extern int hash_sha1_file_literally(const void *buf, unsigned long len, const char *type, unsigned char *sha1, unsigned flags);
extern int pretend_sha1_file(void *, unsigned long, enum object_type, unsigned char *);
extern int force_object_loose(const unsigned char *sha1, time_t mtime);
extern int git_open_noatime(const char *name);
diff --git a/sha1_file.c b/sha1_file.c
index c08c0cb..dc940e6 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -2962,6 +2962,27 @@ int write_sha1_file(const void *buf, unsigned long len, const char *type, unsign
return write_loose_object(sha1, hdr, hdrlen, buf, len, 0);
}
+int hash_sha1_file_literally(const void *buf, unsigned long len, const char *type,
+ unsigned char *sha1, unsigned flags)
+{
+ char *header;
+ int hdrlen, status = 0;
+
+ /* type string, SP, %lu of the length plus NUL must fit this */
+ header = xmalloc(strlen(type) + 32);
+ write_sha1_file_prepare(buf, len, type, sha1, header, &hdrlen);
+
+ if (!(flags & HASH_WRITE_OBJECT))
+ goto cleanup;
+ if (has_sha1_file(sha1))
+ goto cleanup;
+ status = write_loose_object(sha1, header, hdrlen, buf, len, 0);
+
+cleanup:
+ free(header);
+ return status;
+}
+
int force_object_loose(const unsigned char *sha1, time_t mtime)
{
void *buf;
--
2.4.0-311-gf1d9b8d
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH 2/4] write_sha1_file_prepare: fix buffer overrun with extra-long object type
2015-05-05 17:30 ` Junio C Hamano
@ 2015-05-05 18:49 ` Eric Sunshine
0 siblings, 0 replies; 15+ messages in thread
From: Eric Sunshine @ 2015-05-05 18:49 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Git List
On Tue, May 5, 2015 at 1:30 PM, Junio C Hamano <gitster@pobox.com> wrote:
> From: Eric Sunshine <sunshine@sunshineco.com>
> Date: Mon, 4 May 2015 03:25:15 -0400
> Subject: [PATCH] hash-object --literally: fix buffer overrun with extra-long object type
>
> "hash-object" learned in 5ba9a93 (hash-object: add --literally
> option, 2014-09-11) to allow crafting a corrupt/broken object of
> unknown type.
>
> When the user-provided type is particularly long, however, it can
> overflow the relatively small stack-based character array handed to
> write_sha1_file_prepare() by hash_sha1_file() and write_sha1_file(),
> leading to stack corruption (and crash). Introduce a custom helper
> to allow arbitrarily long typenames just for "hash-object --literally".
>
> [jc: Eric's original used a strbuf in the more common codepaths, and
> I rewrote it to avoid penalizing the non-literally code. Bugs are mine]
Thanks for re-rolling again. The amended Subject: works nicely now,
and the addition to the commit message makes sense. Also, the code
changes in response to the minor questions I raised[1] all look good.
[1]: http://thread.gmane.org/gmane.comp.version-control.git/268306/focus=268374
(rest of patch left unsnipped)
> Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
> Signed-off-by: Junio C Hamano <gitster@pobox.com>
> ---
> diff --git a/builtin/hash-object.c b/builtin/hash-object.c
> index 6158363..17e8bfdc 100644
> --- a/builtin/hash-object.c
> +++ b/builtin/hash-object.c
> @@ -22,10 +22,8 @@ static int hash_literally(unsigned char *sha1, int fd, const char *type, unsigne
>
> if (strbuf_read(&buf, fd, 4096) < 0)
> ret = -1;
> - else if (flags & HASH_WRITE_OBJECT)
> - ret = write_sha1_file(buf.buf, buf.len, type, sha1);
> else
> - ret = hash_sha1_file(buf.buf, buf.len, type, sha1);
> + ret = hash_sha1_file_literally(buf.buf, buf.len, type, sha1, flags);
> strbuf_release(&buf);
> return ret;
> }
> diff --git a/cache.h b/cache.h
> index dfa1a56..e037cad 100644
> --- a/cache.h
> +++ b/cache.h
> @@ -888,6 +888,7 @@ static inline const unsigned char *lookup_replace_object_extended(const unsigned
> extern int sha1_object_info(const unsigned char *, unsigned long *);
> extern int hash_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *sha1);
> extern int write_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *return_sha1);
> +extern int hash_sha1_file_literally(const void *buf, unsigned long len, const char *type, unsigned char *sha1, unsigned flags);
> extern int pretend_sha1_file(void *, unsigned long, enum object_type, unsigned char *);
> extern int force_object_loose(const unsigned char *sha1, time_t mtime);
> extern int git_open_noatime(const char *name);
> diff --git a/sha1_file.c b/sha1_file.c
> index c08c0cb..dc940e6 100644
> --- a/sha1_file.c
> +++ b/sha1_file.c
> @@ -2962,6 +2962,27 @@ int write_sha1_file(const void *buf, unsigned long len, const char *type, unsign
> return write_loose_object(sha1, hdr, hdrlen, buf, len, 0);
> }
>
> +int hash_sha1_file_literally(const void *buf, unsigned long len, const char *type,
> + unsigned char *sha1, unsigned flags)
> +{
> + char *header;
> + int hdrlen, status = 0;
> +
> + /* type string, SP, %lu of the length plus NUL must fit this */
> + header = xmalloc(strlen(type) + 32);
> + write_sha1_file_prepare(buf, len, type, sha1, header, &hdrlen);
> +
> + if (!(flags & HASH_WRITE_OBJECT))
> + goto cleanup;
> + if (has_sha1_file(sha1))
> + goto cleanup;
> + status = write_loose_object(sha1, header, hdrlen, buf, len, 0);
> +
> +cleanup:
> + free(header);
> + return status;
> +}
> +
> int force_object_loose(const unsigned char *sha1, time_t mtime)
> {
> void *buf;
> --
> 2.4.0-311-gf1d9b8d
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2015-05-05 18:50 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-05-04 7:25 [PATCH 0/3] hash-object crash fix and new doc and tests Eric Sunshine
2015-05-04 7:25 ` [PATCH 1/3] git-hash-object.txt: document --literally option Eric Sunshine
2015-05-04 7:25 ` [PATCH 2/3] t1007: add hash-object --literally tests Eric Sunshine
2015-05-04 7:25 ` [PATCH 3/3] write_sha1_file_prepare: fix buffer overrun with extra-long object type Eric Sunshine
2015-05-04 17:58 ` Junio C Hamano
2015-05-04 17:59 ` Junio C Hamano
2015-05-04 21:37 ` [PATCH 0/4] "hash-object --literally" fixes Junio C Hamano
2015-05-04 21:37 ` [PATCH 1/4] git-hash-object.txt: document --literally option Junio C Hamano
2015-05-04 21:37 ` [PATCH 2/4] write_sha1_file_prepare: fix buffer overrun with extra-long object type Junio C Hamano
2015-05-05 0:13 ` Eric Sunshine
2015-05-05 0:28 ` Junio C Hamano
2015-05-05 17:30 ` Junio C Hamano
2015-05-05 18:49 ` Eric Sunshine
2015-05-04 21:37 ` [PATCH 3/4] t1007: add hash-object --literally tests Junio C Hamano
2015-05-04 21:37 ` [PATCH 4/4] write_sha1_file(): do not use a separate sha1[] array Junio C Hamano
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).