netblue30 / firejail

Linux namespaces and seccomp-bpf sandbox
https://firejail.wordpress.com
GNU General Public License v2.0
5.81k stars 567 forks source link

`--build` creates invalid paths with "after,$HOME" $HOME expanded #4592

Open matu3ba opened 3 years ago

matu3ba commented 3 years ago

Description

Path handling for firejail --build nvim is broken.

Steps to Reproduce

Steps to reproduce the behavior

  1. Run in bash LANG=C firejail --build nvim
  2. See result contains stuff like allow ${HOME}/.local/share/nvim/site/after,/etc/xdg/nvim/after,/home/misterspoon/.config/kdedefaults/nvim/after,/home/misterspoon/.config/nvim/after/start
  3. Install from git to have profile lookup.
  4. firejail nvim
  5. Get error shown in actual behavior

Expected behavior

There should be never invalid paths generated. I hope this code is not used elsewhere.

Actual behavior

site/after,/ ... nvim/after, and especially /kdedefaults/nvim/after, looks broken. Invalid path generated.

Error: "${HOME}/.local/share/nvim/site/after,/etc/xdg/nvim/after,/home/misterspoon/.config/kdedefaults/nvim/after,/home/misterspoon/.config/nvim/after/start" is an invalid filename: rejected character: ","

Additional context

PATH contains the path to nvim installation from source. I have a file $HOME/.local/share/nvim/site/pack/packer/start/coq_nvim/.vars/runtime/lib/python3.9/site-packages/pip/_vendor/tenacity/after.py and $HOME/.local/share/nvim/site/pack/packer/start/coq_nvim/.vars/runtime/lib/python3.9/site-packages/pip/_vendor/tenacity/pycache/after.cpython-39.pyc.

Environment

Checklist

Log

Output of firejail --build nvim

``` # Firejail profile for nvim # Persistent local customizations #include nvim.local # Persistent global definitions #include globals.local ### Basic Blacklisting ### ### Enable as many of them as you can! A very important one is ### "disable-exec.inc". This will make among other things your home ### and /tmp directories non-executable. include disable-common.inc # dangerous directories like ~/.ssh and ~/.gnupg #include disable-devel.inc # development tools such as gcc and gdb #include disable-exec.inc # non-executable directories such as /var, /tmp, and /home #include disable-interpreters.inc # perl, python, lua etc. include disable-programs.inc # user configuration for programs such as firefox, vlc etc. #include disable-shell.inc # sh, bash, zsh etc. #include disable-xdg.inc # standard user directories: Documents, Pictures, Videos, Music ### Home Directory Whitelisting ### ### If something goes wrong, this section is the first one to comment out. ### Instead, you'll have to relay on the basic blacklisting above. allow ${HOME}/.local/nvim/lib/nvim allow ${HOME}/.gitconfig allow ${HOME}/.config/git allow ${HOME}/.local/nvim/lib/nvim/plugin allow ${HOME}/.local/share/nvim allow ${HOME}/.local/share/nvim/site/plugin allow ${HOME}/.local/share/nvim/site/after/pack allow ${HOME}/.local/share/nvim/site/after/start allow ${HOME}/.local/nvim/lib/nvim/ftdetect allow ${HOME}/.local/share/nvim/site/pack/packer/start/zig.vim/ftdetect allow ${HOME}/.local/share/nvim/site/pack/packer/start/zig.vim/ftdetect/ allow ${HOME}/.local/share/nvim/site/pack/packer/start/which-key.nvim/ftdetect allow ${HOME}/.local/share/nvim/site/pack/packer/start/todo-comments.nvim/ftdetect allow ${HOME}/.local/share/nvim/site/pack/packer/start/telescope.nvim/ftdetect allow ${HOME}/.local/share/nvim/site/pack/packer/start/telescope-project.nvim/ftdetect allow ${HOME}/.local/share/nvim/site/pack/packer/start/telescope-fzf-native.nvim/ftdetect allow ${HOME}/.local/share/nvim/site/pack/packer/start/popup.nvim/ftdetect allow ${HOME}/.local/share/nvim/site/pack/packer/start/plenary.nvim/ftdetect allow ${HOME}/.local/share/nvim/site/pack/packer/start/packer.nvim/ftdetect allow ${HOME}/.local/share/nvim/site/pack/packer/start/one-small-step-for-vimkind/ftdetect allow ${HOME}/.local/share/nvim/site/pack/packer/start/nvim-luadev/ftdetect allow ${HOME}/.local/share/nvim/site/pack/packer/start/nvim-lspconfig/ftdetect allow ${HOME}/.local/share/nvim/site/pack/packer/start/material.nvim/ftdetect allow ${HOME}/.local/share/nvim/site/pack/packer/start/lightspeed.nvim/ftdetect allow ${HOME}/.local/share/nvim/site/pack/packer/start/gitsigns.nvim/ftdetect allow ${HOME}/.local/share/nvim/site/pack/packer/start/coq_nvim/ftdetect allow ${HOME}/.local/share/nvim/site/pack/packer/start/coq_nvim/ftdetect/ allow ${HOME}/.local/share/nvim/site/pack/packer/start/coq.artifacts/ftdetect allow ${HOME}/.local/share/nvim/site/ftdetect allow ${HOME}/.local/share/nvim/site/pack/packer/start/material.nvim/lua/material allow ${HOME}/.local/share/nvim/site/pack/packer/start/material.nvim/colors allow ${HOME}/.local/share/nvim/site/pack/packer/start/telescope-project.nvim/lua/telescope/_extensions allow ${HOME}/.local/share/nvim/site/pack/packer/start/telescope-fzf-native.nvim/lua allow ${HOME}/.local/share/nvim/site/pack/packer/start/telescope-fzf-native.nvim/lua/telescope/_extensions allow ${HOME}/.local/share/nvim/site/pack/packer/start/plenary.nvim/lua/plenary allow ${HOME}/.local/share/nvim/site/pack/packer/start/telescope.nvim/lua/telescope allow ${HOME}/.local/share/nvim/site/pack/packer/start/nvim-lspconfig/lua allow ${HOME}/.local/share/nvim/site/pack/packer/start/packer.nvim/lua allow ${HOME}/.local/share/nvim/site/after,/etc/xdg/nvim/after,/home/misterspoon/.config/kdedefaults/nvim/after,/home/misterspoon/.config/nvim/after/start allow ${HOME}/.local/share/nvim/site/after,/etc/xdg/nvim/after,/home/misterspoon/.config/kdedefaults/nvim/after,/home/misterspoon/.config/nvim/after/pack allow ${HOME}/.local/nvim/lib/nvim/start allow ${HOME}/.local/nvim/lib/nvim/pack allow ${HOME}/.local/share/nvim/site/start allow ${HOME}/.local/share/nvim/site/pack/packer/start/ allow ${HOME}/.local/share/nvim/site/pack/ allow ${HOME}/.config/nvim allow ${HOME}/.local/nvim/share/nvim allow ${HOME}/.config/kdedefaults/nvim allow ${HOME}/.terminfo/78 allow ${HOME}/.terminfo/x allow ${HOME}/.cache/nvim include whitelist-common.inc ### Filesystem Whitelisting ### allow /usr/share/nvim allow /usr/share/terminfo include whitelist-usr-share-common.inc include whitelist-var-common.inc #apparmor # if you have AppArmor running, try this one! caps.drop all ipc-namespace netfilter #no3d # disable 3D acceleration #nodvd # disable DVD and CD devices #nogroups # disable supplementary user groups #noinput # disable input devices nonewprivs noroot #notv # disable DVB TV devices #nou2f # disable U2F devices #novideo # disable video capture devices protocol unix, net none seccomp shell none tracelog #disable-mnt # no access to /mnt, /media, /run/mount and /run/media private-bin tmux,python3.9,git #private-cache # run with an empty ~/.cache directory private-dev private-etc gitconfig,xdg, #private-lib #private-tmp # File accessed in /tmp directory: # /tmp/nvimKbSKzZ/, #dbus-user none #dbus-system none #memory-deny-write-execute ```

matu3ba commented 3 years ago

looks like a wild pointer to me. The only occurence of after is in build_profile.c on line 95: printf("--- Built profile beings after this line ---\n"); Is there a way to run firejail within valgrind or do I need to use gdb for this?

