Project

General

Profile

Actions

Bug #1308

closed

end of list / NULL pointer check cds_hlist_for_each_entry_rcu_2 gets optimized away

Added by Andreas Schultz almost 3 years ago. Updated almost 3 years ago.

Status:
Resolved
Priority:
Normal
Assignee:
-
Target version:
-
Start date:
04/20/2021
Due date:
% Done:

100%

Estimated time:

Description

The NULL check cds_hlist_for_each_entry_rcu_2 gets optimized away by newer gcc's, resulting in a endless loop that will segfaults when it dereference the NULL pointer at the end of the list.

Distro: Ubuntu Hirsute
GCC: gcc version 10.3.0 (Ubuntu 10.3.0-1ubuntu1)

Reproduce:

run doc/examples/hlist/cds_hlist_for_each_entry_rcu

$ gdb  doc/examples/hlist/cds_hlist_for_each_entry_rcu 
GNU gdb (Ubuntu 10.1-2ubuntu2) 10.1.90.20210411-git
Copyright (C) 2021 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
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-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://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 doc/examples/hlist/cds_hlist_for_each_entry_rcu...
(gdb) run
Starting program: /usr/src/components/userspace-rcu/doc/examples/hlist/cds_hlist_for_each_entry_rcu 
Download failed: Function not implemented.  Continuing without debug info for /lib64/ld-linux-x86-64.so.2.
Download failed: Function not implemented.  Continuing without debug info for /usr/src/components/userspace-rcu/system-supplied DSO at 0x7ffff7fc7000.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
main () at cds_hlist_for_each_entry_rcu.c:75
75            printf(" %d", node->value);
(gdb) print node
$1 = (struct mynode *) 0xfffffffffffffff8

objdump -S proves the missing NULL check:

    /*
     * This traversal can be performed concurrently with RCU
     * updates.
     */
    cds_hlist_for_each_entry_rcu_2(node, &mylist, node) {
    11f2:    48 8b 7c 24 08           mov    0x8(%rsp),%rdi
    11f7:    e8 d4 fe ff ff           call   10d0 <rcu_dereference_sym@plt>
    11fc:    48 8d 58 f8              lea    -0x8(%rax),%rbx

>>> around here should be a NULL pointer check 

    1200:    8b 13                    mov    (%rbx),%edx
    1202:    48 89 ee                 mov    %rbp,%rsi
    1205:    bf 01 00 00 00           mov    $0x1,%edi
    120a:    31 c0                    xor    %eax,%eax
    120c:    e8 ff fe ff ff           call   1110 <__printf_chk@plt>
    1211:    48 8b 7b 08              mov    0x8(%rbx),%rdi
    1215:    e8 b6 fe ff ff           call   10d0 <rcu_dereference_sym@plt>
    121a:    48 8d 58 f8              lea    -0x8(%rax),%rbx
    121e:    eb e0                    jmp    1200 <main+0xc0>
Actions

Also available in: Atom PDF