github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/pkg/report/gvisor.go (about)

     1  // Copyright 2018 syzkaller project authors. All rights reserved.
     2  // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
     3  
     4  package report
     5  
     6  import (
     7  	"bytes"
     8  	"regexp"
     9  
    10  	"github.com/google/syzkaller/pkg/report/crash"
    11  )
    12  
    13  type gvisor struct {
    14  	*config
    15  }
    16  
    17  func ctorGvisor(cfg *config) (reporterImpl, []string, error) {
    18  	ctx := &gvisor{
    19  		config: cfg,
    20  	}
    21  	suppressions := []string{
    22  		"panic: ptrace sysemu failed: no such process",                                          // OOM kill
    23  		`panic: ptrace (s|g)et fpregs.* failed: no such process`,                                // OOM kill
    24  		`panic: ptrace (s|g)et regs.* failed: no such process`,                                  // OOM kill
    25  		"panic: error initializing first thread: resource temporarily unavailable",              // PID exhaustion
    26  		"panic: unable to activate mm: creating stub process: resource temporarily unavailable", // PID exhaustion
    27  		"panic: executor failed: pthread_create failed",                                         // PID exhaustion
    28  		"panic: failed to start executor binary",
    29  		"panic: error mapping run data: error mapping runData: cannot allocate memory",
    30  		"race: limit on 8128 simultaneously alive goroutines is exceeded, dying",
    31  		"ERROR: ThreadSanitizer", // Go race failing due to OOM.
    32  		"FATAL: ThreadSanitizer",
    33  		"ThreadSanitizer: clock allocator overflow \\(65536\\*1024\\). Dying.",
    34  	}
    35  	return ctx, suppressions, nil
    36  }
    37  
    38  func (ctx *gvisor) ContainsCrash(output []byte) bool {
    39  	return containsCrash(output, gvisorOopses, ctx.ignores)
    40  }
    41  
    42  func (ctx *gvisor) Parse(output []byte) *Report {
    43  	rep := simpleLineParser(output, gvisorOopses, nil, ctx.ignores)
    44  	if rep == nil {
    45  		return nil
    46  	}
    47  	rep.Title = replaceTable(gvisorTitleReplacement, rep.Title)
    48  	rep.Report = ctx.shortenReport(rep.Report)
    49  	return rep
    50  }
    51  
    52  func (ctx *gvisor) shortenReport(report []byte) []byte {
    53  	// gvisor panics include stacks of all goroutines.
    54  	// This output is too lengthy for report and not very useful.
    55  	// So we always take 5 lines from report and then cut it at the next empty line.
    56  	// The intention is to capture panic header and traceback of the first goroutine.
    57  	pos := 0
    58  	for i := 0; i < 5; i++ {
    59  		pos1 := bytes.IndexByte(report[pos:], '\n')
    60  		if pos1 == -1 {
    61  			return report
    62  		}
    63  		pos += pos1 + 1
    64  	}
    65  	end := bytes.Index(report[pos:], []byte{'\n', '\n'})
    66  	if end == -1 {
    67  		return report
    68  	}
    69  	if bytes.Contains(report, []byte("WARNING: DATA RACE")) {
    70  		// For data races extract both stacks.
    71  		end2 := bytes.Index(report[pos+end+2:], []byte{'\n', '\n'})
    72  		if end2 != -1 {
    73  			end += end2 + 2
    74  		}
    75  	}
    76  	return report[:pos+end+1]
    77  }
    78  
    79  func (ctx *gvisor) Symbolize(rep *Report) error {
    80  	return nil
    81  }
    82  
    83  var gvisorTitleReplacement = []replacement{
    84  	{
    85  		regexp.MustCompile(`container ".*"`),
    86  		"container NAME",
    87  	},
    88  	{
    89  		regexp.MustCompile(`sandbox ".*"`),
    90  		"sandbox NAME",
    91  	},
    92  	{
    93  		regexp.MustCompile(`(pid|PID) [0-9]+`),
    94  		"pid X",
    95  	},
    96  }
    97  
    98  var gvisorOopses = append([]*oops{
    99  	{
   100  		[]byte("Panic:"),
   101  		[]oopsFormat{
   102  			{
   103  				title:        compile("Panic:(.*)"),
   104  				fmt:          "Panic:%[1]v",
   105  				noStackTrace: true,
   106  			},
   107  		},
   108  		[]*regexp.Regexp{},
   109  		crash.UnknownType,
   110  	},
   111  	{
   112  		[]byte("SIGSEGV:"),
   113  		[]oopsFormat{
   114  			{
   115  				title:        compile("SIGSEGV:(.*)"),
   116  				fmt:          "SIGSEGV:%[1]v",
   117  				noStackTrace: true,
   118  			},
   119  		},
   120  		[]*regexp.Regexp{},
   121  		crash.UnknownType,
   122  	},
   123  	{
   124  		[]byte("SIGBUS:"),
   125  		[]oopsFormat{
   126  			{
   127  				title:        compile("SIGBUS:(.*)"),
   128  				fmt:          "SIGBUS:%[1]v",
   129  				noStackTrace: true,
   130  			},
   131  		},
   132  		[]*regexp.Regexp{},
   133  		crash.UnknownType,
   134  	},
   135  	{
   136  		[]byte("FATAL ERROR:"),
   137  		[]oopsFormat{
   138  			{
   139  				title:        compile("FATAL ERROR:(.*)"),
   140  				fmt:          "FATAL ERROR:%[1]v",
   141  				noStackTrace: true,
   142  			},
   143  		},
   144  		[]*regexp.Regexp{},
   145  		crash.UnknownType,
   146  	},
   147  	{
   148  		[]byte("WARNING: DATA RACE"),
   149  		[]oopsFormat{
   150  			{
   151  				title:        compile("WARNING: DATA RACE"),
   152  				report:       compile("WARNING: DATA RACE\n(?:.*\n)*?  (?:[a-zA-Z0-9./_-]+/)([a-zA-Z0-9.()*_]+)\\(\\)\n"),
   153  				fmt:          "DATA RACE in %[1]v",
   154  				noStackTrace: true,
   155  			},
   156  		},
   157  		[]*regexp.Regexp{},
   158  		crash.UnknownType,
   159  	},
   160  	{
   161  		[]byte("Invalid request partialResult"),
   162  		[]oopsFormat{
   163  			{
   164  				title:        compile("Invalid request partialResult"),
   165  				report:       compile("Invalid request partialResult .* for (.*) operation"),
   166  				fmt:          "Invalid request partialResult in %[1]v",
   167  				noStackTrace: true,
   168  			},
   169  		},
   170  		[]*regexp.Regexp{},
   171  		crash.UnknownType,
   172  	},
   173  	{
   174  		[]byte("fatal error:"),
   175  		[]oopsFormat{
   176  			{
   177  				title:        compile("fatal error:(.*)"),
   178  				fmt:          "fatal error:%[1]v",
   179  				noStackTrace: true,
   180  			},
   181  		},
   182  		[]*regexp.Regexp{},
   183  		crash.UnknownType,
   184  	},
   185  }, commonOopses...)