UPDATED description.

rusty-snake commented 3 years ago

Is there a way to run firejail within valgrind or do I need to use gdb for this?

Maybe this is helpful https://github.com/netblue30/firejail/wiki/Debugging-Firejail#advanced-troubleshooting.

ASAN build would be nice too however I did not make it work so far.

smitsohu commented 3 years ago

Just run fbuilder manually. It will be much easier to debug.

/usr/lib64/firejail/fbuilder nvim (probably)

smitsohu commented 3 years ago

ASAN build would be nice too however I did not make it work so far.

+1 I also tried a while back but didn't make it past an endless loop in the instrumented binary.

matu3ba commented 3 years ago

nvm. I should not use mold for this stuff.

~~The binary seems very messed up. valgrind cant read the debug sections. Can you confirm this? Changing common.mk by removing -O2 did not change this for me.~~

objdump -h fbuilder returns very oddly looking 2 .rodata sections

12 .rodata       00000202  0000000000001a50  0000000000001a50  00001a50  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
13 .rodata       00001260  0000000000001c60  0000000000001c60  00001c60  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
``` fbuilder: file format elf64-x86-64 Sections: Idx Name Size VMA LMA File off Algn 0 .interp 0000001c 0000000000000270 0000000000000270 00000270 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 1 .note.gnu.build-id 00000024 000000000000028c 000000000000028c 0000028c 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 2 .note.ABI-tag 00000020 00000000000002b0 00000000000002b0 000002b0 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 3 .dynsym 000003c0 0000000000000618 0000000000000618 00000618 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 4 .rela.plt 00000348 00000000000002d0 00000000000002d0 000002d0 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 5 .dynstr 000001ce 00000000000009d8 00000000000009d8 000009d8 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 6 .eh_frame 00000838 0000000000000ba8 0000000000000ba8 00000ba8 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 7 .eh_frame_hdr 00000114 00000000000013e0 00000000000013e0 000013e0 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 8 .gnu.hash 00000100 00000000000014f8 00000000000014f8 000014f8 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 9 .rela.dyn 00000360 00000000000015f8 00000000000015f8 000015f8 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 10 .gnu.version 00000050 0000000000001958 0000000000001958 00001958 2**1 CONTENTS, ALLOC, LOAD, READONLY, DATA 11 .gnu.version_r 000000a0 00000000000019a8 00000000000019a8 000019a8 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 12 .rodata 00000202 0000000000001a50 0000000000001a50 00001a50 2**4 CONTENTS, ALLOC, LOAD, READONLY, DATA 13 .rodata 00001260 0000000000001c60 0000000000001c60 00001c60 2**4 CONTENTS, ALLOC, LOAD, READONLY, DATA 14 .plt 00000240 0000000000003000 0000000000003000 00003000 2**4 CONTENTS, ALLOC, LOAD, READONLY, CODE 15 .fini 0000000d 0000000000003240 0000000000003240 00003240 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 16 .init 0000001b 0000000000003250 0000000000003250 00003250 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 17 .text 00003205 0000000000003270 0000000000003270 00003270 2**4 CONTENTS, ALLOC, LOAD, READONLY, CODE 18 .got 00000028 0000000000007000 0000000000007000 00007000 2**3 CONTENTS, ALLOC, LOAD, DATA 19 .dynamic 00000220 0000000000007028 0000000000007028 00007028 2**3 CONTENTS, ALLOC, LOAD, DATA 20 .data.rel.ro 000000f0 0000000000007260 0000000000007260 00007260 2**5 CONTENTS, ALLOC, LOAD, DATA 21 .fini_array 00000008 0000000000007350 0000000000007350 00007350 2**3 CONTENTS, ALLOC, LOAD, DATA 22 .init_array 00000008 0000000000007358 0000000000007358 00007358 2**3 CONTENTS, ALLOC, LOAD, DATA 23 .got.plt 00000130 0000000000008000 0000000000008000 00008000 2**3 CONTENTS, ALLOC, LOAD, DATA 24 .data 00000010 0000000000008130 0000000000008130 00008130 2**3 CONTENTS, ALLOC, LOAD, DATA 25 .tm_clone_table 00000000 0000000000008140 0000000000008140 00008140 2**3 CONTENTS, ALLOC, LOAD, DATA 26 .dynbss 00000048 0000000000008140 0000000000008140 00008140 2**6 ALLOC 27 .bss 00000074 0000000000008188 0000000000008188 00008140 2**3 ALLOC 28 .comment 0000006e 0000000000000000 0000000000000000 00008140 2**0 CONTENTS, READONLY ```

