[bug #59881] Segmentation Fault through manipulated Makefile

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

[bug #59881] Segmentation Fault through manipulated Makefile

Paul D. Smith
URL:
  <https://savannah.gnu.org/bugs/?59881>

                 Summary: Segmentation Fault through manipulated Makefile
                 Project: make
            Submitted by: None
            Submitted on: Fri 15 Jan 2021 01:18:53 PM UTC
                Severity: 3 - Normal
              Item Group: Bug
                  Status: None
                 Privacy: Public
             Assigned to: None
             Open/Closed: Open
         Discussion Lock: Any
       Component Version: SCM
        Operating System: None
           Fixed Release: None
           Triage Status: None

    _______________________________________________________

Details:

I found another bug which causes a segfault when reading with "make -f min".

The issue is this line:
https://github.com/mirror/make/blob/master/src/file.c#L528

There the value of "o" is smaller than "buffer" which causes an integer
underflow and a very large "len" value. When now calling "strcache_add_len"
the memcpy has such a large length that it actually tries to write to a value
below the stack:
https://github.com/mirror/make/blob/master/src/strcache.c#L248

I hadn't the time to check if there is a previous root cause which could be
detected sooner, but one fix (at least for that example) would be to just
check if "o" is smaller than "buffer".

On this example I am not sure if it is possible to exploit. This could be
potentially upgraded to an arbitrary write primitive to execute code. I know
there are easier ways to execute code (Since it is a makefile), but it could
be a way to hide malware within the Makefile of open source projects.



    _______________________________________________________

File Attachments:


-------------------------------------------------------
Date: Fri 15 Jan 2021 01:18:53 PM UTC  Name: min  Size: 206B   By: None

<http://savannah.gnu.org/bugs/download.php?file_id=50723>

    _______________________________________________________

Reply to this item at:

  <https://savannah.gnu.org/bugs/?59881>

_______________________________________________
  Message sent via Savannah
  https://savannah.gnu.org/


Reply | Threaded
Open this post in threaded view
|

[bug #59881] Segmentation Fault through manipulated Makefile

Paul D. Smith
Follow-up Comment #1, bug #59881 (project make):

This makefile causes variable_buffer_output to realloc. This renders buffer in
enter_prereqs invalid.

Here is a patch.

diff --git a/src/file.c b/src/file.c
index a979ca5..61f0a56 100644
--- a/src/file.c
+++ b/src/file.c
@@ -524,8 +524,12 @@ enter_prereqs (struct dep *deps, const char *stem)
                   continue;
                 }

-              /* Save the name.  */
-              dp->name = strcache_add_len (buffer, o - buffer);
+              /* Save the name.
+               * VARIABLE_BUFFER_OUTPUT could realloc, which'd render BUFFER
+               * invalid.
+               * sv 59881.  */
+              dp->name = strcache_add_len (variable_buffer,
+                                           o - variable_buffer);
             }
           dp->stem = stem;
           dp->staticpattern = 1;


    _______________________________________________________

Reply to this item at:

  <https://savannah.gnu.org/bugs/?59881>

_______________________________________________
  Message sent via Savannah
  https://savannah.gnu.org/


Reply | Threaded
Open this post in threaded view
|

[bug #59881] Segmentation Fault through manipulated Makefile

Paul D. Smith
Follow-up Comment #2, bug #59881 (project make):

Here is a test.

diff --git a/tests/scripts/functions/error b/tests/scripts/functions/error
index 998afe4..cb8fcc4 100644
--- a/tests/scripts/functions/error
+++ b/tests/scripts/functions/error
@@ -63,6 +63,28 @@ $answer = "Some stuff\n$makefile:17: *** error is
definitely.  Stop.\n";
 $answer = "$makefile:22: *** Error found!.  Stop.\n";
 &compare_output($answer,&get_logfile(1));
 
+
+# Test #6
+# A makefile which causes variable_buffer_output to realloc and renders
buffer
+# invalid and used to crash make.
+# sv 59881.
+my $makestring = ':
+
+0:
+00000000
+000
    000000000000
                000000000:
+0%0:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000%0000000000000
+0';
+
+open(MAKEFILE, "> $makefile") or die "Failed to open $makefile: $!\n";
+print MAKEFILE $makestring;
+close(MAKEFILE) or die "Failed to write $makefile: $!\n";
+
+&run_make_with_options($makefile, '', &get_logfile, 512);
+my $answer = "$makefile:4: *** missing separator.  Stop.\n";
+&compare_output($answer, &get_logfile(1));
+
+
 # This tells the test driver that the perl test script executed properly.
 1;


    _______________________________________________________

Reply to this item at:

  <https://savannah.gnu.org/bugs/?59881>

_______________________________________________
  Message sent via Savannah
  https://savannah.gnu.org/


Reply | Threaded
Open this post in threaded view
|

[bug #59881] Segmentation Fault through manipulated Makefile

Paul D. Smith
Follow-up Comment #3, bug #59881 (project make):

Thank you for your report.
How did you manage to obtain this makefile?

    _______________________________________________________

Reply to this item at:

  <https://savannah.gnu.org/bugs/?59881>

_______________________________________________
  Message sent via Savannah
  https://savannah.gnu.org/


Reply | Threaded
Open this post in threaded view
|

[bug #59881] Segmentation Fault through manipulated Makefile

Paul D. Smith
Follow-up Comment #4, bug #59881 (project make):

You're welcome Dmitry. I found this makefile by fuzzing the make parser. If
you want I could maybe spent another few rounds on fuzzing this project. I am
just not sure if it is worth the effort on both sides (for me to fuzz the
project, and for you to fix obscure makefile inputs).

I am personally and professionally more interested in finding security related
bugs ;-)

    _______________________________________________________

Reply to this item at:

  <https://savannah.gnu.org/bugs/?59881>

_______________________________________________
  Message sent via Savannah
  https://savannah.gnu.org/


Reply | Threaded
Open this post in threaded view
|

[bug #59881] Segmentation Fault through manipulated Makefile

Paul D. Smith
Follow-up Comment #5, bug #59881 (project make):

I believe, this is useful. You found a genuine bug. Do you mind sharing you
fuzzing tecqnique?

    _______________________________________________________

Reply to this item at:

  <https://savannah.gnu.org/bugs/?59881>

_______________________________________________
  Message sent via Savannah
  https://savannah.gnu.org/


Reply | Threaded
Open this post in threaded view
|

[bug #59881] Segmentation Fault through manipulated Makefile

Paul D. Smith
Follow-up Comment #6, bug #59881 (project make):

I think it's probably better to use variable_buffer here, for safety.  But,
there's something much deeper and more mysterious happening.  It shouldn't
really be possible to hit this problem.  The reason that the buffer is resized
is that the stem of the pattern contains spaces; it's "000000000 0000000000
0000000".  Because of this, the expansion of the pattern on the RHS happens
multiple times for this single file instead of just one time.

It's related to the vertical TAB characters in this file; if I replace them
with spaces I don't see this behavior.  The problem is that in some places in
the parser we're treating VT as whitespace (word separators) and in other
places we are treating it as non-whitespace.

I'm investigating this.

    _______________________________________________________

Reply to this item at:

  <https://savannah.gnu.org/bugs/?59881>

_______________________________________________
  Message sent via Savannah
  https://savannah.gnu.org/


Reply | Threaded
Open this post in threaded view
|

[bug #59881] Segmentation Fault through manipulated Makefile

Paul D. Smith
Follow-up Comment #7, bug #59881 (project make):

I found the real bug and have a fix.  I will also provide changes to fix the
variable_buffer issue Dmitry noticed; although I'm not convinced it is
actually possible to expand the buffer in situations where we don't expect it,
it's certainly better to not risk it.

    _______________________________________________________

Reply to this item at:

  <https://savannah.gnu.org/bugs/?59881>

_______________________________________________
  Message sent via Savannah
  https://savannah.gnu.org/


Reply | Threaded
Open this post in threaded view
|

[bug #59881] Segmentation Fault through manipulated Makefile

Paul D. Smith
Update of bug #59881 (project make):

                  Status:                    None => Fixed                  
             Assigned to:                    None => psmith                
             Open/Closed:                    Open => Closed                
        Operating System:                    None => Any                    
           Fixed Release:                    None => SCM                    
           Triage Status:                    None => Medium Effort          

    _______________________________________________________

Follow-up Comment #8:

I pushed a fix.  Thanks all!

    _______________________________________________________

Reply to this item at:

  <https://savannah.gnu.org/bugs/?59881>

_______________________________________________
  Message sent via Savannah
  https://savannah.gnu.org/