Skip to content
This repository has been archived by the owner on Sep 22, 2022. It is now read-only.

mdbx_env_open: undefined behavior reported by llvm11 ubsan #153

Closed
lithdew opened this issue Jan 18, 2021 · 10 comments
Closed

mdbx_env_open: undefined behavior reported by llvm11 ubsan #153

lithdew opened this issue Jan 18, 2021 · 10 comments
Assignees
Labels

Comments

@lithdew
Copy link

lithdew commented Jan 18, 2021

Tested on libmdbx v0.9.2, zig master, llvm 11.

Suppressing UBsan reports by passing -fno-sanitize=undefined allows the following program to execute successfully.

const std = @import("std");
const c = @cImport(@cInclude("mdbx.h"));

pub fn main() !void {
    var env: ?*c.MDBX_env = null;
    if (c.mdbx_env_create(&env) != c.MDBX_SUCCESS) {
        return error.CreateFailed;
    }
    defer if (c.mdbx_env_close(env) != c.MDBX_SUCCESS) unreachable;

    const env_flags = @intToEnum(c.MDBX_env_flags_t, c.MDBX_NOSUBDIR);
    if (c.mdbx_env_open(env, "bench_mdbx.db", env_flags, 0644) != c.MDBX_SUCCESS) {
        return error.OpenFailed;
    }
}

zig stack trace:

$ /home/lith/Desktop/merkle/zig-cache/o/f36316c81b6908c5de61734068a39dd5/bench_mdbx
Illegal instruction at address 0x7506de

/home/lith/.cache/zigmod/deps/v/http/sha256-c35cc53d66d74ebfc86e39441ba26276541ac7892bf91dba1e70c83665a02767/mdbx.c:0:3: 0x7506de in mdbx_meta_set_txnid (/home/lith/.cache/zigmod/deps/v/http/sha256-c35cc53d66d74ebfc86e39441ba26276541ac7892bf91dba1e70c83665a02767/mdbx.c)
/home/lith/.cache/zigmod/deps/v/http/sha256-c35cc53d66d74ebfc86e39441ba26276541ac7892bf91dba1e70c83665a02767/mdbx.c:11877:3: 0x7827ac in mdbx_meta_model (/home/lith/.cache/zigmod/deps/v/http/sha256-c35cc53d66d74ebfc86e39441ba26276541ac7892bf91dba1e70c83665a02767/mdbx.c)
  mdbx_meta_set_txnid(env, model_meta, MIN_TXNID + num);
  ^
/home/lith/.cache/zigmod/deps/v/http/sha256-c35cc53d66d74ebfc86e39441ba26276541ac7892bf91dba1e70c83665a02767/mdbx.c:11886:22: 0x781924 in mdbx_init_metas (/home/lith/.cache/zigmod/deps/v/http/sha256-c35cc53d66d74ebfc86e39441ba26276541ac7892bf91dba1e70c83665a02767/mdbx.c)
  MDBX_page *page1 = mdbx_meta_model(env, page0, 0);
                     ^
/home/lith/.cache/zigmod/deps/v/http/sha256-c35cc53d66d74ebfc86e39441ba26276541ac7892bf91dba1e70c83665a02767/mdbx.c:12719:13: 0x75ab7a in mdbx_setup_dxb (/home/lith/.cache/zigmod/deps/v/http/sha256-c35cc53d66d74ebfc86e39441ba26276541ac7892bf91dba1e70c83665a02767/mdbx.c)
    meta = *mdbx_init_metas(env, buffer);
            ^
/home/lith/.cache/zigmod/deps/v/http/sha256-c35cc53d66d74ebfc86e39441ba26276541ac7892bf91dba1e70c83665a02767/mdbx.c:13885:22: 0x7569cf in mdbx_env_open (/home/lith/.cache/zigmod/deps/v/http/sha256-c35cc53d66d74ebfc86e39441ba26276541ac7892bf91dba1e70c83665a02767/mdbx.c)
  const int dxb_rc = mdbx_setup_dxb(env, lck_rc);
                     ^