~~and valgrind has problem to read the debug data: valgrind --leak-check=full -s ./fbuilder ~/.local/nvim/bin/nvim +q~~

``` ==277551== Memcheck, a memory error detector ==277551== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==277551== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info ==277551== Command: ./fbuilder /home/misterspoon/.local/nvim/bin/nvim ==277551== --277551-- WARNING: Serious error when reading debug info --277551-- When reading debug info from /usr/local/lib/firejail/fbuilder: --277551-- Can't make sense of .rodata section mapping --- Built profile beings after this line --- # Save this file as "application.profile" (change "application" with the # program name) in ~/.config/firejail directory. Firejail will find it # automatically every time you sandbox your application. # # Run "firejail application" to test it. In the file there are # some other commands you can try. Enable them by removing the "#". # Firejail profile for /home/misterspoon/.local/nvim/bin/nvim # Persistent local customizations #include /home/misterspoon/.local/nvim/bin/nvim.local # Persistent global definitions #include globals.local ### Basic Blacklisting ### ### Enable as many of them as you can! A very important one is ### "disable-exec.inc". This will make among other things your home ### and /tmp directories non-executable. include disable-common.inc # dangerous directories like ~/.ssh and ~/.gnupg #include disable-devel.inc # development tools such as gcc and gdb #include disable-exec.inc # non-executable directories such as /var, /tmp, and /home #include disable-interpreters.inc # perl, python, lua etc. include disable-programs.inc # user configuration for programs such as firefox, vlc etc. #include disable-shell.inc # sh, bash, zsh etc. #include disable-xdg.inc # standard user directories: Documents, Pictures, Videos, Music ### Home Directory Whitelisting ### ### If something goes wrong, this section is the first one to comment out. ### Instead, you'll have to relay on the basic blacklisting above. allow ${HOME}/.local/nvim/lib/nvim allow ${HOME}/.gitconfig allow ${HOME}/.config/git allow ${HOME}/.local/nvim/lib/nvim/plugin allow ${HOME}/.local/share/nvim allow ${HOME}/.local/share/nvim/site/plugin allow ${HOME}/.local/share/nvim/site/after/pack allow ${HOME}/.local/share/nvim/site/after/start allow ${HOME}/.local/nvim/lib/nvim/ftdetect allow ${HOME}/.local/share/nvim/site/ftdetect allow ${HOME}/.local/share/nvim/site/after,/etc/xdg/nvim/after,/home/misterspoon/.config/kdedefaults/nvim/after,/home/misterspoon/.config/nvim/after/start allow ${HOME}/.local/share/nvim/site/after,/etc/xdg/nvim/after,/home/misterspoon/.config/kdedefaults/nvim/after,/home/misterspoon/.config/nvim/after/pack allow ${HOME}/.local/nvim/lib/nvim/start allow ${HOME}/.local/nvim/lib/nvim/pack allow ${HOME}/.local/share/nvim/site/start allow ${HOME}/.local/share/nvim/site/pack allow ${HOME}/.config/nvim allow ${HOME}/.local/nvim/share/nvim allow ${HOME}/.config/kdedefaults/nvim allow ${HOME}/.terminfo/78 allow ${HOME}/.terminfo/x allow ${HOME}/.cache/nvim include whitelist-common.inc ### Filesystem Whitelisting ### allow /usr/share/nvim allow /usr/share/terminfo include whitelist-usr-share-common.inc include whitelist-var-common.inc #apparmor # if you have AppArmor running, try this one! caps.drop all ipc-namespace netfilter #no3d # disable 3D acceleration #nodvd # disable DVD and CD devices #nogroups # disable supplementary user groups #noinput # disable input devices nonewprivs noroot #notv # disable DVB TV devices #nou2f # disable U2F devices #novideo # disable video capture devices protocol unix, net none seccomp shell none tracelog #disable-mnt # no access to /mnt, /media, /run/mount and /run/media private-bin tmux,python3.9,git, #private-cache # run with an empty ~/.cache directory private-dev private-etc gitconfig,xdg, #private-lib #private-tmp # File accessed in /tmp directory: # /tmp/nvim9GQeu7/, #dbus-user none #dbus-system none #memory-deny-write-execute ==277551== ==277551== HEAP SUMMARY: ==277551== in use at exit: 1,559 bytes in 61 blocks ==277551== total heap usage: 2,526 allocs, 2,465 frees, 307,669 bytes allocated ==277551== ==277551== 35 bytes in 1 blocks are definitely lost in loss record 19 of 21 ==277551== at 0x483E7C5: malloc (vg_replace_malloc.c:380) ==277551== by 0x4911C5F: __vasprintf_internal (in /usr/lib/libc-2.33.so) ==277551== by 0x49A18C2: __asprintf_chk (in /usr/lib/libc-2.33.so) ==277551== by 0x10CA1E: ??? (in /usr/local/lib/firejail/fbuilder) ==277551== by 0x10E07C: ??? (in /usr/local/lib/firejail/fbuilder) ==277551== by 0x1FFF000575: ??? ==277551== by 0x656D6F682F007264: ??? ==277551== by 0x7372657473696D2E: ??? ==277551== by 0x6F6C2E2F6E6F6F6F: ??? ==277551== by 0x6D69766E2F6C6162: ??? ==277551== by 0x69766E2F6E69622E: ??? ==277551== by 0x3D4C4C454853006C: ??? ==277551== ==277551== LEAK SUMMARY: ==277551== definitely lost: 35 bytes in 1 blocks ==277551== indirectly lost: 0 bytes in 0 blocks ==277551== possibly lost: 0 bytes in 0 blocks ==277551== still reachable: 1,524 bytes in 60 blocks ==277551== suppressed: 0 bytes in 0 blocks ==277551== Reachable blocks (those to which a pointer was found) are not shown. ==277551== To see them, rerun with: --leak-check=full --show-leak-kinds=all ==277551== ==277551== For lists of detected and suppressed errors, rerun with: -s ==277551== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) [misterspoon@pc firejail]$ valgrind --leak-check=full -s ./fbuilder ~/.local/nvim/bin/nvim +q ==277595== Memcheck, a memory error detector ==277595== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==277595== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info ==277595== Command: ./fbuilder /home/misterspoon/.local/nvim/bin/nvim +q ==277595== --277595-- WARNING: Serious error when reading debug info --277595-- When reading debug info from /usr/local/lib/firejail/fbuilder: --277595-- Can't make sense of .rodata section mapping Error: cannot run the sandbox ==277595== ==277595== HEAP SUMMARY: ==277595== in use at exit: 35 bytes in 1 blocks ==277595== total heap usage: 2 allocs, 1 frees, 135 bytes allocated ==277595== ==277595== LEAK SUMMARY: ==277595== definitely lost: 0 bytes in 0 blocks ==277595== indirectly lost: 0 bytes in 0 blocks ==277595== possibly lost: 0 bytes in 0 blocks ==277595== still reachable: 35 bytes in 1 blocks ==277595== suppressed: 0 bytes in 0 blocks ==277595== Reachable blocks (those to which a pointer was found) are not shown. ==277595== To see them, rerun with: --leak-check=full --show-leak-kinds=all ==277595== ==277595== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) ```
rusty-snake commented 3 years ago

