Skip to content

segmentation fault with complex if-feature expression #887

@rjarry

Description

@rjarry

I noticed that some (not all) complex if-feature expressions can cause a segfault when dumping a module to the LYS_OUT_TREE format.

Here is a minimalist test program to reproduce the issue:

/* iff-test.c */
#include <stdlib.h>
#include <string.h>
#include <libyang/libyang.h>

static char *yang =
  "module test {"
  "  yang-version 1.1;"
  "  namespace 'urn:yang:test';"
  "  prefix tst;"
  "  feature a;"
  "  feature b;"
  "  grouping tree {"
  "    leaf hostname {"
  "      type string;"
  "    }"
  "    list url {"
  "      key 'proto host';"
  "      leaf proto {"
  "        type string;"
  "      }"
  "      leaf host {"
  "        type string;"
  "      }"
  "      leaf port {"
  "        type uint16;"
  "      }"
  "      leaf path {"
  "        type string;"
  "      }"
  "    }"
  "    leaf-list number {"
  "      type uint16;"
  "    }"
  "    leaf speed {"
  "      if-feature a;"
  "      type uint32;"
  "    }"
  "    leaf isolation-level {"
  "      if-feature 'a and not (b or a) or not (a or not b)';"
  "      type uint32;"
  "    }"
  "  }"
  "  container conf {"
  "    uses tree;"
  "  }"
  "  container state {"
  "    config false;"
  "    uses tree;"
  "  }"
  "}";

int main(int argc, char **argv)
{
        struct ly_ctx *ctx;
        const struct lys_module *module;

        ctx = ly_ctx_new(NULL, 0);
        module = lys_parse_mem(ctx, yang, LYS_IN_YANG);
        lys_features_enable(module, "*");

        lys_print_file(stdout, module, LYS_OUT_TREE, NULL, 0, 0);

        return 0;
}

When building and running, we get a segfault:

~$ gcc iff-test.c -o iff-test -lyang
~$ ./iff-test
module: test
  +--rw conf
  |  +--rw hostname?          string
  |  +--rw url* [proto host]
  |  |  +--rw proto    string
  |  |  +--rw host     string
  |  |  +--rw port?    uint16
  |  |  +--rw path?    string
  |  +--rw number*            uint16
Segmentation fault (core dumped)

Inspecting the core dump reveals that there seems to be an infinite recursion:

(gdb) backtrace
#0  0x00007f96e372624b in resolve_feature_value (feat=0x71) at /root/libyang/src/resolve.c:1361
#1  0x00007f96e37262f2 in resolve_iffeature_recursive (expr=0x565144162350, index_e=0x7ffffa8a12f0, 
    index_f=0x7ffffa8a12f4) at /root/libyang/src/resolve.c:1382
#2  0x00007f96e372632f in resolve_iffeature_recursive (expr=0x565144162350, index_e=0x7ffffa8a12f0, 
    index_f=0x7ffffa8a12f4) at /root/libyang/src/resolve.c:1388
#3  0x00007f96e372632f in resolve_iffeature_recursive (expr=0x565144162350, index_e=0x7ffffa8a12f0, 
    index_f=0x7ffffa8a12f4) at /root/libyang/src/resolve.c:1388
#4  0x00007f96e372630e in resolve_iffeature_recursive (expr=0x565144162350, index_e=0x7ffffa8a12f0, 
    index_f=0x7ffffa8a12f4) at /root/libyang/src/resolve.c:1385
#5  0x00007f96e372630e in resolve_iffeature_recursive (expr=0x565144162350, index_e=0x7ffffa8a12f0, 
    index_f=0x7ffffa8a12f4) at /root/libyang/src/resolve.c:1385
#6  0x00007f96e372630e in resolve_iffeature_recursive (expr=0x565144162350, index_e=0x7ffffa8a12f0, 
    index_f=0x7ffffa8a12f4) at /root/libyang/src/resolve.c:1385
.... truncated ....
#122 0x00007f96e372632f in resolve_iffeature_recursive (expr=0x565144162350, index_e=0x7ffffa8a12f0, 
    index_f=0x7ffffa8a12f4) at /root/libyang/src/resolve.c:1388
#123 0x00007f96e372632f in resolve_iffeature_recursive (expr=0x565144162350, index_e=0x7ffffa8a12f0, 
    index_f=0x7ffffa8a12f4) at /root/libyang/src/resolve.c:1388
#124 0x00007f96e3726349 in resolve_iffeature_recursive (expr=0x565144162350, index_e=0x7ffffa8a12f0, 
    index_f=0x7ffffa8a12f4) at /root/libyang/src/resolve.c:1389
#125 0x00007f96e37263e9 in resolve_iffeature (expr=0x565144162350) at /root/libyang/src/resolve.c:1406
#126 0x00007f96e37a7f7d in lys_is_disabled (node=0x56514417f560, recursive=0) at /root/libyang/src/tree_schema.c:93
#127 0x00007f96e3807ea7 in tree_sibling_is_valid_child (node=0x56514417f480, including=0, module=0x56514417dd20, 
    aug_parent=0x0, nodetype=LYS_LEAF) at /root/libyang/src/printer_tree.c:99
#128 0x00007f96e38081c7 in tree_next_indent (level=2, node=0x56514417f480, aug_parent=0x0, opts=0x7ffffa8a15c0)
    at /root/libyang/src/printer_tree.c:173
#129 0x00007f96e380948e in tree_print_snode (out=0x7ffffa8a1680, level=2, max_name_len=16, node=0x56514417f480, 
---Type <return> to continue, or q <return> to quit---
    mask=53439, aug_parent=0x0, subtree=0, opts=0x7ffffa8a15c0) at /root/libyang/src/printer_tree.c:597
#130 0x00007f96e3809c89 in tree_print_snode (out=0x7ffffa8a1680, level=1, max_name_len=16, node=0x56514417ec50, 
    mask=53439, aug_parent=0x0, subtree=0, opts=0x7ffffa8a15c0) at /root/libyang/src/printer_tree.c:765
#131 0x00007f96e3809c89 in tree_print_snode (out=0x7ffffa8a1680, level=1, max_name_len=6, node=0x56514417eb90, 
    mask=36927, aug_parent=0x0, subtree=0, opts=0x7ffffa8a15c0) at /root/libyang/src/printer_tree.c:765
#132 0x00007f96e380a387 in tree_print_model (out=0x7ffffa8a1680, module=0x56514417dd20, target_schema_path=0x0, ll=0, 
    options=0) at /root/libyang/src/printer_tree.c:945
#133 0x00007f96e37cf412 in lys_print_ (out=0x7ffffa8a1680, module=0x56514417dd20, format=LYS_OUT_TREE, target_node=0x0, 
    line_length=0, options=0) at /root/libyang/src/printer.c:370
#134 0x00007f96e37cf534 in lys_print_file (f=0x7f96e3709760 <_IO_2_1_stdout_>, module=0x56514417dd20, 
    format=LYS_OUT_TREE, target_node=0x0, line_length=0, options=0) at /root/libyang/src/printer.c:403
#135 0x00005651431848e7 in main ()

Maybe a problem with the parsing of the expression.

I am aware that the if-feature expression I used does not make any sense. However, this should not make libyang crash.

Metadata

Metadata

Assignees

Labels

is:bugBug description.status:completedFrom the developer perspective, the issue was solved (bug fixed, question answered,...)

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions