Skip to content

Commit 1a481a6

Browse files
committed
tools/syz-aflow: support downloading bugs behind an AppEngine login
Some syzbot dashboard pages are guarded by an AppEngine login page. The -download flag helps generate an input.json out of a bug report but it currently uses simple HTTP GET commands without any authentication. When called on a bug behind a login page, it received a login page HTML instead of a json payload and fails in confusing ways. The authentication page can be skipped using an authentication token. It's easy to retrieve a token from the gcloud auth print-access-token command.
1 parent ebb1853 commit 1a481a6

File tree

1 file changed

+45
-8
lines changed

1 file changed

+45
-8
lines changed

tools/syz-aflow/aflow.go

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ import (
2424
"github.com/google/syzkaller/pkg/aflow/trajectory"
2525
"github.com/google/syzkaller/pkg/osutil"
2626
"github.com/google/syzkaller/pkg/tool"
27+
28+
"golang.org/x/oauth2/google"
2729
)
2830

2931
func main() {
@@ -35,10 +37,20 @@ func main() {
3537
flagCacheSize = flag.String("cache-size", "10GB", "max cache size (e.g. 100MB, 5GB, 1TB)")
3638
flagDownloadBug = flag.String("download-bug", "", "extid of a bug to download from the dashboard"+
3739
" and save into -input file")
40+
flagAuth = flag.Bool("auth", false, "use gcloud auth token for downloading bugs (set it up with"+
41+
" gcloud auth application-default login)")
3842
)
3943
defer tool.Init()()
4044
if *flagDownloadBug != "" {
41-
if err := downloadBug(*flagDownloadBug, *flagInput); err != nil {
45+
token := ""
46+
if *flagAuth {
47+
var err error
48+
token, err = getAccessToken()
49+
if err != nil {
50+
tool.Fail(err)
51+
}
52+
}
53+
if err := downloadBug(*flagDownloadBug, *flagInput, token); err != nil {
4254
tool.Fail(err)
4355
}
4456
return
@@ -109,11 +121,11 @@ func onEvent(span *trajectory.Span) error {
109121
return nil
110122
}
111123

112-
func downloadBug(extID, inputFile string) error {
124+
func downloadBug(extID, inputFile, token string) error {
113125
if inputFile == "" {
114126
return fmt.Errorf("-download-bug requires -input flag")
115127
}
116-
resp, err := get(fmt.Sprintf("/bug?extid=%v&json=1", extID))
128+
resp, err := get(fmt.Sprintf("/bug?extid=%v&json=1", extID), token)
117129
if err != nil {
118130
return err
119131
}
@@ -125,15 +137,15 @@ func downloadBug(extID, inputFile string) error {
125137
inputs := map[string]any{
126138
"SyzkallerCommit": crash["syzkaller-commit"],
127139
}
128-
inputs["ReproSyz"], err = get(crash["syz-reproducer"].(string))
140+
inputs["ReproSyz"], err = get(crash["syz-reproducer"].(string), token)
129141
if err != nil {
130142
return err
131143
}
132-
inputs["ReproC"], err = get(crash["c-reproducer"].(string))
144+
inputs["ReproC"], err = get(crash["c-reproducer"].(string), token)
133145
if err != nil {
134146
return err
135147
}
136-
inputs["KernelConfig"], err = get(crash["kernel-config"].(string))
148+
inputs["KernelConfig"], err = get(crash["kernel-config"].(string), token)
137149
if err != nil {
138150
return err
139151
}
@@ -144,16 +156,41 @@ func downloadBug(extID, inputFile string) error {
144156
return osutil.WriteFile(inputFile, data)
145157
}
146158

147-
func get(path string) (string, error) {
159+
func get(path, token string) (string, error) {
148160
if path == "" {
149161
return "", nil
150162
}
151163
const host = "https://syzbot.org"
152-
resp, err := http.Get(fmt.Sprintf("%v%v", host, path))
164+
req, err := http.NewRequest("GET", fmt.Sprintf("%v%v", host, path), nil)
165+
if err != nil {
166+
return "", err
167+
}
168+
if token != "" {
169+
req.Header.Add("Authorization", "Bearer "+token)
170+
}
171+
resp, err := http.DefaultClient.Do(req)
153172
if err != nil {
154173
return "", err
155174
}
156175
defer resp.Body.Close()
176+
if resp.StatusCode != http.StatusOK {
177+
return "", fmt.Errorf("request failed: %v", resp.Status)
178+
}
157179
body, err := io.ReadAll(resp.Body)
158180
return string(body), err
159181
}
182+
183+
func getAccessToken() (string, error) {
184+
ctx := context.Background()
185+
scopes := []string{"https://www.googleapis.com/auth/cloud-platform"}
186+
creds, err := google.FindDefaultCredentials(ctx, scopes...)
187+
if err != nil {
188+
return "", err
189+
}
190+
token, err := creds.TokenSource.Token()
191+
if err != nil {
192+
return "", fmt.Errorf("error retrieving token from source: %w", err)
193+
}
194+
195+
return token.AccessToken, nil
196+
}

0 commit comments

Comments
 (0)