@@ -42,11 +42,55 @@ type reproduceResult struct {
4242 CrashReport string
4343}
4444
45- func reproduce (ctx * aflow.Context , args reproduceArgs ) (reproduceResult , error ) {
46- if args .Type != "qemu" {
47- // Since we use injected kernel boot, and don't build full disk image.
48- return reproduceResult {}, errors .New ("only qemu VM type is supported" )
45+ func ReproduceCrash (syzkaller , kernelObj , kernelSrc , image , vmType , reproC , workdir string , vm []byte ) (string , string , error ) {
46+ if vmType != "qemu" {
47+ return "" , "" , errors .New ("only qemu VM type is supported" )
48+ }
49+
50+ var vmConfig map [string ]any
51+ if err := json .Unmarshal (vm , & vmConfig ); err != nil {
52+ return "" , "" , fmt .Errorf ("failed to parse VM config: %w" , err )
53+ }
54+ vmConfig ["kernel" ] = filepath .Join (kernelObj , filepath .FromSlash (build .LinuxKernelImage (targets .AMD64 )))
55+ vmCfg , err := json .Marshal (vmConfig )
56+ if err != nil {
57+ return "" , "" , fmt .Errorf ("failed to serialize VM config: %w" , err )
58+ }
59+
60+ cfg := mgrconfig .DefaultValues ()
61+ cfg .RawTarget = "linux/amd64"
62+ cfg .Workdir = workdir
63+ cfg .Syzkaller = syzkaller
64+ cfg .KernelObj = kernelObj
65+ cfg .KernelSrc = kernelSrc
66+ cfg .Image = image
67+ cfg .Type = vmType
68+ cfg .VM = vmCfg
69+ if err := mgrconfig .SetTargets (cfg ); err != nil {
70+ return "" , "" , err
71+ }
72+ if err := mgrconfig .Complete (cfg ); err != nil {
73+ return "" , "" , err
4974 }
75+ env , err := instance .NewEnv (cfg , nil , nil )
76+ if err != nil {
77+ return "" , "" , err
78+ }
79+ results , err := env .Test (1 , nil , nil , []byte (reproC ))
80+ if err != nil {
81+ return "" , "" , err
82+ }
83+ if results [0 ].Error != nil {
84+ if crashErr := new (instance.CrashError ); errors .As (results [0 ].Error , & crashErr ) {
85+ return string (crashErr .Report .Report ), "" , nil
86+ } else {
87+ return "" , results [0 ].Error .Error (), nil
88+ }
89+ }
90+ return "" , "" , nil
91+ }
92+
93+ func reproduce (ctx * aflow.Context , args reproduceArgs ) (reproduceResult , error ) {
5094 imageData , err := os .ReadFile (args .Image )
5195 if err != nil {
5296 return reproduceResult {}, err
@@ -61,50 +105,12 @@ func reproduce(ctx *aflow.Context, args reproduceArgs) (reproduceResult, error)
61105 }
62106 cached , err := aflow .CacheObject (ctx , "repro" , desc , func () (Cached , error ) {
63107 var res Cached
64- var vmConfig map [string ]any
65- if err := json .Unmarshal (args .VM , & vmConfig ); err != nil {
66- return res , fmt .Errorf ("failed to parse VM config: %w" , err )
67- }
68- vmConfig ["kernel" ] = filepath .Join (args .KernelObj , filepath .FromSlash (build .LinuxKernelImage (targets .AMD64 )))
69- vmCfg , err := json .Marshal (vmConfig )
70- if err != nil {
71- return res , fmt .Errorf ("failed to serialize VM config: %w" , err )
72- }
73108 workdir , err := ctx .TempDir ()
74109 if err != nil {
75110 return res , err
76111 }
77- cfg := mgrconfig .DefaultValues ()
78- cfg .RawTarget = "linux/amd64"
79- cfg .Workdir = workdir
80- cfg .Syzkaller = args .Syzkaller
81- cfg .KernelObj = args .KernelObj
82- cfg .KernelSrc = args .KernelSrc
83- cfg .Image = args .Image
84- cfg .Type = args .Type
85- cfg .VM = vmCfg
86- if err := mgrconfig .SetTargets (cfg ); err != nil {
87- return res , err
88- }
89- if err := mgrconfig .Complete (cfg ); err != nil {
90- return res , err
91- }
92- env , err := instance .NewEnv (cfg , nil , nil )
93- if err != nil {
94- return res , err
95- }
96- results , err := env .Test (1 , nil , nil , []byte (args .ReproC ))
97- if err != nil {
98- return res , err
99- }
100- if results [0 ].Error != nil {
101- if crashErr := new (instance.CrashError ); errors .As (results [0 ].Error , & crashErr ) {
102- res .Report = string (crashErr .Report .Report )
103- } else {
104- res .Error = results [0 ].Error .Error ()
105- }
106- }
107- return res , nil
112+ res .Error , res .Report , err = ReproduceCrash (args .Syzkaller , args .KernelObj , args .KernelSrc , args .Image , args .Type , args .ReproC , workdir , args .VM )
113+ return res , err
108114 })
109115 if err != nil {
110116 return reproduceResult {}, err
0 commit comments