NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

lib/51363: ubsan (undef behaviour sanitizer) faults



>Number:         51363
>Category:       lib
>Synopsis:       libubsan (undefined behaviour sanitizer) crashes where it should=
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Jul 26 18:50:00 +0000 2016
>Originator:     =09
>Release:        NetBSD 7.99.34
>Organization:
	method logic digital
>Environment:
System: NetBSD kamloops 7.99.34 NetBSD 7.99.34 (GENERIC) #12: Mon Jul
25 16:54:20 PDT 2016
root@kamloops:/usr/obj/sys/arch/amd64/compile/GENERIC amd64
Architecture: x86_64
Machine: amd64
>Description:
	libubsan should trap for undefined behaviour errors and either fail
gracefully w/i runtime, or continue running the ub-afflicted program.
My examples demonstrate that it segfaults instead.
	See attached program and Makefile in "How-To-Repeat".

	See truncated stack trace and description here:

GNU gdb (GDB) 7.10.1
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.htm=
l>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64--netbsd".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ../../../../json_afl...done.
[New process 1]
Core was generated by `json_afl'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  __sanitizer::AppendString (
    s=3D0x1100000074 <error: Cannot access memory at address
0x1100000074>, precision=3D-1,
    buff_end=3D0x7f7fff78f43f "", buff=3D0x7f7fff78f238)
    at /usr/src/external/gpl3/gcc/dist/libsanitizer/sanitizer_common/saniti=
zer_printf.cc:102
102	  for (; *s; s++) {
(gdb) bt full
#0  __sanitizer::AppendString (
    s=3D0x1100000074 <error: Cannot access memory at address
0x1100000074>, precision=3D-1,
    buff_end=3D0x7f7fff78f43f "", buff=3D0x7f7fff78f238)
    at /usr/src/external/gpl3/gcc/dist/libsanitizer/sanitizer_common/saniti=
zer_printf.cc:102
        result =3D 0
#1  __sanitizer::VSNPrintf (buff=3D<optimized out>,
buff_length=3Dbuff_length@entry=3D400,
    format=3Dformat@entry=3D0x749819a1717a "", args=3Dargs@entry=3D0x7f7fff=
78f488)
    at /usr/src/external/gpl3/gcc/dist/libsanitizer/sanitizer_common/saniti=
zer_printf.cc:181
        width =3D 0
        have_ll =3D <optimized out>
        uval =3D <optimized out>
        pad_with_zero =3D false
        have_z =3D false
        have_precision =3D <optimized out>
        precision =3D -1
        dval =3D <optimized out>
        kPrintfFormatsHelp =3D 0x749819a199e0 "Supported Printf formats:
%([0-9]*)?(z|ll)?{d,u,x}; %p; %(\\.\\*)?s; %c\n"
        buff_end =3D 0x7f7fff78f43f ""
        cur =3D 0x749819a1717b "%s note: %s"
        result =3D 0
#2  0x0000749819a0e372 in __sanitizer::SharedPrintfCode(bool, const
char *, typedef __va_list_tag __va_list_tag *)
(append_pid=3Dappend_pid@entry=3Dfalse, format=3D0x749819a1717a "",
    args=3Dargs@entry=3D0x7f7fff78f488)
    at /usr/src/external/gpl3/gcc/dist/libsanitizer/sanitizer_common/saniti=
zer_printf.cc:263
        use_mmap =3D <optimized out>
        args2 =3D <error reading variable args2 (Attempt to dereference
a generic pointer.)>
        local_buffer =3D " is outside the range of representable values
of type \000\000t\023\302\031*t\000\000\000\000\000\000\000\000\000\000\b\3=
54\240\031*t\000\000\220\001\000\000\000\000\000\000P*x\377\177\177\000\000=
(\365x\377\177\177\000\000\062*\240\031*t\000\000\022\063\340\027*t\000\000=
Zq*\031*t\000\000\000\000\000\000\000\000\000\000\b\000\000\000\060\000\000=
\000\000\366x\377\177\177\000\000@\365x\377\177\177\000\000\033[1m\033[31m
runtime error: \033[1m\033[0m\033[1m\000\000\000"...
        needed_length =3D 0
        buffer =3D 0x7f7fff78f2b0 " is outside the range of
representable values of type "
        buffer_size =3D <optimized out>
#3  0x0000749819a0e507 in __sanitizer::Printf (format=3D<optimized out>)
    at /usr/src/external/gpl3/gcc/dist/libsanitizer/sanitizer_common/saniti=
zer_printf.cc:286
        args =3D <error reading variable args (Attempt to dereference a
generic pointer.)>
#4  0x0000749819a06526 in renderText (Message=3D<optimized out>,
Args=3D0x7f7fff78f7a0)
    at /usr/src/external/gpl3/gcc/dist/libsanitizer/ubsan/ubsan_diag.cc:166
        A =3D @0x7f7fff78f7e0: {Kind =3D __ubsan::Diag::AK_String, {
            String =3D 0x1100000074 <error: Cannot access memory at
address 0x1100000074>,
            UInt =3D 0x0000749819a06f490000001100000074, SInt =3D
0x0000749819a06f490000001100000074,
            Float =3D <invalid float value>, Pointer =3D 0x1100000074}}
        Msg =3D 0x749819a16a7f "2"
#5  0x0000749819a0698c in __ubsan::Diag::~Diag (this=3D0x7f7fff78f760,
__in_chrg=3D<optimized out>)
    at /usr/src/external/gpl3/gcc/dist/libsanitizer/ubsan/ubsan_diag.cc:327
No locals.
#6  0x0000749819a02e2f in handleFloatCastOverflow (Data=3D<optimized
out>, From=3D4748456034501132288,
    Opts=3D...) at
/usr/src/external/gpl3/gcc/dist/libsanitizer/ubsan/ubsan_handlers.cc:294
        Loc =3D {Kind =3D __ubsan::Location::LK_Module, SourceLoc =3D
{Filename =3D 0x0, Line =3D 0,
            Column =3D 0}, ModuleLoc =3D {ModuleName =3D 0x749816e00708
"libubsan.so.0",
            Offset =3D 24449}, MemoryLoc =3D 128196628474880}
        R =3D {Opts =3D {DieAfterReport =3D false, pc =3D 4320072, bp =3D
140187723692336}, SummaryLoc =3D {
            Kind =3D __ubsan::Location::LK_Module, SourceLoc =3D {Filename
=3D 0x0, Line =3D 0,
              Column =3D 0}, ModuleLoc =3D {ModuleName =3D 0x749816e00708
"libubsan.so.0",
              Offset =3D 24449}, MemoryLoc =3D 128196628474880}}
#7  0x0000749819a05f82 in __ubsan::__ubsan_handle_float_cast_overflow
(Data=3D<optimized out>,
    From=3D<optimized out>)
    at /usr/src/external/gpl3/gcc/dist/libsanitizer/ubsan/ubsan_handlers.cc=
:300
        bp =3D 140187723692336
        pc =3D <optimized out>
        Opts =3D {DieAfterReport =3D false, pc =3D 1, bp =3D 515}

[...]

No locals.
(gdb) quit


As an experiment, using frame 4 as a reference, I replaced A.string
(which appears faulty ( String =3D 0x1100000074 <error: Cannot access
memory at address 0x1100000074> )) w/ a hardcoded string which does
allow libubsan (on NetBSD) to display a message and continue
operations (see Fix: below). I tested the fault-exercising code
against an unpatched libubsan on a Linux (Ubuntu 16.04.1 "xenial
xerius") box and it did not fault (i.e., it seemed to work properly).

>How-To-Repeat:

test program
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
#include <stdio.h>

int
main(int argc, char *argv[])
{
  unsigned long x;

  x=3D 1.9e19;
  fprintf(stderr, "%lu\n", x);
}

Makefile (mind tabs/spaces)
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D
CC=3Dclang

faulter: faulter.c
	${CC} -o faulter faulter.c -fsanitize=3Dundefined -fsanitize-recover=3Dall=
 -lubsan

>Fix:
	I forced a proof-of-concept "fix" in frame 4 that allowed
non-faulting behaviour. I haven't tested further yet.

/usr/src/external/gpl3/gcc/dist/libsanitizer/ubsan/ubsan_diag.cc
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D

--- ./ubsan_diag.bak    2016-07-26 11:28:15.810432051 -0700
+++ ubsan_diag.cc       2016-07-26 11:28:35.206426305 -0700
@@ -162,7 +162,7 @@
       const Diag::Arg &A =3D Args[*++Msg - '0'];
       switch (A.Kind) {
       case Diag::AK_String:
-        Printf("%s", A.String);
+        Printf("%s", "push on...");
         break;
       case Diag::AK_Mangled: {
         Printf("'%s'", Symbolizer::GetOrInit()->Demangle(A.String));

>Unformatted:
  fail/continue gracefully


Home | Main Index | Thread Index | Old Index