Skip to content

lilv_state_new_from_file: avoid segfault when path does not exist

Théo Lebrun requested to merge tleb0/lilv:fix-state-from-file-segfault into master

Concretely:

⟩ file foo/
foo/: directory

⟩ # before:
⟩ jalv -l foo/ http://open-music-kontrollers.ch/lv2/moony#a2xa2
fish: Job 1, 'jalv -l foo/ http://ope…' terminated by signal SIGSEGV (Address boundary error)

⟩ # after:
⟩ LD_PRELOAD=../lilv/build/liblilv-0.so jalv -l foo/ http://open-music-kontrollers.ch/lv2/moony#a2xa2
lilv_state_new_from_file(): error: Path `foo//state.ttl' cannot be made canonical.
error: Failed to load state from foo/

The call trace leading to the segfault is something like:

  • jalv_open calls lilv_state_new_from_file if the load argument is given. It passes load + "/state.ttl" if load is a directory, else it passes load directly.
  • The first thing lilv_state_new_from_file does is call zix_canonical_path on the path (looking at the POSIX codepath only, not Windows).
    • This calls realpath(path, buffer) which returns NULL if the operation failed or if zix_calloc fails.
    • zix_canonical_path is therefore returning NULL.
  • We call serd_node_new_file_uri with the previous result. The first thing this does is call strlen on its argument, meaning we segfault.

I've therefore added a check in LILV to avoid calling serd_node_new_file_uri with a NULL pointer.

Edited by Théo Lebrun

Merge request reports