Building with -fanalyzer (gcc (GCC) 11.2.1 20210728 (Red Hat 11.2.1-1)) finds

filedb.c:71:22: error: use of possibly-NULL ‘strdup(fname)’ where non-null expected [CWE-690] [-Werror=analyzer-possible-null-argument] ``` filedb.c: In function ‘filedb_add.part.0’: filedb.c:71:22: error: use of possibly-NULL ‘strdup(fname)’ where non-null expected [CWE-690] [-Werror=analyzer-possible-null-argument] 71 | entry->len = strlen(entry->fname); | ^~~~~~~~~~~~~~~~~~~~ ‘filedb_load_whitelist’: event 1 | | 90 | FileDB *filedb_load_whitelist(FileDB *head, const char *fname, const char *prefix) { | | ^~~~~~~~~~~~~~~~~~~~~ | | | | | (1) entry to ‘filedb_load_whitelist’ | ‘filedb_load_whitelist’: event 2 | | 91 | assert(fname); | | ^~~~~~ | | | | | (2) following ‘true’ branch (when ‘fname’ is non-NULL)... | ‘filedb_load_whitelist’: event 3 | | 92 | assert(prefix); | | ^~~~~~ | | | | | (3) ...to here | ‘filedb_load_whitelist’: event 4 | | 92 | assert(prefix); | | ^~~~~~ | | | | | (4) following ‘true’ branch (when ‘prefix’ is non-NULL)... | ‘filedb_load_whitelist’: events 5-6 | | 93 | int len = strlen(prefix); | | ^~~ | | | | | (5) ...to here | 94 | char *f; | 95 | if (asprintf(&f, "%s/%s", SYSCONFDIR, fname) == -1) | | ~ | | | | | (6) following ‘false’ branch... | ‘filedb_load_whitelist’: event 7 | |../include/common.h:39:28: | 39 | #define errExit(msg) do { char msgout[500]; snprintf(msgout, 500, "Error %s: %s:%d %s", msg, __FILE__, __LINE__, __FUNCTION__); perror(msgout); exit(1);} while (0) | | ^ | | | | | (7) ...to here filedb.c:96:17: note: in expansion of macro ‘errExit’ | 96 | errExit("asprintf"); | | ^~~~~~~ | ‘filedb_load_whitelist’: event 8 | | 98 | if (!fp) { | | ^ | | | | | (8) following ‘false’ branch (when ‘fp’ is non-NULL)... | ‘filedb_load_whitelist’: event 9 | |cc1: | (9): ...to here | ‘filedb_load_whitelist’: events 10-16 | | 105 | while (fgets(buf, MAX_BUF, fp)) { | | ^~~~~ | | | | | (10) following ‘true’ branch... | 106 | if (strncmp(buf, prefix, len) != 0) | | ~~ ~ | | | | | | | (12) following ‘false’ branch... | | (11) ...to here |...... | 109 | char *fn = buf + len; | | ~~~~ | | | | | (13) ...to here | 110 | char *ptr = strchr(buf, '\n'); | 111 | if (!ptr) | | ~ | | | | | (14) following ‘false’ branch (when ‘ptr’ is non-NULL)... | 112 | continue; | 113 | *ptr = '\0'; | | ~ | | | | | (15) ...to here |...... | 116 | head = filedb_add(head, fn); | | ~~~~~~~~~~~~~~~~~~~~ | | | | | (16) calling ‘filedb_add’ from ‘filedb_load_whitelist’ | +--> ‘filedb_add’: event 17 | | 54 | FileDB *filedb_add(FileDB *head, const char *fname) { | | ^~~~~~~~~~ | | | | | (17) entry to ‘filedb_add’ | ‘filedb_add’: event 18 | | 55 | assert(fname); | | ^~~~~~ | | | | | (18) following ‘true’ branch (when ‘fname’ is non-NULL)... | ‘filedb_add’: events 19-20 | | 60 | if (filedb_find(head, fname)) | | ^~ ~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | | | (20) calling ‘filedb_find’ from ‘filedb_add’ | | (19) ...to here | +--> ‘filedb_find’: event 21 | | 24 | FileDB *filedb_find(FileDB *head, const char *fname) { | | ^~~~~~~~~~~ | | | | | (21) entry to ‘filedb_find’ | ‘filedb_find’: event 22 | | 25 | assert(fname); | | ^~~~~~ | | | | | (22) following ‘true’ branch (when ‘fname’ is non-NULL)... | ‘filedb_find’: events 23-29 | | 26 | FileDB *ptr = head; | | ^~~~~~ | | | | | (23) ...to here |...... | 30 | while (ptr) { | | ~~~ | | | | | (24) following ‘true’ branch (when ‘ptr’ is non-NULL)... | | (26) following ‘true’ branch (when ‘ptr’ is non-NULL)... | 31 | // exact name | 32 | if (strcmp(fname, ptr->fname) == 0) { | | ~~ | | | | | (25) ...to here | | (27) ...to here |...... | 48 | if (found) | | ~ | | | | | (28) following ‘true’ branch (when ‘found != 0’)... | 49 | return ptr; | | ~~~~~~ | | | | | (29) ...to here | <------+ | ‘filedb_add’: events 30-31 | | 60 | if (filedb_find(head, fname)) | | ~^~~~~~~~~~~~~~~~~~~~~~~~ | | || | | |(30) returning to ‘filedb_add’ from ‘filedb_find’ | | (31) following ‘false’ branch... | ‘filedb_add’: event 32 | |cc1: | (32): ...to here | ‘filedb_add’: event 33 | |cc1: | (33): calling ‘filedb_add.part.0’ from ‘filedb_add’ | +--> ‘filedb_add.part.0’: events 34-35 | | 54 | FileDB *filedb_add(FileDB *head, const char *fname) { | | ^~~~~~~~~~ | | | | | (34) entry to ‘filedb_add.part.0’ |...... | 65 | if (!entry) | | ~ | | | | | (35) following ‘false’ branch (when ‘entry’ is non-NULL)... | ‘filedb_add.part.0’: event 36 | |../include/common.h:39:28: | 39 | #define errExit(msg) do { char msgout[500]; snprintf(msgout, 500, "Error %s: %s:%d %s", msg, __FILE__, __LINE__, __FUNCTION__); perror(msgout); exit(1);} while (0) | | ^ | | | | | (36) ...to here filedb.c:66:17: note: in expansion of macro ‘errExit’ | 66 | errExit("malloc"); | | ^~~~~~~ | ‘filedb_add.part.0’: events 37-39 | | 68 | entry->fname = strdup(fname); | | ^~~~~~~~~~~~~ | | | | | (37) this call could return NULL | 69 | if (!entry->fname) | | ~ | | | | | (38) assuming ‘strdup(fname)’ is non-NULL | | (39) following ‘false’ branch... | ‘filedb_add.part.0’: event 40 | |../include/common.h:39:28: | 39 | #define errExit(msg) do { char msgout[500]; snprintf(msgout, 500, "Error %s: %s:%d %s", msg, __FILE__, __LINE__, __FUNCTION__); perror(msgout); exit(1);} while (0) | | ^ | | | | | (40) ...to here filedb.c:70:17: note: in expansion of macro ‘errExit’ | 70 | errExit("strdup"); | | ^~~~~~~ | <------+ | ‘filedb_add’: event 41 | |cc1: | (41): returning to ‘filedb_add’ from ‘filedb_add.part.0’ | <------+ | ‘filedb_load_whitelist’: events 42-49 | | 105 | while (fgets(buf, MAX_BUF, fp)) { | | ~~~~~ | | | | | (43) following ‘true’ branch... | 106 | if (strncmp(buf, prefix, len) != 0) | | ~~ ~ | | | | | | | (45) following ‘false’ branch... | | (44) ...to here |...... | 109 | char *fn = buf + len; | | ~~~~ | | | | | (46) ...to here | 110 | char *ptr = strchr(buf, '\n'); | 111 | if (!ptr) | | ~ | | | | | (47) following ‘false’ branch (when ‘ptr’ is non-NULL)... | 112 | continue; | 113 | *ptr = '\0'; | | ~ | | | | | (48) ...to here |...... | 116 | head = filedb_add(head, fn); | | ^~~~~~~~~~~~~~~~~~~~ | | | | | (42) returning to ‘filedb_load_whitelist’ from ‘filedb_add’ | | (49) calling ‘filedb_add’ from ‘filedb_load_whitelist’ | +--> ‘filedb_add’: event 50 | | 54 | FileDB *filedb_add(FileDB *head, const char *fname) { | | ^~~~~~~~~~ | | | | | (50) entry to ‘filedb_add’ | ‘filedb_add’: event 51 | | 55 | assert(fname); | | ^~~~~~ | | | | | (51) following ‘true’ branch (when ‘fname’ is non-NULL)... | ‘filedb_add’: events 52-53 | | 60 | if (filedb_find(head, fname)) | | ^~ ~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | | | (53) calling ‘filedb_find’ from ‘filedb_add’ | | (52) ...to here | +--> ‘filedb_find’: event 54 | | 24 | FileDB *filedb_find(FileDB *head, const char *fname) { | | ^~~~~~~~~~~ | | | | | (54) entry to ‘filedb_find’ | ‘filedb_find’: event 55 | | 25 | assert(fname); | | ^~~~~~ | | | | | (55) following ‘true’ branch (when ‘fname’ is non-NULL)... | ‘filedb_find’: events 56-61 | | 26 | FileDB *ptr = head; | | ^~~~~~ | | | | | (56) ...to here |...... | 30 | while (ptr) { | | ~~~ | | | | | (57) following ‘true’ branch (when ‘ptr’ is non-NULL)... | 31 | // exact name | 32 | if (strcmp(fname, ptr->fname) == 0) { | | ~~ ~ | | | | | | | (59) following ‘false’ branch (when the strings are non-equal)... | | (58) ...to here |...... | 38 | if (len > ptr->len && | | ~~ | | | | | (60) ...to here |...... | 48 | if (found) | | ~ | | | | | (61) following ‘false’ branch (when ‘found == 0’)... | ‘filedb_find’: event 62 | |cc1: | (62): ...to here | <------+ | ‘filedb_add’: events 63-64 | | 60 | if (filedb_find(head, fname)) | | ~^~~~~~~~~~~~~~~~~~~~~~~~ | | || | | |(63) returning to ‘filedb_add’ from ‘filedb_find’ | | (64) following ‘false’ branch... | ‘filedb_add’: event 65 | |cc1: | (65): ...to here | ‘filedb_add’: event 66 | |cc1: | (66): calling ‘filedb_add.part.0’ from ‘filedb_add’ | +--> ‘filedb_add.part.0’: events 67-68 | | 54 | FileDB *filedb_add(FileDB *head, const char *fname) { | | ^~~~~~~~~~ | | | | | (67) entry to ‘filedb_add.part.0’ |...... | 65 | if (!entry) | | ~ | | | | | (68) following ‘false’ branch (when ‘entry’ is non-NULL)... | ‘filedb_add.part.0’: event 69 | |../include/common.h:39:28: | 39 | #define errExit(msg) do { char msgout[500]; snprintf(msgout, 500, "Error %s: %s:%d %s", msg, __FILE__, __LINE__, __FUNCTION__); perror(msgout); exit(1);} while (0) | | ^ | | | | | (69) ...to here filedb.c:66:17: note: in expansion of macro ‘errExit’ | 66 | errExit("malloc"); | | ^~~~~~~ | ‘filedb_add.part.0’: events 70-71 | | 68 | entry->fname = strdup(fname); | | ^~~~~~~~~~~~~ | | | | | (70) this call could return NULL | 69 | if (!entry->fname) | | ~ | | | | | (71) following ‘false’ branch... | ‘filedb_add.part.0’: event 72 | |../include/common.h:39:28: | 39 | #define errExit(msg) do { char msgout[500]; snprintf(msgout, 500, "Error %s: %s:%d %s", msg, __FILE__, __LINE__, __FUNCTION__); perror(msgout); exit(1);} while (0) | | ^ | | | | | (72) ...to here filedb.c:70:17: note: in expansion of macro ‘errExit’ | 70 | errExit("strdup"); | | ^~~~~~~ | ‘filedb_add.part.0’: event 73 | | 71 | entry->len = strlen(entry->fname); | | ^~~~~~~~~~~~~~~~~~~~ | | | | | (73) argument 1 (‘strdup(fname)’) from (70) could be NULL where non-null expected | In file included from ../include/common.h:31, from fbuilder.h:23, from filedb.c:21: /usr/include/string.h:391:15: note: argument 1 of ‘strlen’ must be non-null 391 | extern size_t strlen (const char *__s) | ^~~~~~ ```