Skip to content

p4c segfault in bmv2 backend found by fuzzer #5464

@cfbolz

Description

@cfbolz

Hi everyone!

The following randomly generated P4 program segfaults the bmv2 backend:

extern packet_in { }
extern packet_out { }
extern bool static_assert( bool check);
struct standard_metadata_t { }
enum HashAlgorithm { csum16 }
extern void verify_checksum<T, O>(in bool condition,  T data,  O checksum,  HashAlgorithm algo);
parser Parser<H, M>( packet_in b,  H parsedHdr,  M meta,  standard_metadata_t standard_metadata);
control VerifyChecksum<H, M>(inout H hdr,  M meta);
control Ingress<H, M>(inout H hdr,  M meta,  standard_metadata_t standard_metadata);
control Egress<H, M>(inout H hdr,  M meta,  standard_metadata_t standard_metadata);
control ComputeChecksum<H, M>(inout H hdr,  M meta);
control Deparser<H>( packet_out b,  H hdr);
package V1Switch<H, M>( Parser<H, M> p,  VerifyChecksum<H, M> vr,  Ingress<H, M> ig,  Egress<H, M> eg,  ComputeChecksum<H, M> ck,  Deparser<H> dep);
struct headers_t { }
struct metadata_t {
  bit<(1)> result;
  bit<(1)> b;
}
parser EmptyParser( packet_in b,  headers_t headers,  metadata_t meta,  standard_metadata_t standard_metadata)() {
  state start { }
}
control EmptyVerifyChecksum(inout headers_t hdr,  metadata_t meta)() {
  apply {
    verify_checksum(false, {  }, meta.result, HashAlgorithm.csum16);
  }
}
control EmptyIngress(inout headers_t headers,  metadata_t meta,  standard_metadata_t standard_metadata)() {
  apply { }
}
control EmptyEgress(inout headers_t hdr,  metadata_t meta,  standard_metadata_t standard_metadata)() {
  apply { }
}
control EmptyComputeChecksum(inout headers_t hdr,  metadata_t meta)() {
  apply { }
}
control EmptyDeparser( packet_out b,  headers_t hdr)() {
  apply { }
}
V1Switch(EmptyParser(), EmptyVerifyChecksum(), EmptyIngress(), EmptyEgress(), EmptyComputeChecksum(), EmptyDeparser()) main;

This is the behaviour I get:

p4c -o ./p4_compiler_output bug3.pretty.p4  
bug3.pretty.p4(20): [--Wwarn=parser-transition] warning: start: implicit transition to `reject'
  state start { }
        ^^^^^
bug3.pretty.p4(19): [--Wwarn=unreachable] warning: accept state in parser EmptyParser is unreachable
parser EmptyParser( packet_in b, headers_t headers, metadata_t meta, standard_metadata_t standard...
       ^^^^^^^^^^^
bug3.pretty.p4(19): [--Wwarn=unreachable] warning: accept state in parser EmptyParser is unreachable
parser EmptyParser( packet_in b, headers_t headers, metadata_t meta, standard_metadata_t standard...
       ^^^^^^^^^^^
[--Wwarn=unsupported] warning: Explicit transition to reject not supported on this target
In file: /home/cfbolz/projects/p4/p4-spectec/p4c/lib/crash.cpp:299
Compiler Bug: Exiting with SIGSEGV

Using GDB, here's the traceback at the point of the crash:

$ gdb --args /home/cfbolz/projects/p4/p4-spectec/p4c/build/p4c-bm2-ss -I /home/cfbolz/projects/p4/p4-spectec/p4c/build/p4include --p4v=16 -o './p4_compiler_output/bug3.pretty.json' './p4_compiler_output/bug3.pretty.p4i' --arch v1model
...
(gdb) run
...
(gdb) where
#0  0x0000555558160d42 in P4::IR::ID::operator P4::cstring (this=0xc0) at /home/cfbolz/projects/p4/p4-spectec/p4c/ir/id.h:63
#1  0x000055555815bc49 in P4::BMV2::SimpleSwitchBackend::convertChecksum (this=0x7ffff77a5d20, block=0x7ffff7566a80, checksums=0x7ffff76fa2d0, calculations=0x7ffff76fa450, verify=true)
    at /home/cfbolz/projects/p4/p4-spectec/p4c/backends/bmv2/simple_switch/simpleSwitch.cpp:975
#2  0x000055555815ec55 in P4::BMV2::SimpleSwitchBackend::convert (this=0x7ffff77a5d20, tlb=0x7ffff775a480) at /home/cfbolz/projects/p4/p4-spectec/p4c/backends/bmv2/simple_switch/simpleSwitch.cpp:1268
#3  0x00005555580f2b55 in main (argc=9, argv=0x7fffffffda18) at /home/cfbolz/projects/p4/p4-spectec/p4c/backends/bmv2/simple_switch/main.cpp:121

(the P4::IR::ID instance has a nonsensical this pointer at this point.)

I'm sure this program is nonsensical, but I would have expected a clear error message by the compiler.

Background: My student @hehin101 (collaborating with @jaehyun1ee) have been fuzzing P4-SpecTec and P4C. We are finding a number of segfaults in P4C. Is there interest in me filing them as (minimized) crashing tests here? We found <10 so far and are deduplicating them by looking at the C++ tracebacks. I don't want to spam your issue tracker in an annoying way, so please let me know whether the project has a preference for whether and if yes how we should report these.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bmv2Topics related to BMv2 or v1model

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions