github.com/google/syzkaller@v0.0.0-20251211124644-a066d2bc4b02/pkg/repro/strace.go (about)

     1  // Copyright 2022 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 repro
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  
    10  	"github.com/google/syzkaller/pkg/instance"
    11  	"github.com/google/syzkaller/pkg/log"
    12  	"github.com/google/syzkaller/pkg/mgrconfig"
    13  	"github.com/google/syzkaller/pkg/report"
    14  	"github.com/google/syzkaller/vm"
    15  	"github.com/google/syzkaller/vm/dispatcher"
    16  )
    17  
    18  type StraceResult struct {
    19  	Report *report.Report
    20  	Output []byte
    21  	Error  error
    22  }
    23  
    24  const (
    25  	straceOutputLogSize = 2048 << 10
    26  )
    27  
    28  func RunStrace(result *Result, cfg *mgrconfig.Config, reporter *report.Reporter, pool *vm.Dispatcher) *StraceResult {
    29  	if cfg.StraceBin == "" {
    30  		return straceFailed(fmt.Errorf("strace binary is not set in the config"))
    31  	}
    32  	var runRes *instance.RunResult
    33  	var err error
    34  	runErr := pool.Run(context.Background(), func(ctx context.Context, inst *vm.Instance, updInfo dispatcher.UpdateInfo) {
    35  		updInfo(func(info *dispatcher.Info) {
    36  			info.Status = "running strace"
    37  		})
    38  		ret, setupErr := instance.SetupExecProg(inst, cfg, reporter,
    39  			&instance.OptionalConfig{
    40  				StraceBin:        cfg.StraceBin,
    41  				BeforeContextLen: straceOutputLogSize,
    42  			})
    43  		if setupErr != nil {
    44  			err = fmt.Errorf("failed to set up instance: %w", setupErr)
    45  			return
    46  		}
    47  		params := instance.ExecParams{
    48  			Opts:     result.Opts,
    49  			Duration: result.Duration,
    50  		}
    51  		if result.CRepro {
    52  			log.Logf(1, "running C repro under strace")
    53  			params.CProg = result.Prog
    54  			runRes, err = ret.RunCProg(params)
    55  		} else {
    56  			log.Logf(1, "running syz repro under strace")
    57  			params.SyzProg = result.Prog.Serialize()
    58  			runRes, err = ret.RunSyzProg(params)
    59  		}
    60  	})
    61  	if runErr != nil {
    62  		return straceFailed(runErr)
    63  	} else if err != nil {
    64  		return straceFailed(err)
    65  	}
    66  	return &StraceResult{
    67  		Report: runRes.Report,
    68  		Output: runRes.Output,
    69  	}
    70  }
    71  
    72  func straceFailed(err error) *StraceResult {
    73  	return &StraceResult{Error: err}
    74  }
    75  
    76  func (strace *StraceResult) IsSameBug(repro *Result) bool {
    77  	if strace == nil || strace.Report == nil || repro.Report == nil {
    78  		return false
    79  	}
    80  	return strace.Report.Title == repro.Report.Title
    81  }