...
 
Commits (6)
    https://gitcode.net/pureGavin/syzkaller/-/commit/d521bc5692c2ea3fa25a1a2ae3190b18c0dfc181 dashboard/app: export discussion link, jsonAPI 2023-06-19T14:00:42+02:00 Taras Madan tarasmadan@google.com https://gitcode.net/pureGavin/syzkaller/-/commit/f1f9726ad56cc48e47cc0fdef249052883d7d7ee dashboard/app: prepare json generation code for extension 2023-06-19T16:42:56+02:00 Taras Madan tarasmadan@google.com https://gitcode.net/pureGavin/syzkaller/-/commit/4b9f2f7e29d6f5c2e47ee1de4cd5d8f5c4e1d7e4 dashboard/app: add bugGroup json reporting 2023-06-19T16:42:56+02:00 Taras Madan tarasmadan@google.com https://gitcode.net/pureGavin/syzkaller/-/commit/09ffe269727719aad37ea8145eb57fefb0097165 dashboard/app: test bugGroup json reporting 2023-06-19T16:42:56+02:00 Taras Madan tarasmadan@google.com https://gitcode.net/pureGavin/syzkaller/-/commit/0cf1feea4ed6ec2e962a5116275c5de83e09b728 dashboard/app: export fix-commits as a json 2023-06-20T15:04:32+02:00 Taras Madan tarasmadan@google.com https://gitcode.net/pureGavin/syzkaller/-/commit/79782afcff30fd0c0af8c2725d508b2c7150f3ed executor: include missing linux/falloc.h 2023-06-20T19:10:08+02:00 Khem Raj raj.khem@gmail.com Its needed for FALLOC_FL_ZERO_RANGE which needs this header, it works with glibc because fcntl.h includes this header indirectly, however the failure comes to fore with musl C library where this header is not included indirectly by other system headers, therefore include it as required. Fixes In file included from executor/common.h:505: executor/common_linux.h:5604:16: error: use of undeclared identifier 'FALLOC_FL_ZERO_RANGE' fallocate(fd, FALLOC_FL_ZERO_RANGE, 0, SWAP_FILE_SIZE); ^
...@@ -6,6 +6,8 @@ package main ...@@ -6,6 +6,8 @@ package main
import ( import (
"fmt" "fmt"
"testing" "testing"
"github.com/google/syzkaller/dashboard/dashapi"
) )
func TestJSONAPIIntegration(t *testing.T) { func TestJSONAPIIntegration(t *testing.T) {
...@@ -39,6 +41,25 @@ func TestJSONAPIIntegration(t *testing.T) { ...@@ -39,6 +41,25 @@ func TestJSONAPIIntegration(t *testing.T) {
}`, }`,
) )
sampleOpenBugGroupDescr := []byte(`{
"version": 1,
"Bugs": [
{
"title": "title1",
"link": "/bug?extid=decf42d66dced481afc1"
},
{
"title": "title2",
"link": "/bug?extid=0267d1c87b9ed4eb5def"
}
]
}`)
sampleFixedBugGroupDescr := []byte(`{
"version": 1,
"Bugs": null
}`)
c := NewCtx(t) c := NewCtx(t)
defer c.Close() defer c.Close()
...@@ -56,6 +77,9 @@ func TestJSONAPIIntegration(t *testing.T) { ...@@ -56,6 +77,9 @@ func TestJSONAPIIntegration(t *testing.T) {
c.client.ReportCrash(crash2) c.client.ReportCrash(crash2)
bugReport2 := c.client.pollBug() bugReport2 := c.client.pollBug()
checkBugPageJSONIs(c, bugReport2.ID, sampleCrashWithReproDescr) checkBugPageJSONIs(c, bugReport2.ID, sampleCrashWithReproDescr)
checkBugGroupPageJSONIs(c, "/test1?json=1", sampleOpenBugGroupDescr)
checkBugGroupPageJSONIs(c, "/test1/fixed?json=1", sampleFixedBugGroupDescr)
} }
func checkBugPageJSONIs(c *Ctx, ID string, expectedContent []byte) { func checkBugPageJSONIs(c *Ctx, ID string, expectedContent []byte) {
...@@ -67,3 +91,59 @@ func checkBugPageJSONIs(c *Ctx, ID string, expectedContent []byte) { ...@@ -67,3 +91,59 @@ func checkBugPageJSONIs(c *Ctx, ID string, expectedContent []byte) {
actualContent, _ := c.client.GET(url) actualContent, _ := c.client.GET(url)
c.expectEQ(string(actualContent), string(expectedContent)) c.expectEQ(string(actualContent), string(expectedContent))
} }
func checkBugGroupPageJSONIs(c *Ctx, url string, expectedContent []byte) {
contentType, _ := c.client.ContentType(url)
c.expectEQ(contentType, "application/json")
actualContent, _ := c.client.GET(url)
c.expectEQ(string(actualContent), string(expectedContent))
}
func TestJSONAPIFixCommits(t *testing.T) {
c := NewCtx(t)
defer c.Close()
build1 := testBuild(1)
c.client.UploadBuild(build1)
crash1 := testCrash(build1, 1)
c.client.ReportCrash(crash1)
rep1 := c.client.pollBug()
// Specify fixing commit for the bug.
c.client.ReportingUpdate(&dashapi.BugUpdate{
ID: rep1.ID,
Status: dashapi.BugStatusOpen,
FixCommits: []string{"foo: fix1", "foo: fix2"},
})
c.client.UploadCommits([]dashapi.Commit{
{Hash: "hash1", Title: "foo: fix1"},
})
c.client.CommitPoll()
want := []byte(`{
"version": 1,
"title": "title1",
"fix-commits": [
{
"title": "foo: fix1",
"hash": "hash1"
},
{
"title": "foo: fix2"
}
],
"crashes": [
{
"kernel-config": "/text?tag=KernelConfig\u0026x=a989f27ebc47e2dc",
"kernel-source-commit": "1111111111111111111111111111111111111111",
"syzkaller-git": "https://github.com/google/syzkaller/commits/syzkaller_commit1",
"syzkaller-commit": "syzkaller_commit1"
}
]
}`)
checkBugGroupPageJSONIs(c, "/bug?extid=decf42d66dced481afc1&json=1", want)
}
...@@ -5,7 +5,6 @@ package main ...@@ -5,7 +5,6 @@ package main
import ( import (
"bytes" "bytes"
"encoding/json"
"fmt" "fmt"
"html/template" "html/template"
"net/http" "net/http"
...@@ -463,6 +462,12 @@ func handleMain(c context.Context, w http.ResponseWriter, r *http.Request) error ...@@ -463,6 +462,12 @@ func handleMain(c context.Context, w http.ResponseWriter, r *http.Request) error
Managers: makeManagerList(managers, hdr.Namespace), Managers: makeManagerList(managers, hdr.Namespace),
BugFilter: makeUIBugFilter(c, filter), BugFilter: makeUIBugFilter(c, filter),
} }
if isJSONRequested(r) {
w.Header().Set("Content-Type", "application/json")
return writeJSONVersionOf(w, data)
}
return serveTemplate(w, "main.html", data) return serveTemplate(w, "main.html", data)
} }
...@@ -598,6 +603,12 @@ func handleTerminalBugList(c context.Context, w http.ResponseWriter, r *http.Req ...@@ -598,6 +603,12 @@ func handleTerminalBugList(c context.Context, w http.ResponseWriter, r *http.Req
Stats: stats, Stats: stats,
BugFilter: makeUIBugFilter(c, typ.Filter), BugFilter: makeUIBugFilter(c, typ.Filter),
} }
if isJSONRequested(r) {
w.Header().Set("Content-Type", "application/json")
return writeJSONVersionOf(w, data)
}
return serveTemplate(w, "terminal.html", data) return serveTemplate(w, "terminal.html", data)
} }
...@@ -1024,11 +1035,8 @@ func isJSONRequested(request *http.Request) bool { ...@@ -1024,11 +1035,8 @@ func isJSONRequested(request *http.Request) bool {
return request.FormValue("json") == "1" return request.FormValue("json") == "1"
} }
func writeJSONVersionOf(writer http.ResponseWriter, bugPage *uiBugPage) error { func writeJSONVersionOf(writer http.ResponseWriter, page interface{}) error {
data, err := json.MarshalIndent( data, err := GetJSONDescrFor(page)
GetExtAPIDescrForBugPage(bugPage),
"",
"\t")
if err != nil { if err != nil {
return err return err
} }
......
...@@ -3,15 +3,26 @@ ...@@ -3,15 +3,26 @@
package main package main
import "encoding/json"
// publicApiBugDescription is used to serve the /bug HTTP requests // publicApiBugDescription is used to serve the /bug HTTP requests
// and provide JSON description of the BUG. Backward compatible. // and provide JSON description of the BUG. Backward compatible.
type PublicAPIBugDescription struct { type publicAPIBugDescription struct {
Version int `json:"version"` Version int `json:"version"`
Title string `json:"title,omitempty"` Title string `json:"title,omitempty"`
Crashes []PublicAPICrashDescription `json:"crashes,omitempty"` FixCommits []fixCommit `json:"fix-commits,omitempty"`
// links to the discussions
Discussions []string `json:"discussions,omitempty"`
Crashes []publicAPICrashDescription `json:"crashes,omitempty"`
}
type fixCommit struct {
Title string `json:"title"`
Link string `json:"link,omitempty"`
Hash string `json:"hash,omitempty"`
} }
type PublicAPICrashDescription struct { type publicAPICrashDescription struct {
SyzReproducer string `json:"syz-reproducer,omitempty"` SyzReproducer string `json:"syz-reproducer,omitempty"`
CReproducer string `json:"c-reproducer,omitempty"` CReproducer string `json:"c-reproducer,omitempty"`
KernelConfig string `json:"kernel-config,omitempty"` KernelConfig string `json:"kernel-config,omitempty"`
...@@ -23,12 +34,32 @@ type PublicAPICrashDescription struct { ...@@ -23,12 +34,32 @@ type PublicAPICrashDescription struct {
Architecture string `json:"architecture,omitempty"` Architecture string `json:"architecture,omitempty"`
} }
func GetExtAPIDescrForBugPage(bugPage *uiBugPage) *PublicAPIBugDescription { func getExtAPIDescrForBugPage(bugPage *uiBugPage) *publicAPIBugDescription {
crash := bugPage.Crashes.Crashes[0] crash := bugPage.Crashes.Crashes[0]
return &PublicAPIBugDescription{ return &publicAPIBugDescription{
Version: 1, Version: 1,
Title: bugPage.Bug.Title, Title: bugPage.Bug.Title,
Crashes: []PublicAPICrashDescription{{ Discussions: func() []string {
if bugPage.Bug.ExternalLink == "" {
return nil
}
return []string{bugPage.Bug.ExternalLink}
}(),
FixCommits: func() []fixCommit {
if len(bugPage.Bug.Commits) == 0 {
return nil
}
var res []fixCommit
for _, commit := range bugPage.Bug.Commits {
res = append(res, fixCommit{
Title: commit.Title,
Hash: commit.Hash,
Link: commit.Link,
})
}
return res
}(),
Crashes: []publicAPICrashDescription{{
SyzReproducer: crash.ReproSyzLink, SyzReproducer: crash.ReproSyzLink,
CReproducer: crash.ReproCLink, CReproducer: crash.ReproCLink,
KernelConfig: crash.KernelConfigLink, KernelConfig: crash.KernelConfigLink,
...@@ -41,3 +72,47 @@ func GetExtAPIDescrForBugPage(bugPage *uiBugPage) *PublicAPIBugDescription { ...@@ -41,3 +72,47 @@ func GetExtAPIDescrForBugPage(bugPage *uiBugPage) *PublicAPIBugDescription {
}}, }},
} }
} }
type publicAPIBugGroup struct {
Version int `json:"version"`
Bugs []publicAPIBug
}
type publicAPIBug struct {
Title string `json:"title,omitempty"`
Link string `json:"link"`
LastUpdated string `json:"last-updated,omitempty"`
}
func getExtAPIDescrForBugGroups(bugGroups []*uiBugGroup) *publicAPIBugGroup {
return &publicAPIBugGroup{
Version: 1,
Bugs: func() []publicAPIBug {
var res []publicAPIBug
for _, group := range bugGroups {
for _, bug := range group.Bugs {
res = append(res, publicAPIBug{
Title: bug.Title,
Link: bug.Link,
})
}
}
return res
}(),
}
}
func GetJSONDescrFor(page interface{}) ([]byte, error) {
var res interface{}
switch i := page.(type) {
case *uiBugPage:
res = getExtAPIDescrForBugPage(i)
case *uiTerminalPage:
res = getExtAPIDescrForBugGroups([]*uiBugGroup{i.Bugs})
case *uiMainPage:
res = getExtAPIDescrForBugGroups(i.Groups)
default:
return nil, ErrClientNotFound
}
return json.MarshalIndent(res, "", "\t")
}
...@@ -5580,6 +5580,7 @@ static long syz_pkey_set(volatile long pkey, volatile long val) ...@@ -5580,6 +5580,7 @@ static long syz_pkey_set(volatile long pkey, volatile long val)
#if SYZ_EXECUTOR || SYZ_SWAP #if SYZ_EXECUTOR || SYZ_SWAP
#include <fcntl.h> #include <fcntl.h>
#include <linux/falloc.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <sys/stat.h> #include <sys/stat.h>
......
...@@ -11767,6 +11767,7 @@ static long syz_pkey_set(volatile long pkey, volatile long val) ...@@ -11767,6 +11767,7 @@ static long syz_pkey_set(volatile long pkey, volatile long val)
#if SYZ_EXECUTOR || SYZ_SWAP #if SYZ_EXECUTOR || SYZ_SWAP
#include <fcntl.h> #include <fcntl.h>
#include <linux/falloc.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <sys/stat.h> #include <sys/stat.h>
......