@@ -24,7 +24,9 @@ import (
2424
2525 "github.com/google/syzkaller/pkg/corpus"
2626 "github.com/google/syzkaller/pkg/cover"
27+ "github.com/google/syzkaller/pkg/db"
2728 "github.com/google/syzkaller/pkg/fuzzer"
29+ "github.com/google/syzkaller/pkg/hash"
2830 "github.com/google/syzkaller/pkg/html/pages"
2931 "github.com/google/syzkaller/pkg/log"
3032 "github.com/google/syzkaller/pkg/mgrconfig"
@@ -55,6 +57,7 @@ type HTTPServer struct {
5557 Pool * vm.Dispatcher
5658 Pools map [string ]* vm.Dispatcher
5759 TogglePause func (paused bool )
60+ CorpusDB * db.DB
5861
5962 // Can be set dynamically after calling Serve.
6063 Corpus atomic.Pointer [corpus.Corpus ]
@@ -81,6 +84,7 @@ func (serv *HTTPServer) Serve() {
8184 handle ("/vms" , serv .httpVMs )
8285 handle ("/vm" , serv .httpVM )
8386 handle ("/metrics" , promhttp .HandlerFor (prometheus .DefaultGatherer , promhttp.HandlerOpts {}).ServeHTTP )
87+ handle ("/addinput" , serv .httpAddInput )
8488 handle ("/syscalls" , serv .httpSyscalls )
8589 handle ("/corpus" , serv .httpCorpus )
8690 handle ("/corpus.db" , serv .httpDownloadCorpus )
@@ -734,6 +738,42 @@ func (serv *HTTPServer) modulesInfo(w http.ResponseWriter, r *http.Request) {
734738 serv .jsonPage (w , r , "modules" , cover .Modules )
735739}
736740
741+ func (serv * HTTPServer ) httpAddInput (w http.ResponseWriter , r * http.Request ) {
742+ w .Header ().Set ("Content-Type" , "multipart/form-data" )
743+ if r .Method != http .MethodPost {
744+ http .Error (w , "only POST method supported" , http .StatusMethodNotAllowed )
745+ return
746+ }
747+ err := r .ParseMultipartForm (20 << 20 )
748+ if err != nil {
749+ http .Error (w , fmt .Sprintf ("failed to parse form: %v" , err ), http .StatusBadRequest )
750+ return
751+ }
752+ file , _ , err := r .FormFile ("file" )
753+ if err != nil {
754+ http .Error (w , fmt .Sprintf ("failed to retrieve file from form-data: %v" , err ), http .StatusBadRequest )
755+ return
756+ }
757+ defer file .Close ()
758+ data , err := io .ReadAll (file )
759+ if err != nil {
760+ http .Error (w , fmt .Sprintf ("failed to read file: %v" , err ), http .StatusBadRequest )
761+ return
762+ }
763+ p , err := serv .Cfg .Target .Deserialize (data , prog .NonStrict )
764+ if err != nil {
765+ http .Error (w , fmt .Sprintf ("failed to deserialize prog: %v" , err ), http .StatusBadRequest )
766+ return
767+ }
768+ data = p .Serialize ()
769+ sig := hash .String (data )
770+ if serv .CorpusDB != nil {
771+ serv .CorpusDB .Save (sig , data , 0 )
772+ serv .CorpusDB .Flush ()
773+ w .Write ([]byte (fmt .Sprintf ("uploaded:\n %v" , data )))
774+ }
775+ }
776+
737777var alphaNumRegExp = regexp .MustCompile (`^[a-zA-Z0-9]*$` )
738778
739779func isAlphanumeric (s string ) bool {
0 commit comments