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

Possibly incorrect reporting of memory as uninitialized by MSan in glib program #813

Closed
josephbisch opened this issue May 23, 2017 · 2 comments

Comments

@josephbisch
Copy link

When running the following program with MSan, it appears that MSan is incorrectly reporting memory as uninitialized, when it seems to be initialized. Just echo -n $'0\x91' > repro and then pass it to the program with ./prog repro.

You need to also have compiled the glib you are using with MSan of course. Also notice the section where I print out the shadow memory using __msan_print_shadow(). I believe that the output from that function indicates that only the first byte is seen as uninitialized by MSan, and the rest are seen as initialized. Also as you can see from the p recoded, recoded looks like it is initialized. You can replace the 0 in the input to the program with something else and it will be reflected in the first byte of recoded. That is not the behavior I would expect if the byte really was uninitialized.

The newest clang I tried this with is 4.0.0 (trunk 290119). But this also happens with clang 3.9.1-8 from Debian.

The fuzz.c file referred to in the sections below is the name of the program.

Shadow Memory Inspection:

(gdb) p recoded 
$2 = 0x70200000f7c0 "0‘"
(gdb) p __msan_print_shadow(recoded, 5)
Shadow map of [0x20200000f7c0, 0x20200000f7c5), 5 bytes:
0x20200000f7c0: ff000000 00...... ........ ........  |A . . .|

Origin A (origin_id 7d800001):
  Uninitialized value was created by a heap allocation
    #0 0x425831 in __interceptor_malloc (src/fuzz/fuzz+0x425831)
    #1 0x7ffff716d153 in g_malloc glib-msan/glib/gmem.c:94:13
    #2 0x7ffff6efcaf7 in g_convert_with_iconv glib-msan/glib/gconvert.c:408:17
    #3 0x7ffff6eff7b2 in g_convert glib-msan/glib/gconvert.c:568:9
    #4 0x7ffff6f02109 in g_convert_with_fallback glib-msan/glib/gconvert.c:660:10
    #5 0x4915cc in LLVMFuzzerTestOneInput src/fuzz/fuzz.c:15:21

$3 = 36921312

Program Output:

2
Uninitialized bytes in __interceptor_strlen at offset 0 inside
[0x701000000050, 5)
==9669==WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0x4900c8 in LLVMFuzzerTestOneInput src/fuzz/fuzz.c:15:18
    #1 0x490b75 in main src/fuzz/fuzz.c:28:2
    #2 0x7fd820463510 in __libc_start_main (/usr/lib/libc.so.6+0x20510)
    #3 0x419d89 in _start (src/fuzz/fuzz+0x419d89)

  Uninitialized value was created by a heap allocation
    #0 0x422421 in __interceptor_malloc llvm-svn/src/llvm/projects/compiler-rt/lib/msan/msan_interceptors.cc:952
    #1 0x7fd821dfb499 in g_malloc glib-msan/glib/gmem.c:94:13
    #2 0x7fd821ba19f4 in g_convert_with_iconv glib-msan/glib/gconvert.c:408:17
    #3 0x7fd821ba4557 in g_convert glib-msan/glib/gconvert.c:565:9
    #4 0x7fd821ba6edb in g_convert_with_fallback glib-msan/glib/gconvert.c:657:10
    #5 0x48ffb3 in LLVMFuzzerTestOneInput src/fuzz/fuzz.c:14:18
    #6 0x490b75 in main src/fuzz/fuzz.c:28:2
    #7 0x7fd820463510 in __libc_start_main (/usr/lib/libc.so.6+0x20510)

SUMMARY: MemorySanitizer: use-of-uninitialized-value
src/fuzz/fuzz.c:15:18 in LLVMFuzzerTestOneInput
Exiting

Program:

#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>

#include "glib.h"

int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
    char *copy = (char *)malloc(size+1);
    memcpy(copy, data, size);
    copy[size] = '\0';
    printf("%lu\n", size);
    char *recoded = g_convert_with_fallback(copy, strlen(copy), "UTF-8", "CP1252", NULL, NULL, NULL, NULL);
    printf("%lu\n", strlen(recoded));
    free(recoded);
    free(copy);
    return 0;
}

int main(int argc, char **argv) {
    FILE *f = fopen(argv[1], "r");
    fseek(f, 0, SEEK_END);
    size_t len = ftell(f);
    fseek(f, 0, SEEK_SET);
    unsigned char *buf = (unsigned char *)malloc(len);
    fread(buf, 1, len, f);
    LLVMFuzzerTestOneInput(buf, len);
    free(buf);
}
@eugenis
Copy link
Contributor

eugenis commented May 24, 2017 via email

@josephbisch
Copy link
Author

Thanks. Closing this because I can confirm that it is indeed fixed with llvm trunk.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants