Skip to content

Instantly share code, notes, and snippets.

@burghardt
Created March 31, 2023 08:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save burghardt/26780b0fcd71943bf40bfc1e864db04d to your computer and use it in GitHub Desktop.
Save burghardt/26780b0fcd71943bf40bfc1e864db04d to your computer and use it in GitHub Desktop.
Test case for musl libc wcsnrtombs() vulnerability (CVE-2020-28928)
/*
* CVE-2020-28928 test case for musl libc wcsnrtombs() vulnerability
*
* Copyright (c) 2023 Krzysztof Burghardt
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
#include <locale.h>
#include <stdio.h>
#include <string.h>
#include <wchar.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
void alarm_handler(int signum) {
printf("FAIL: Timeout reached. This libc IS vulnerable!\n");
exit(1);
}
int main() {
setlocale(LC_ALL, "en_US.UTF-8");
const wchar_t *wcs = L"äöüß";
size_t wn = wcslen(wcs);
char output[256] = {0};
size_t n = 3; // Set a limited output buffer size
mbstate_t st = {0};
// Set alarm handler and alarm for 15 seconds
signal(SIGALRM, alarm_handler);
alarm(15);
// Attempt conversion, infinite loop expected for musl < 1.2.1
size_t result = wcsnrtombs(output, &wcs, wn, n, &st);
if (result == (size_t)-1) {
printf("FAIL: Conversion failed. This is strange.\n");
return 2;
}
printf("Converted: %s\n", output);
printf("Bytes converted: %zu\n", result);
printf("OK: Conversion successful. This libc is NOT vulnerable.\n");
return 0;
}
@burghardt
Copy link
Author

Built with musl-gcc wrapper. Tested with musl-1.2.0 (vulnerable) and musl-1.2.3 (patched).

Vulnerable musl output:

$ /usr/local/musl/bin/musl-gcc -o test_wcsnrtombs_unpatched test_wcsnrtombs.c
$ ./test_wcsnrtombs_unpatched  ; echo $?
FAIL: Timeout reached. This libc IS vulnerable!
1

Patched musl output:

$ /usr/local/musl-patched/bin/musl-gcc -o test_wcsnrtombs_patched test_wcsnrtombs.c
$ ./test_wcsnrtombs_patched ; echo $?
Converted: ä
Bytes converted: 2
OK: Conversion successful. This libc is NOT vulnerable.
0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment