git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Hanno Böck" <hanno@hboeck.de>
To: git@vger.kernel.org
Subject: [patch] Out of bounds read in git apply on malformed input in gitdiff_verify_name()
Date: Tue, 14 Jun 2016 12:52:18 +0200	[thread overview]
Message-ID: <20160614125218.18e08566@pc1> (raw)


[-- Attachment #1.1: Type: text/plain, Size: 4655 bytes --]

Hi,

The attached sample file will cause an out of bounds heap read in the
function gitdiff_verify_name() when passed to git apply.

To reproduce:
* Build git with address sanitizer (-fsanitize=address in cflags)
* git apply --check [path_to_file]

I have pasted the full address sanitizer error trace below.

The code where this happens is here (builtin/apply.c):
                if (!another || memcmp(another, orig_name, len + 1))

The problem seems to be that there is no guarantee that another and
orig_name have the same length, len is set to strlen(orig_name) a few
lines earlier. Thus if orig_name is more than 1 byte shorter than
another it causes an invalid memory read.

Changing memcmp to strncmp should fix this, patch attached.

Found with the help of american fuzzy lop and address sanitizer.


==7717==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000ed30 at pc 0x41d3ab bp 0x7ffd00ad61d0 sp 0x7ffd00ad61c0
READ of size 3 at 0x60200000ed30 thread T0
    #0 0x41d3aa in gitdiff_verify_name builtin/apply.c:940
    #1 0x41d687 in gitdiff_oldname builtin/apply.c:956
    #2 0x41f387 in parse_git_header builtin/apply.c:1309
    #3 0x42014b in find_header builtin/apply.c:1475
    #4 0x422bc5 in parse_chunk builtin/apply.c:1988
    #5 0x432c24 in apply_patch builtin/apply.c:4373
    #6 0x433df8 in cmd_apply builtin/apply.c:4626
    #7 0x407dcd in run_builtin /f/git/plain/git-2.9.0/git.c:352
    #8 0x40818c in handle_builtin /f/git/plain/git-2.9.0/git.c:539
    #9 0x4084db in run_argv /f/git/plain/git-2.9.0/git.c:593
    #10 0x408934 in main /f/git/plain/git-2.9.0/git.c:698
    #11 0x7fddbf96c78f in __libc_start_main (/lib64/libc.so.6+0x2078f)
    #12 0x405308 in _start (/f/git/plain/git-2.9.0/git+0x405308)

0x60200000ed32 is located 0 bytes to the right of 2-byte region [0x60200000ed30,0x60200000ed32)
allocated by thread T0 here:
    #0 0x7fddc07b9707 in malloc (/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/libasan.so.1+0x57707)
    #1 0x790768 in do_xmalloc /f/git/plain/git-2.9.0/wrapper.c:59
    #2 0x79089e in do_xmallocz /f/git/plain/git-2.9.0/wrapper.c:99
    #3 0x79090f in xmallocz /f/git/plain/git-2.9.0/wrapper.c:107
    #4 0x79094c in xmemdupz /f/git/plain/git-2.9.0/wrapper.c:123
    #5 0x41c1f7 in find_name_common builtin/apply.c:704
    #6 0x41c29b in find_name builtin/apply.c:715
    #7 0x41d31b in gitdiff_verify_name builtin/apply.c:939
    #8 0x41d687 in gitdiff_oldname builtin/apply.c:956
    #9 0x41f387 in parse_git_header builtin/apply.c:1309
    #10 0x42014b in find_header builtin/apply.c:1475
    #11 0x422bc5 in parse_chunk builtin/apply.c:1988
    #12 0x432c24 in apply_patch builtin/apply.c:4373
    #13 0x433df8 in cmd_apply builtin/apply.c:4626
    #14 0x407dcd in run_builtin /f/git/plain/git-2.9.0/git.c:352
    #15 0x40818c in handle_builtin /f/git/plain/git-2.9.0/git.c:539
    #16 0x4084db in run_argv /f/git/plain/git-2.9.0/git.c:593
    #17 0x408934 in main /f/git/plain/git-2.9.0/git.c:698
    #18 0x7fddbf96c78f in __libc_start_main (/lib64/libc.so.6+0x2078f)

SUMMARY: AddressSanitizer: heap-buffer-overflow builtin/apply.c:940 gitdiff_verify_name
Shadow bytes around the buggy address:
  0x0c047fff9d50: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9d60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9d70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9d80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9d90: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c047fff9da0: fa fa fa fa fa fa[02]fa fa fa 03 fa fa fa fd fd
  0x0c047fff9db0: fa fa 03 fa fa fa 00 02 fa fa fd fd fa fa 00 00
  0x0c047fff9dc0: fa fa 04 fa fa fa 00 03 fa fa fd fd fa fa 00 00
  0x0c047fff9dd0: fa fa 01 fa fa fa 00 06 fa fa 05 fa fa fa 00 04
  0x0c047fff9de0: fa fa 04 fa fa fa 06 fa fa fa 00 04 fa fa 00 04
  0x0c047fff9df0: fa fa 00 04 fa fa 00 04 fa fa fd fa fa fa 02 fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Contiguous container OOB:fc
  ASan internal:           fe
==7717==ABORTING

-- 
Hanno Böck
https://hboeck.de/

mail/jabber: hanno@hboeck.de
GPG: BBB51E42

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.2: git-fix-oob-memcmp-strncmp.diff --]
[-- Type: text/x-patch, Size: 703 bytes --]

diff -Naur git-2.9.0/builtin/apply.c git-2.9.0-1/builtin/apply.c
--- git-2.9.0/builtin/apply.c	2016-06-13 21:07:49.000000000 +0200
+++ git-2.9.0-1/builtin/apply.c	2016-06-14 11:38:19.940588382 +0200
@@ -937,7 +937,7 @@
 			die(_("git apply: bad git-diff - expected /dev/null, got %s on line %d"),
 			    orig_name, linenr);
 		another = find_name(line, NULL, p_value, TERM_TAB);
-		if (!another || memcmp(another, orig_name, len + 1))
+		if (!another || strncmp(another, orig_name, len + 1))
 			die((side == DIFF_NEW_NAME) ?
 			    _("git apply: bad git-diff - inconsistent new filename on line %d") :
 			    _("git apply: bad git-diff - inconsistent old filename on line %d"), linenr);

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.3: git-out-of-bounds-gitdiff_verify_name.patch --]
[-- Type: text/x-patch, Size: 30 bytes --]

diff --git 
--- /00
--- /0

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

                 reply	other threads:[~2016-06-14 10:57 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=20160614125218.18e08566@pc1 \
    --to=hanno@hboeck.de \
    --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).