/home/lith/Desktop/merkle/bench_mdbx.zig:12:24: 0xe8ed54 in main (bench_mdbx)
    if (c.mdbx_env_open(env, "bench_mdbx.db", env_flags, 0644) != c.MDBX_SUCCESS) {
                       ^
/home/lith/Desktop/zig/lib/std/start.zig:345:37: 0xe8f031 in std.start.main (bench_mdbx)
            const result = root.main() catch |err| {
                                    ^
Aborted (core dumped)

gdb stack trace:

Program received signal SIGILL, Illegal instruction.
0x00000000007506de in mdbx_meta_set_txnid (env=<optimized out>, env@entry=0x101aa80, meta=0x101b3a4, txnid=1)
    at /home/lith/.cache/zigmod/deps/v/http/sha256-c35cc53d66d74ebfc86e39441ba26276541ac7892bf91dba1e70c83665a02767/mdbx.c:3528
3528      mdbx_assert(env, (1u << env->me_psize2log) == env->me_psize);
(gdb) bt
#0  0x00000000007506de in mdbx_meta_set_txnid (env=<optimized out>, env@entry=0x101aa80, meta=0x101b3a4, txnid=1)
    at /home/lith/.cache/zigmod/deps/v/http/sha256-c35cc53d66d74ebfc86e39441ba26276541ac7892bf91dba1e70c83665a02767/mdbx.c:3528
#1  0x00000000007827ad in mdbx_meta_model (env=env@entry=0x101aa80, model=0x101b390, num=<optimized out>, num@entry=0)
    at /home/lith/.cache/zigmod/deps/v/http/sha256-c35cc53d66d74ebfc86e39441ba26276541ac7892bf91dba1e70c83665a02767/mdbx.c:11877
#2  0x0000000000781925 in mdbx_init_metas (env=env@entry=0x101aa80, buffer=0x101b390)
    at /home/lith/.cache/zigmod/deps/v/http/sha256-c35cc53d66d74ebfc86e39441ba26276541ac7892bf91dba1e70c83665a02767/mdbx.c:11886
#3  0x000000000075ab7b in mdbx_setup_dxb (env=env@entry=0x101aa80, lck_rc=lck_rc@entry=-1)
    at /home/lith/.cache/zigmod/deps/v/http/sha256-c35cc53d66d74ebfc86e39441ba26276541ac7892bf91dba1e70c83665a02767/mdbx.c:12719
#4  0x00000000007569d0 in mdbx_env_open (env=0x101aa80, pathname=<optimized out>, flags=<optimized out>, mode=<optimized out>)
    at /home/lith/.cache/zigmod/deps/v/http/sha256-c35cc53d66d74ebfc86e39441ba26276541ac7892bf91dba1e70c83665a02767/mdbx.c:13885
#5  0x0000000000e8ed55 in main () at bench_mdbx.zig:12
#6  0x0000000000e8f032 in std.start.callMain () at /home/lith/Desktop/zig/lib/std/start.zig:345
#7  std.start.initEventLoopAndCallMain () at /home/lith/Desktop/zig/lib/std/start.zig:287
#8  std.start.callMainWithArgs (argc=1, argv=0x7fffffff3558, envp=...) at /home/lith/Desktop/zig/lib/std/start.zig:250
#9  std.start.main (c_argc=1, c_argv=0x7fffffff3558, c_envp=0x7fffffff3568) at /home/lith/Desktop/zig/lib/std/start.zig:257
(gdb) display/i $pc
1: x/i $pc
=> 0x7506de <mdbx_meta_set_txnid+494>:  ud2
(gdb) 

ubsan reports undefined behavior in mdbx_meta_set_txnid. Here is the disassembly:

(gdb) disass 0x7506de
Dump of assembler code for function mdbx_meta_set_txnid:
   0x00000000007504f0 <+0>:     push   %rbp
   0x00000000007504f1 <+1>:     mov    %rsp,%rbp
   0x00000000007504f4 <+4>:     push   %r15
   0x00000000007504f6 <+6>:     push   %r14
   0x00000000007504f8 <+8>:     push   %r13
   0x00000000007504fa <+10>:    push   %r12
   0x00000000007504fc <+12>:    push   %rbx
   0x00000000007504fd <+13>:    sub    $0x18,%rsp
   0x0000000000750501 <+17>:    mov    %rdx,%r14
   0x0000000000750504 <+20>:    mov    %rsi,%rbx
   0x0000000000750507 <+23>:    mov    0x894f0a(%rip),%r13        # 0xfe5418
   0x000000000075050e <+30>:    testb  $0x1,0x0(%r13)
   0x0000000000750513 <+35>:    jne    0x750548 <mdbx_meta_set_txnid+88>
   0x0000000000750515 <+37>:    test   %rbx,%rbx
   0x0000000000750518 <+40>:    je     0x7506de <mdbx_meta_set_txnid+494>
   0x000000000075051e <+46>:    vmovups 0x898d3a(%rip),%xmm0        # 0xfe9260 <bootid>
   0x0000000000750526 <+54>:    vmovups %xmm0,0xc0(%rbx)
   0x000000000075052e <+62>:    mov    %r14,0x8(%rbx)
   0x0000000000750532 <+66>:    mov    %r14,0xb0(%rbx)
   0x0000000000750539 <+73>:    add    $0x18,%rsp
   0x000000000075053d <+77>:    pop    %rbx
   0x000000000075053e <+78>:    pop    %r12
   0x0000000000750540 <+80>:    pop    %r13
   0x0000000000750542 <+82>:    pop    %r14
   0x0000000000750544 <+84>:    pop    %r15
   0x0000000000750546 <+86>:    pop    %rbp
   0x0000000000750547 <+87>:    ret    
   0x0000000000750548 <+88>:    mov    %rdi,%r15
   0x000000000075054b <+91>:    test   $0x7,%r15b
   0x000000000075054f <+95>:    jne    0x7506de <mdbx_meta_set_txnid+494>
   0x0000000000750555 <+101>:   test   %r15,%r15
   0x0000000000750558 <+104>:   je     0x7506de <mdbx_meta_set_txnid+494>
   0x000000000075055e <+110>:   lea    0x8(%r15),%rdi
   0x0000000000750562 <+114>:   test   $0x7,%dil
   0x0000000000750566 <+118>:   jne    0x7506de <mdbx_meta_set_txnid+494>
   0x000000000075056c <+124>:   lea    0x54(%r15),%rdx
   0x0000000000750570 <+128>:   test   $0x3,%dl
   0x0000000000750573 <+131>:   jne    0x7506de <mdbx_meta_set_txnid+494>
   0x0000000000750579 <+137>:   movzbl (%rdx),%eax
   0x000000000075057c <+140>:   cmp    $0x1f,%eax
   0x000000000075057f <+143>:   ja     0x7506de <mdbx_meta_set_txnid+494>
   0x0000000000750585 <+149>:   lea    0x50(%r15),%rsi
   0x0000000000750589 <+153>:   test   $0x7,%sil
   0x000000000075058d <+157>:   jne    0x7506de <mdbx_meta_set_txnid+494>
   0x0000000000750593 <+163>:   mov    0x8(%r15),%r12
   0x0000000000750597 <+167>:   mov    $0x1,%ecx
   0x000000000075059c <+172>:   shlx   %eax,%ecx,%eax
   0x00000000007505a1 <+177>:   cmp    (%rsi),%eax
   0x00000000007505a3 <+179>:   jne    0x750658 <mdbx_meta_set_txnid+360>
   0x00000000007505a9 <+185>:   test   $0x3,%dl
   0x00000000007505ac <+188>:   jne    0x7506de <mdbx_meta_set_txnid+494>
   0x00000000007505b2 <+194>:   movzbl (%rdx),%eax
   0x00000000007505b5 <+197>:   cmp    $0x3f,%eax
   0x00000000007505b8 <+200>:   ja     0x7506de <mdbx_meta_set_txnid+494>
   0x00000000007505be <+206>:   test   %r12,%r12
   0x00000000007505c1 <+209>:   je     0x7506de <mdbx_meta_set_txnid+494>
   0x00000000007505c7 <+215>:   cmp    $0xffffffffffffffec,%r12
   0x00000000007505cb <+219>:   jae    0x7506de <mdbx_meta_set_txnid+494>
   0x00000000007505d1 <+225>:   add    $0x14,%r12
   0x00000000007505d5 <+229>:   cmp    %rbx,%r12
   0x00000000007505d8 <+232>:   ja     0x750515 <mdbx_meta_set_txnid+37>
   0x00000000007505de <+238>:   mov    (%rdi),%rdi
   0x00000000007505e1 <+241>:   testb  $0x1,0x0(%r13)
   0x00000000007505e6 <+246>:   jne    0x750696 <mdbx_meta_set_txnid+422>
   0x00000000007505ec <+252>:   movzbl (%rdx),%eax
   0x00000000007505ef <+255>:   cmp    $0x3f,%rax
   0x00000000007505f3 <+259>:   ja     0x7506de <mdbx_meta_set_txnid+494>
   0x00000000007505f9 <+265>:   mov    $0x3,%ecx
--Type <RET> for more, q to quit, c to continue without paging--
   0x00000000007505fe <+270>:   shlx   %rax,%rcx,%rax
   0x0000000000750603 <+275>:   add    %rdi,%rax
   0x0000000000750606 <+278>:   cmp    %rdi,%rax
   0x0000000000750609 <+281>:   jb     0x7506de <mdbx_meta_set_txnid+494>
   0x000000000075060f <+287>:   test   %rdi,%rdi
   0x0000000000750612 <+290>:   je     0x7506de <mdbx_meta_set_txnid+494>
   0x0000000000750618 <+296>:   test   %rax,%rax
   0x000000000075061b <+299>:   je     0x7506de <mdbx_meta_set_txnid+494>
   0x0000000000750621 <+305>:   cmp    $0xffffffffffffffec,%rax
   0x0000000000750625 <+309>:   jae    0x7506de <mdbx_meta_set_txnid+494>
   0x000000000075062b <+315>:   add    $0x14,%rax
   0x000000000075062f <+319>:   cmp    %rbx,%rax
   0x0000000000750632 <+322>:   jb     0x750515 <mdbx_meta_set_txnid+37>
   0x0000000000750638 <+328>:   lea    -0x4eba09(%rip),%rsi        # 0x264c36
   0x000000000075063f <+335>:   lea    -0x4d139a(%rip),%rdx        # 0x27f2ac
   0x0000000000750646 <+342>:   mov    %r15,%rdi
   0x0000000000750649 <+345>:   mov    $0x1d14,%ecx
   0x000000000075064e <+350>:   call   0x73b66c <mdbx_assert_fail>
   0x0000000000750653 <+355>:   jmp    0x750515 <mdbx_meta_set_txnid+37>
   0x0000000000750658 <+360>:   mov    %rsi,-0x38(%rbp)
   0x000000000075065c <+364>:   lea    -0x5105bb(%rip),%rsi        # 0x2400a8
   0x0000000000750663 <+371>:   mov    %rdx,-0x40(%rbp)
   0x0000000000750667 <+375>:   lea    -0x4e7c42(%rip),%rdx        # 0x268a2c
   0x000000000075066e <+382>:   mov    %rdi,-0x30(%rbp)
   0x0000000000750672 <+386>:   mov    %r15,%rdi
   0x0000000000750675 <+389>:   mov    $0xdc8,%ecx
   0x000000000075067a <+394>:   call   0x73b66c <mdbx_assert_fail>
   0x000000000075067f <+399>:   mov    -0x30(%rbp),%rdi
   0x0000000000750683 <+403>:   mov    -0x38(%rbp),%rsi
   0x0000000000750687 <+407>:   mov    -0x40(%rbp),%rdx
   0x000000000075068b <+411>:   test   $0x3,%dl
   0x000000000075068e <+414>:   je     0x7505b2 <mdbx_meta_set_txnid+194>
   0x0000000000750694 <+420>:   jmp    0x7506de <mdbx_meta_set_txnid+494>
   0x0000000000750696 <+422>:   cmp    $0x1f,%al
   0x0000000000750698 <+424>:   ja     0x7506de <mdbx_meta_set_txnid+494>
   0x000000000075069a <+426>:   test   $0x7,%sil
   0x000000000075069e <+430>:   jne    0x7506de <mdbx_meta_set_txnid+494>
   0x00000000007506a0 <+432>:   mov    %rdx,%r12
   0x00000000007506a3 <+435>:   mov    $0x1,%ecx
   0x00000000007506a8 <+440>:   shlx   %eax,%ecx,%eax
   0x00000000007506ad <+445>:   cmp    (%rsi),%eax
   0x00000000007506af <+447>:   je     0x7505ec <mdbx_meta_set_txnid+252>
   0x00000000007506b5 <+453>:   lea    -0x510614(%rip),%rsi        # 0x2400a8
   0x00000000007506bc <+460>:   lea    -0x4e7c97(%rip),%rdx        # 0x268a2c
   0x00000000007506c3 <+467>:   mov    %rdi,%r13
   0x00000000007506c6 <+470>:   mov    %r15,%rdi
   0x00000000007506c9 <+473>:   mov    $0xdc8,%ecx
   0x00000000007506ce <+478>:   call   0x73b66c <mdbx_assert_fail>
   0x00000000007506d3 <+483>:   mov    %r13,%rdi
   0x00000000007506d6 <+486>:   mov    %r12,%rdx
   0x00000000007506d9 <+489>:   jmp    0x7505ec <mdbx_meta_set_txnid+252>
=> 0x00000000007506de <+494>:   ud2    
@erthink
Copy link
Owner

erthink commented Jan 18, 2021

@lithdew, please check and reopen this issue if something will wrong.

@lithdew
Copy link
Author

lithdew commented Jan 18, 2021

@lithdew, please check and reopen this issue if something will wrong.

Tried it just now - LLVM's UBsan still reports undefined behavior with the same stack trace.

$ zig build bench_mdbx
Illegal instruction at address 0x75a4ea
/home/lith/.cache/zigmod/deps/git/github.com/erthink/libmdbx/src/core.c:0:3: 0x75a4ea in mdbx_meta_set_txnid (/home/lith/.cache/zigmod/deps/git/github.com/erthink/libmdbx/src/core.c)
/home/lith/.cache/zigmod/deps/git/github.com/erthink/libmdbx/src/core.c:8879:3: 0x78a674 in mdbx_meta_model (/home/lith/.cache/zigmod/deps/git/github.com/erthink/libmdbx/src/core.c)
  mdbx_meta_set_txnid(env, model_meta, MIN_TXNID + num);
  ^
/home/lith/.cache/zigmod/deps/git/github.com/erthink/libmdbx/src/core.c:8889:22: 0x78942e in mdbx_init_metas (/home/lith/.cache/zigmod/deps/git/github.com/erthink/libmdbx/src/core.c)
  MDBX_page *page1 = mdbx_meta_model(env, page0, 0);
                     ^
/home/lith/.cache/zigmod/deps/git/github.com/erthink/libmdbx/src/core.c:9728:13: 0x764ed5 in mdbx_setup_dxb (/home/lith/.cache/zigmod/deps/git/github.com/erthink/libmdbx/src/core.c)
    meta = *mdbx_init_metas(env, buffer);
            ^
/home/lith/.cache/zigmod/deps/git/github.com/erthink/libmdbx/src/core.c:10895:22: 0x760b81 in mdbx_env_open (/home/lith/.cache/zigmod/deps/git/github.com/erthink/libmdbx/src/core.c)
  const int dxb_rc = mdbx_setup_dxb(env, lck_rc);
                     ^
/home/lith/Desktop/merkle/bench_mdbx.zig:43:24: 0xe99942 in main (bench_mdbx)
    if (c.mdbx_env_open(env, "bench_mdbx.db", env_flags, 0644) != c.MDBX_SUCCESS) {
                       ^
/home/lith/Desktop/zig/lib/std/start.zig:345:37: 0xe9aa81 in std.start.main (bench_mdbx)
            const result = root.main() catch |err| {

@erthink
Copy link
Owner

erthink commented Jan 18, 2021

Please try to disable optimization and attach the disassembly listing (like last time). Otherwise, I have no idea what caused the fall.

@lithdew
Copy link
Author

lithdew commented Jan 18, 2021

Please try to disable optimization and attach the disassembly listing (like last time). Otherwise, I have no idea what caused the fall.

Sure - optimizations are all disabled by default.

Program received signal SIGILL, Illegal instruction.
0x000000000075a4ea in mdbx_meta_set_txnid (env=<optimized out>, env@entry=0x1037a80, meta=<optimized out>, txnid=1)
    at /home/lith/.cache/zigmod/deps/git/github.com/erthink/libmdbx/src/core.c:497
497       mdbx_assert(env, (1u << env->me_psize2log) == env->me_psize);
(gdb) display/i $pc
1: x/i $pc
=> 0x75a4ea <mdbx_meta_set_txnid+698>:  ud2    
(gdb) disass 0x75a4ea
Dump of assembler code for function mdbx_meta_set_txnid:
   0x000000000075a230 <+0>:     push   %rbp
   0x000000000075a231 <+1>:     mov    %rsp,%rbp
   0x000000000075a234 <+4>:     push   %r15
   0x000000000075a236 <+6>:     push   %r14
   0x000000000075a238 <+8>:     push   %r13
   0x000000000075a23a <+10>:    push   %r12
   0x000000000075a23c <+12>:    push   %rbx
   0x000000000075a23d <+13>:    sub    $0x18,%rsp
   0x000000000075a241 <+17>:    mov    %rdx,%r14
   0x000000000075a244 <+20>:    mov    %rsi,%r13
   0x000000000075a247 <+23>:    mov    0x8a764a(%rip),%r12        # 0x1001898
   0x000000000075a24e <+30>:    testb  $0x1,(%r12)
   0x000000000075a253 <+35>:    jne    0x75a301 <mdbx_meta_set_txnid+209>
   0x000000000075a259 <+41>:    test   %r13,%r13
   0x000000000075a25c <+44>:    je     0x75a4ea <mdbx_meta_set_txnid+698>
   0x000000000075a262 <+50>:    vmovups 0x8ab49e(%rip),%xmm0        # 0x1005708 <bootid>
   0x000000000075a26a <+58>:    vmovups %xmm0,0xc0(%r13)
   0x000000000075a273 <+67>:    lea    0x8(%r13),%rbx
   0x000000000075a277 <+71>:    testb  $0x1,(%r12)
   0x000000000075a27c <+76>:    jne    0x75a411 <mdbx_meta_set_txnid+481>
   0x000000000075a282 <+82>:    test   $0x3,%bl
   0x000000000075a285 <+85>:    jne    0x75a4ea <mdbx_meta_set_txnid+698>
   0x000000000075a28b <+91>:    mov    %r14d,0x8(%r13)
   0x000000000075a28f <+95>:    cmp    $0xfffffffffffffffb,%rbx
   0x000000000075a293 <+99>:    ja     0x75a4ea <mdbx_meta_set_txnid+698>
   0x000000000075a299 <+105>:   lea    0xc(%r13),%rax
   0x000000000075a29d <+109>:   test   $0x3,%al
   0x000000000075a29f <+111>:   jne    0x75a4ea <mdbx_meta_set_txnid+698>
   0x000000000075a2a5 <+117>:   mov    %r14,%rbx
   0x000000000075a2a8 <+120>:   shr    $0x20,%rbx
   0x000000000075a2ac <+124>:   mov    %ebx,0xc(%r13)
   0x000000000075a2b0 <+128>:   lea    0xb0(%r13),%r15
   0x000000000075a2b7 <+135>:   testb  $0x1,(%r12)
   0x000000000075a2bc <+140>:   jne    0x75a439 <mdbx_meta_set_txnid+521>
   0x000000000075a2c2 <+146>:   test   $0x3,%r15b
   0x000000000075a2c6 <+150>:   jne    0x75a4ea <mdbx_meta_set_txnid+698>
   0x000000000075a2cc <+156>:   mov    %r14d,0xb0(%r13)
   0x000000000075a2d3 <+163>:   cmp    $0xfffffffffffffffb,%r15
   0x000000000075a2d7 <+167>:   ja     0x75a4ea <mdbx_meta_set_txnid+698>
   0x000000000075a2dd <+173>:   add    $0xb4,%r13
   0x000000000075a2e4 <+180>:   test   $0x3,%r13b
   0x000000000075a2e8 <+184>:   jne    0x75a4ea <mdbx_meta_set_txnid+698>
   0x000000000075a2ee <+190>:   mov    %ebx,0x0(%r13)
   0x000000000075a2f2 <+194>:   add    $0x18,%rsp
   0x000000000075a2f6 <+198>:   pop    %rbx
   0x000000000075a2f7 <+199>:   pop    %r12
   0x000000000075a2f9 <+201>:   pop    %r13
   0x000000000075a2fb <+203>:   pop    %r14
   0x000000000075a2fd <+205>:   pop    %r15
--Type <RET> for more, q to quit, c to continue without paging--
   0x000000000075a2ff <+207>:   pop    %rbp
   0x000000000075a300 <+208>:   ret    
   0x000000000075a301 <+209>:   mov    %rdi,%r15
   0x000000000075a304 <+212>:   test   $0x7,%r15b
   0x000000000075a308 <+216>:   jne    0x75a4ea <mdbx_meta_set_txnid+698>
   0x000000000075a30e <+222>:   test   %r15,%r15
   0x000000000075a311 <+225>:   je     0x75a4ea <mdbx_meta_set_txnid+698>
   0x000000000075a317 <+231>:   lea    0x8(%r15),%rdi
   0x000000000075a31b <+235>:   test   $0x7,%dil
   0x000000000075a31f <+239>:   jne    0x75a4ea <mdbx_meta_set_txnid+698>
   0x000000000075a325 <+245>:   lea    0x54(%r15),%rdx
   0x000000000075a329 <+249>:   test   $0x3,%dl
   0x000000000075a32c <+252>:   jne    0x75a4ea <mdbx_meta_set_txnid+698>
   0x000000000075a332 <+258>:   movzbl (%rdx),%eax
   0x000000000075a335 <+261>:   cmp    $0x1f,%eax
   0x000000000075a338 <+264>:   ja     0x75a4ea <mdbx_meta_set_txnid+698>
   0x000000000075a33e <+270>:   lea    0x50(%r15),%rsi
   0x000000000075a342 <+274>:   test   $0x7,%sil
   0x000000000075a346 <+278>:   jne    0x75a4ea <mdbx_meta_set_txnid+698>
   0x000000000075a34c <+284>:   mov    0x8(%r15),%rbx
   0x000000000075a350 <+288>:   mov    $0x1,%ecx
   0x000000000075a355 <+293>:   shlx   %eax,%ecx,%eax
   0x000000000075a35a <+298>:   cmp    (%rsi),%eax
   0x000000000075a35c <+300>:   jne    0x75a462 <mdbx_meta_set_txnid+562>
   0x000000000075a362 <+306>:   test   $0x3,%dl
   0x000000000075a365 <+309>:   jne    0x75a4ea <mdbx_meta_set_txnid+698>
   0x000000000075a36b <+315>:   movzbl (%rdx),%eax
   0x000000000075a36e <+318>:   cmp    $0x3f,%eax
   0x000000000075a371 <+321>:   ja     0x75a4ea <mdbx_meta_set_txnid+698>
   0x000000000075a377 <+327>:   test   %rbx,%rbx
   0x000000000075a37a <+330>:   je     0x75a4ea <mdbx_meta_set_txnid+698>
   0x000000000075a380 <+336>:   cmp    $0xffffffffffffffec,%rbx
   0x000000000075a384 <+340>:   jae    0x75a4ea <mdbx_meta_set_txnid+698>
   0x000000000075a38a <+346>:   add    $0x14,%rbx
   0x000000000075a38e <+350>:   cmp    %r13,%rbx
   0x000000000075a391 <+353>:   ja     0x75a259 <mdbx_meta_set_txnid+41>
   0x000000000075a397 <+359>:   mov    (%rdi),%rdi
   0x000000000075a39a <+362>:   testb  $0x1,(%r12)
   0x000000000075a39f <+367>:   jne    0x75a4a0 <mdbx_meta_set_txnid+624>
   0x000000000075a3a5 <+373>:   movzbl (%rdx),%eax
   0x000000000075a3a8 <+376>:   cmp    $0x3f,%rax
   0x000000000075a3ac <+380>:   ja     0x75a4ea <mdbx_meta_set_txnid+698>
   0x000000000075a3b2 <+386>:   mov    $0x3,%ecx
   0x000000000075a3b7 <+391>:   shlx   %rax,%rcx,%rax
   0x000000000075a3bc <+396>:   add    %rdi,%rax
   0x000000000075a3bf <+399>:   cmp    %rdi,%rax
   0x000000000075a3c2 <+402>:   jb     0x75a4ea <mdbx_meta_set_txnid+698>
   0x000000000075a3c8 <+408>:   test   %rdi,%rdi
   0x000000000075a3cb <+411>:   je     0x75a4ea <mdbx_meta_set_txnid+698>
   0x000000000075a3d1 <+417>:   test   %rax,%rax
--Type <RET> for more, q to quit, c to continue without paging--
   0x000000000075a3d4 <+420>:   je     0x75a4ea <mdbx_meta_set_txnid+698>
   0x000000000075a3da <+426>:   cmp    $0xffffffffffffffec,%rax
   0x000000000075a3de <+430>:   jae    0x75a4ea <mdbx_meta_set_txnid+698>
   0x000000000075a3e4 <+436>:   add    $0x14,%rax
   0x000000000075a3e8 <+440>:   cmp    %r13,%rax
   0x000000000075a3eb <+443>:   jb     0x75a259 <mdbx_meta_set_txnid+41>
   0x000000000075a3f1 <+449>:   lea    -0x4f4154(%rip),%rsi        # 0x2662a4
   0x000000000075a3f8 <+456>:   lea    -0x4d94e7(%rip),%rdx        # 0x280f18
   0x000000000075a3ff <+463>:   mov    %r15,%rdi
   0x000000000075a402 <+466>:   mov    $0x1140,%ecx
   0x000000000075a407 <+471>:   call   0x79ba70 <mdbx_assert_fail>
   0x000000000075a40c <+476>:   jmp    0x75a259 <mdbx_meta_set_txnid+41>
   0x000000000075a411 <+481>:   test   $0x3,%bl
   0x000000000075a414 <+484>:   je     0x75a282 <mdbx_meta_set_txnid+82>
   0x000000000075a41a <+490>:   lea    -0x554cde(%rip),%rsi        # 0x205743
   0x000000000075a421 <+497>:   lea    -0x4e249c(%rip),%rdx        # 0x277f8c
   0x000000000075a428 <+504>:   xor    %edi,%edi
   0x000000000075a42a <+506>:   mov    $0x9c,%ecx
   0x000000000075a42f <+511>:   call   0x79ba70 <mdbx_assert_fail>
   0x000000000075a434 <+516>:   jmp    0x75a282 <mdbx_meta_set_txnid+82>
   0x000000000075a439 <+521>:   test   $0x3,%r15b
   0x000000000075a43d <+525>:   je     0x75a2c2 <mdbx_meta_set_txnid+146>
   0x000000000075a443 <+531>:   lea    -0x554d07(%rip),%rsi        # 0x205743
   0x000000000075a44a <+538>:   lea    -0x4e24c5(%rip),%rdx        # 0x277f8c
   0x000000000075a451 <+545>:   xor    %edi,%edi
   0x000000000075a453 <+547>:   mov    $0x9c,%ecx
   0x000000000075a458 <+552>:   call   0x79ba70 <mdbx_assert_fail>
   0x000000000075a45d <+557>:   jmp    0x75a2c2 <mdbx_meta_set_txnid+146>
   0x000000000075a462 <+562>:   mov    %rsi,-0x40(%rbp)
   0x000000000075a466 <+566>:   lea    -0x5196ce(%rip),%rsi        # 0x240d9f
   0x000000000075a46d <+573>:   mov    %rdx,-0x30(%rbp)
   0x000000000075a471 <+577>:   lea    -0x4f0281(%rip),%rdx        # 0x26a1f7
   0x000000000075a478 <+584>:   mov    %rdi,-0x38(%rbp)
   0x000000000075a47c <+588>:   mov    %r15,%rdi
   0x000000000075a47f <+591>:   mov    $0x1f1,%ecx
   0x000000000075a484 <+596>:   call   0x79ba70 <mdbx_assert_fail>
   0x000000000075a489 <+601>:   mov    -0x38(%rbp),%rdi
   0x000000000075a48d <+605>:   mov    -0x40(%rbp),%rsi
   0x000000000075a491 <+609>:   mov    -0x30(%rbp),%rdx
   0x000000000075a495 <+613>:   test   $0x3,%dl
   0x000000000075a498 <+616>:   je     0x75a36b <mdbx_meta_set_txnid+315>
   0x000000000075a49e <+622>:   jmp    0x75a4ea <mdbx_meta_set_txnid+698>
   0x000000000075a4a0 <+624>:   cmp    $0x1f,%al
   0x000000000075a4a2 <+626>:   ja     0x75a4ea <mdbx_meta_set_txnid+698>
   0x000000000075a4a4 <+628>:   test   $0x7,%sil
   0x000000000075a4a8 <+632>:   jne    0x75a4ea <mdbx_meta_set_txnid+698>
   0x000000000075a4aa <+634>:   mov    %rdx,%rbx
   0x000000000075a4ad <+637>:   mov    $0x1,%ecx
   0x000000000075a4b2 <+642>:   shlx   %eax,%ecx,%eax
   0x000000000075a4b7 <+647>:   cmp    (%rsi),%eax
--Type <RET> for more, q to quit, c to continue without paging--
   0x000000000075a4b9 <+649>:   je     0x75a3a5 <mdbx_meta_set_txnid+373>
   0x000000000075a4bf <+655>:   lea    -0x519727(%rip),%rsi        # 0x240d9f
   0x000000000075a4c6 <+662>:   lea    -0x4f02d6(%rip),%rdx        # 0x26a1f7
   0x000000000075a4cd <+669>:   mov    %rdi,-0x30(%rbp)
   0x000000000075a4d1 <+673>:   mov    %r15,%rdi
   0x000000000075a4d4 <+676>:   mov    $0x1f1,%ecx
   0x000000000075a4d9 <+681>:   call   0x79ba70 <mdbx_assert_fail>
   0x000000000075a4de <+686>:   mov    -0x30(%rbp),%rdi
   0x000000000075a4e2 <+690>:   mov    %rbx,%rdx
   0x000000000075a4e5 <+693>:   jmp    0x75a3a5 <mdbx_meta_set_txnid+373>
=> 0x000000000075a4ea <+698>:   ud2    
End of assembler dump.

@erthink
Copy link
Owner

erthink commented Jan 18, 2021

This code looks partially optimized.
At least compiler generated one UD2 instruction and about 25 conditional jumps to it for cases the UB rules were violated.
So it is impossible to understand which rule was violated without step-by-step tracing of the function in the debugger.

Please try to do this.
If you don't succeed, I'll do it myself, but probably not before the end of this week.

@erthink
Copy link
Owner

erthink commented Jan 20, 2021

I tried to reproduce the problem on Fedora 33 with clang 11 in two cases:

  1. By default make test-ubsantarget which uses the -Ofast -fsanitize=undefined -fsanitize-undefined-trap-on-error compiler flags. This is done by $ CC=clang CXX=clang++ make test-ubsan -j4 command for basic test and then by $ ./test/long_stochastic.sh for extended.
  2. Same as above but with editing GNUmakefile to use -O -fsanitize=undefined -shared-libsan compiler flags and set LD_LIBRARY_PATH=/usr/lib64/clang/11.0.0/lib magic to avoid minor clang's rpath-bug.

Both cases don't reproduce the reported issue nor exposed any other bugs.

$ clang --version
clang version 11.0.0 (Fedora 11.0.0-2.fc33)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

@erthink
Copy link
Owner

erthink commented Jan 20, 2021

For reference and investigation below are three listings the body of mdbx_meta_set_txnid():

  1. for first case above with addinional __noinline to function (otherwise it is always inlined and no mdbx_meta_set_txnid symbol was provided): listing-1-with-Ofast-trap-noinline.txt
  2. for second case above: listing-2-with-O-lib.txt
  3. for first case above but with -O0: listing-3-with-O0-trap.txt

All listings created just by $ objdump --disassemble=mdbx_meta_set_txnid libmdbx.so.

@erthink
Copy link
Owner

erthink commented Jan 20, 2021

Confirmed.
CLANG detects a few false-positive UB which provoked by assertion check:

  • Address arithmetic with NULL (without dereferencing, and no type-id is needed).
    This seems enough stupid, literally like an already fixed bug with the definition of UB within offsetof macro.
  • Address arithmetic with fixed-sized arrays ((without dereferencing) when the result (not a target) address beyond the end of an array. Also seems enough stupid as above.

Nonetheless this allows me to clean up these assertions.

@erthink
Copy link
Owner

erthink commented Jan 20, 2021

@lithdew, please check the devel branch and close this issue on success.

@lithdew
Copy link
Author

lithdew commented Jan 20, 2021

@lithdew, please check the devel branch and close this issue on success.

Thanks! Just confirmed it, no longer detecting any undefined behavior.

@lithdew lithdew closed this as completed Jan 20, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants