From 63f8a50e262f257a8bfd333d6fe6d9b1a99f49ab Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Wed, 6 Oct 2021 23:24:14 +0200 Subject: [PATCH 01/56] created new branch of master to merge the changes --- src/framework/analyses.ml | 11 ++ src/framework/sarif.ml | 250 ++++++++++++++++++++++++++++++++++++++ src/maingoblint.ml | 15 +++ 3 files changed, 276 insertions(+) create mode 100644 src/framework/sarif.ml diff --git a/src/framework/analyses.ml b/src/framework/analyses.ml index d1a56f1aef..efcb1f2611 100644 --- a/src/framework/analyses.ml +++ b/src/framework/analyses.ml @@ -213,6 +213,17 @@ struct else let f = BatIO.output_channel out in write_file f (get_string "outfile") + | "sarif" -> + let open BatPrintf in + + + let write_file f fn = + printf "Writing sarif to temp. file: %s\n%!" fn; + Sarif.createSarifOutput f; + + in + let f = BatIO.output_channel out in + write_file f (get_string "outfile") | "json" -> let open BatPrintf in let module SH = BatHashtbl.Make (Basetype.RawStrings) in diff --git a/src/framework/sarif.ml b/src/framework/sarif.ml new file mode 100644 index 0000000000..55a55405b7 --- /dev/null +++ b/src/framework/sarif.ml @@ -0,0 +1,250 @@ +(** The Sarif format is a standardised output format for static analysis tools. https://docs.oasis-open.org/sarif/sarif/v2.1.0/sarif-v2.1.0.html *) + + +open Cil +open Pretty +open GobConfig + +module GU = Goblintutil + + + +module Information = +struct + type t = { + shortDescription: String.t; + helpText:String.t; + helpUri:String.t; + fullDescription: String.t; + } + +end +module Sarif = +struct + type t = { + id: String.t; + information:Information.t; + } + + (* returns (id,helpText,shortDescription,helpUri,longDescription) *) + let getDescription (category:string) = match category with + |"Analyzer" -> ("Analyzer","The category analyser describes ....","","https://goblint.in.tum.de/home",""); + |"119" -> ("GO"^category, + "Improper Restriction of Operations within the Bounds of a Memory Buffer" + ,"The software performs operations on a memory buffer, but it can read from or write to a memory location that is outside of the intended boundary of the buffer. ", + "https://cwe.mitre.org/data/definitions/119.html", + "Certain languages allow direct addressing of memory locations and do not automatically ensure that these locations are valid for the memory buffer that is being referenced" + ^"This can cause read or write operations to be performed on memory locations that may be associated with other variables, data structures, or internal program data." + ^"As a result, an attacker may be able to execute arbitrary code, alter the intended control flow, read sensitive information, or cause the system to crash. "); + | "190" -> ("GO"^category , + "The software performs a calculation that can produce an integer overflow or wraparound, when the logic assumes that the resulting value will always be larger than the original value." + ^"This can introduce other weaknesses when the calculation is used for resource management or execution control. " + ,"Integer Overflow or Wraparound","https://cwe.mitre.org/data/definitions/190.html", + "An integer overflow or wraparound occurs when an integer value is incremented to a value that is too large to store in the associated representation. When this occurs, the value may wrap to become a very small or negative number. While this may be intended behavior in circumstances that rely on wrapping, it can have security consequences if the wrap is unexpected. This is especially the case if the integer overflow can be triggered using user-supplied inputs. This becomes security-critical when the result is used to control looping, make a security decision, or determine the offset or size in behaviors such as memory allocation, copying, concatenation, etc. "); + | "241" -> ("GO"^category,"Improper Handling of Unexpected Data Type", + "The software does not handle or incorrectly handles when a particular element is not the expected type, e.g. it expects a digit (0-9) but is provided with a letter (A-Z). ","https://cwe.mitre.org/data/definitions/241.html", + "") + | "362" -> ("GO"^category," Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')", + "The program contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently. ", + "https://cwe.mitre.org/data/definitions/362.html", + "") + | "369" -> ("GO"^category," Divide By Zero", + "The product divides a value by zero. ", + "https://cwe.mitre.org/data/definitions/369.html", + "This weakness typically occurs when an unexpected value is provided to the product, or if an error occurs that is not properly detected. It frequently occurs in calculations involving physical dimensions such as size, length, width, and height. "); + | "416" -> ("GO"^category, + "Use After Free", + "Referencing memory after it has been freed can cause a program to crash, use unexpected values, or execute code. ", + "https://cwe.mitre.org/data/definitions/416.html", + "The use of previously-freed memory can have any number of adverse consequences, ranging from the corruption of valid data to the execution of arbitrary code, depending on the instantiation and timing of the flaw. " + ^"The simplest way data corruption may occur involves the system's reuse of the freed memory. Use-after-free errors have two common and sometimes overlapping causes:" + ^" Error conditions and other exceptional circumstances." + ^" Confusion over which part of the program is responsible for freeing the memory." + ^"In this scenario, the memory in question is allocated to another pointer validly at some point after it has been freed. The original pointer to the freed memory is used again and points to somewhere within the new allocation. As the data is changed, it corrupts the validly used memory; this induces undefined behavior in the process." + ^"If the newly allocated data chances to hold a class, in C++ for example, various function pointers may be scattered within the heap data. If one of these function pointers is overwritten with an address to valid shellcode, execution of arbitrary code can be achieved. "); + | "476" -> ("GO"^category,"NULL Pointer Dereference", + "A NULL pointer dereference occurs when the application dereferences a pointer that it expects to be valid, but is NULL, typically causing a crash or exit. ", + "https://cwe.mitre.org/data/definitions/476.html", + "NULL pointer dereference issues can occur through a number of flaws, including race conditions, and simple programming omissions. "); + | "787" -> ("GO"^category, + "Out-of-bounds Write", + "The software writes data past the end, or before the beginning, of the intended buffer. ", + "https://cwe.mitre.org/data/definitions/787.html", + "Typically, this can result in corruption of data, a crash, or code execution. The software may modify an index or perform pointer arithmetic that references a memory location that is outside of the boundaries of the buffer. " + ^" A subsequent write operation then produces undefined or unexpected results. "); + | "788" -> ("GO"^category, + "Access of Memory Location After End of Buffer", + "The software reads or writes to a buffer using an index or pointer that references a memory location after the end of the buffer. ", + "https://cwe.mitre.org/data/definitions/788.html", + "This typically occurs when a pointer or its index is decremented to a position before the buffer;" + ^"when pointer arithmetic results in a position before the buffer; or when a negative index is used, which generates a position before the buffer. "); + | _ -> ("invalid","invalid","invalid","invalid","invalid") + + let rec printCategorieRules f (categories:string list) = + let printSingleCategory f cat = match getDescription cat with + | ("invalid","invalid","invalid","invalid","invalid") -> BatPrintf.fprintf f ""; + | (id,shortDescription,helpText,helpUri,longDescription) -> + BatPrintf.fprintf f " {\n"; + BatPrintf.fprintf f " \"id\": \"%s\",\n" id; + BatPrintf.fprintf f " \"helpUri\": \"%s\",\n" helpUri; + BatPrintf.fprintf f " \"help\": {\n"; + BatPrintf.fprintf f " \"text\": \"%s\"\n" helpText; + BatPrintf.fprintf f " },\n"; + BatPrintf.fprintf f " \"shortDescription\": {\n"; + BatPrintf.fprintf f " \"text\": \"%s\"\n" shortDescription; + BatPrintf.fprintf f " },\n"; + BatPrintf.fprintf f " \"fullDescription\": {\n"; + BatPrintf.fprintf f " \"text\": \"%s\"\n" longDescription; + BatPrintf.fprintf f " }\n "; + BatPrintf.fprintf f " }" + in + match categories with + | [] -> BatPrintf.fprintf f ""; + | x::[] -> printSingleCategory f x; + | x::xs -> printSingleCategory f x; + (*BatPrintf.fprintf f ",";*) + BatPrintf.fprintf f "\n"; + printCategorieRules f xs + + let getBehaviorCategory (behavior:MessageCategory.behavior) = match behavior with + | Implementation-> "Implementation"; + | Machine-> "Machine"; + | Undefined u-> match u with + | NullPointerDereference -> "476"; + | UseAfterFree -> "416" + | ArrayOutOfBounds arrayOutOfBounds -> match arrayOutOfBounds with + | PastEnd -> "788"; + | BeforeStart -> "786:"; + | Unknown -> "119" + + let returnCategory (cat:MessageCategory.category)= match cat with + | MessageCategory.Assert -> "Assert"; + | MessageCategory.Deadcode -> "Deadcode"; + | MessageCategory.Race -> "Race"; + | MessageCategory.Unknown -> "Category Unknown"; + | MessageCategory.Analyzer -> "Analyzer"; + | MessageCategory.Behavior b -> getBehaviorCategory b; + | MessageCategory.Cast c -> "241"; + | MessageCategory.Integer i -> match i with + | Overflow -> "190"; + | DivByZero -> "369" + +end + +let print_physicalLocationPiece f Messages.Piece.{loc; text = m; context=con;} = + let printContext f (context:Obj.t option) = match context with + | Some c -> BatPrintf.fprintf f "has context\n"; + BatPrintf.fprintf f "%d\n" (Obj.reachable_words c); + | None -> (); + in + (* for the github action removes leading ./analysistarget/*) + let trimFile (path:string) = + Str.string_after path 17; + in + match loc with + | None -> + BatPrintf.fprintf f ""; + | Some l -> + BatPrintf.fprintf f " \"physicalLocation\": " ; + BatPrintf.fprintf f "{\n \"artifactLocation\": {\n \"uri\":\"%s\"\n },\n" ( l.file) ; + BatPrintf.fprintf f " \"region\": {\n"; + BatPrintf.fprintf f " \"startLine\":%d,\n" l.line ; + BatPrintf.fprintf f " \"startColumn\":%d,\n" l.column ; + BatPrintf.fprintf f " \"endColumn\":%d,\n" l.column ; + BatPrintf.fprintf f " \"endLine\":%d\n" l.line ; + (*printContext f con;*) + BatPrintf.fprintf f " }\n" + + + + + let printMultipiece f (mp:Messages.MultiPiece.t)= + let rec printPieces f (pieces:Messages.Piece.t list)= match pieces with + | [] -> BatPrintf.fprintf f " }\n"; + | x::[] -> print_physicalLocationPiece f x; + | x::xs -> print_physicalLocationPiece f x; + BatPrintf.fprintf f " },\n"; + printPieces f xs; + in + let printMessageText f Messages.Piece.{loc; text = m; _} = + BatPrintf.fprintf f "\n \"message\": {\n \"text\": \"%s\"\n }," m ; + in + match mp with + | Single (piece: Messages.Piece.t) -> + printMessageText f piece; + BatPrintf.fprintf f "\n \"locations\": [\n {\n "; + print_physicalLocationPiece f piece; + BatPrintf.fprintf f " }\n"; + | Group {group_text = n; pieces = e} -> + BatPrintf.fprintf f "\n \"locations\": [\n {\n "; + printPieces f e; + BatPrintf.fprintf f " }\n" + + let severityToLevel (severity:Messages.Severity.t)= match severity with + | Error -> "error" + | Warning -> "warning" + | Info -> "note" + | Debug -> "none" + | Success -> "none" + +let printSarifResults f = + let rec printTags f (tags:Messages.Tags.t)= match tags with + | [] ->BatPrintf.fprintf f " Unexpected Error, empty tags in Messages.Tags"; + | x::xs -> match x with + | CWE cwe-> BatPrintf.fprintf f " {\n \"ruleId\": \"%s\"," (string_of_int cwe); + (* | Category cat -> BatPrintf.fprintf f " {\n \"ruleId\": \"%s\"," (MessageCategory.show cat ); *) + | Category cat -> BatPrintf.fprintf f " {\n \"ruleId\": \"%s\"," (Sarif.returnCategory cat ); + in + let printOneResult (message:Messages.Message.t )= + printTags f message.tags; + (*BatPrintf.fprintf f " {\n \"ruleId\": \"%d\","1;*) + BatPrintf.fprintf f "\n \"level\": \"%s\"," (severityToLevel message.severity) ; + printMultipiece f message.multipiece; + BatPrintf.fprintf f " }\n ]"; + BatPrintf.fprintf f "\n }"; + in + let rec printResults (message_table:Messages.Message.t list)= + match message_table with + [] -> BatPrintf.fprintf f "\n"; + |x::[] -> printOneResult x; + BatPrintf.fprintf f "\n"; + | x::xs ->printOneResult x; + BatPrintf.fprintf f ",\n"; + printResults xs; + in + (*BatPrintf.fprintf f "MessageTable length %d"(List.length !Messages.Table.messages_list) ; *) + printResults (List.rev !Messages.Table.messages_list) + + + +let createSarifOutput f = + BatPrintf.fprintf f "{\n \"$schema\": \"%s\",\n " "https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.5.json"; + BatPrintf.fprintf f "\"version\": \"%s\",\n " "2.1.0"; + BatPrintf.fprintf f "\"runs\": [\n "; + BatPrintf.fprintf f "{\n "; + BatPrintf.fprintf f "\"tool\": {\n "; + BatPrintf.fprintf f "\ \"driver\": {\n "; + BatPrintf.fprintf f "\"name\": \"%s\",\n " "goblint"; + BatPrintf.fprintf f "\"fullName\": \"%s\",\n " "goblint static analyser"; + BatPrintf.fprintf f "\"informationUri\": \"%s\",\n " "https://goblint.in.tum.de/home"; + BatPrintf.fprintf f "\"organization\": \"%s\",\n " "TUM "; + BatPrintf.fprintf f "\"version\": \"%s\",\n " Version.goblint; + BatPrintf.fprintf f "\"downloadUri\": \"%s\",\n " "https://github.com/goblint/analyzer"; + BatPrintf.fprintf f " \"rules\": [\n "; + Sarif.printCategorieRules f ["124";"190";"281"]; + BatPrintf.fprintf f " ]\n "; + BatPrintf.fprintf f " }\n "; + BatPrintf.fprintf f "},\n"; + BatPrintf.fprintf f "\ \"invocations\": [\n "; + BatPrintf.fprintf f "{\n"; + BatPrintf.fprintf f " \"commandLine\": \"%a\",\n" (BatArray.print ~first:"" ~last:"" ~sep:" " BatString.print) BatSys.argv; + BatPrintf.fprintf f " \"executionSuccessful\": %B\n " true; + BatPrintf.fprintf f " }\n"; + BatPrintf.fprintf f " ],\n" ; + BatPrintf.fprintf f " \"defaultSourceLanguage\": \"%s\",\n" "C"; + BatPrintf.fprintf f " \"results\": [\n"; + printSarifResults f; + BatPrintf.fprintf f " ]\n" ; + BatPrintf.fprintf f " }\n " ; + BatPrintf.fprintf f "]\n" ; + BatPrintf.fprintf f "}\n"; diff --git a/src/maingoblint.ml b/src/maingoblint.ml index 700d03491b..1774f74c20 100644 --- a/src/maingoblint.ml +++ b/src/maingoblint.ml @@ -80,6 +80,20 @@ let option_spec_list = set_bool "g2html" true; set_string "result" "fast_xml" in + let configure_sarif () = + if (get_string "outfile" = "") then + set_string "outfile" "test.sarif"; + if get_string "exp.g2html_path" = "" then + set_string "exp.g2html_path" exe_dir; + set_bool "dbg.print_dead_code" true; + set_bool "exp.cfgdot" true; + set_bool "g2html" false; + set_bool "dbg.verbose" true; + set_bool "gobview" true; + set_bool "warn.race" true; + set_string "warn_at" "early"; + set_string "result" "sarif" + in let tmp_arg = ref "" in [ "-o" , Arg.String (set_string "outfile"), "" ; "-v" , Arg.Unit (fun () -> set_bool "dbg.verbose" true; set_bool "printstats" true), "" @@ -99,6 +113,7 @@ let option_spec_list = ; "--tracelocs" , add_int Tracing.tracelocs, "" ; "--help" , Arg.Unit (fun _ -> print_help stdout),"" ; "--html" , Arg.Unit (fun _ -> configure_html ()),"" + ; "--sarif" , Arg.Unit (fun _ -> configure_sarif ()),"" ; "--compare_runs" , Arg.Tuple [Arg.Set_string tmp_arg; Arg.String (fun x -> set_auto "compare_runs" (sprintf "['%s','%s']" !tmp_arg x))], "" ; "--oil" , Arg.String oil, "" (* ; "--tramp" , Arg.String (set_string "ana.osek.tramp"), "" *) From 90b0a7c2f5ce05c86bc6d23176e09affaafb5088 Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Thu, 7 Oct 2021 08:54:33 +0200 Subject: [PATCH 02/56] fixed tags bug --- src/framework/sarif.ml | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/framework/sarif.ml b/src/framework/sarif.ml index 55a55405b7..4dc0ed23b6 100644 --- a/src/framework/sarif.ml +++ b/src/framework/sarif.ml @@ -159,16 +159,27 @@ let print_physicalLocationPiece f Messages.Piece.{loc; text = m; context=con;} = let printMultipiece f (mp:Messages.MultiPiece.t)= + + let printMessageText f Messages.Piece.{loc; text = m; _} = + BatPrintf.fprintf f "\n \"message\": {\n \"text\": \"%s\"\n }," m ; + in + let printMessages f (pieces:Messages.Piece.t list) = + let toMessage Messages.Piece.{loc; text = m; _} =m in + match pieces with + | [] -> BatPrintf.fprintf f ""; + | x::xs -> BatPrintf.fprintf f "\n \"message\": {\n"; + (* (BatArray.print ~first:"" ~last:"" ~sep:"; ")*) + BatPrintf.fprintf f " \"text\": \"%s\"\n " (String.concat ";\n " (List.map toMessage pieces)) ; + BatPrintf.fprintf f " },\n"; + in let rec printPieces f (pieces:Messages.Piece.t list)= match pieces with | [] -> BatPrintf.fprintf f " }\n"; | x::[] -> print_physicalLocationPiece f x; | x::xs -> print_physicalLocationPiece f x; BatPrintf.fprintf f " },\n"; printPieces f xs; - in - let printMessageText f Messages.Piece.{loc; text = m; _} = - BatPrintf.fprintf f "\n \"message\": {\n \"text\": \"%s\"\n }," m ; - in + + in match mp with | Single (piece: Messages.Piece.t) -> printMessageText f piece; @@ -178,7 +189,8 @@ let print_physicalLocationPiece f Messages.Piece.{loc; text = m; context=con;} = | Group {group_text = n; pieces = e} -> BatPrintf.fprintf f "\n \"locations\": [\n {\n "; printPieces f e; - BatPrintf.fprintf f " }\n" + printMessages f e; + BatPrintf.fprintf f " },\n" let severityToLevel (severity:Messages.Severity.t)= match severity with | Error -> "error" @@ -191,13 +203,11 @@ let printSarifResults f = let rec printTags f (tags:Messages.Tags.t)= match tags with | [] ->BatPrintf.fprintf f " Unexpected Error, empty tags in Messages.Tags"; | x::xs -> match x with - | CWE cwe-> BatPrintf.fprintf f " {\n \"ruleId\": \"%s\"," (string_of_int cwe); - (* | Category cat -> BatPrintf.fprintf f " {\n \"ruleId\": \"%s\"," (MessageCategory.show cat ); *) - | Category cat -> BatPrintf.fprintf f " {\n \"ruleId\": \"%s\"," (Sarif.returnCategory cat ); + | CWE cwe-> BatPrintf.fprintf f " {\n \"ruleId\": \"%s\"," (string_of_int cwe); + | Category cat -> BatPrintf.fprintf f " {\n \"ruleId\": \"%s\"," (Sarif.returnCategory cat ); in let printOneResult (message:Messages.Message.t )= printTags f message.tags; - (*BatPrintf.fprintf f " {\n \"ruleId\": \"%d\","1;*) BatPrintf.fprintf f "\n \"level\": \"%s\"," (severityToLevel message.severity) ; printMultipiece f message.multipiece; BatPrintf.fprintf f " }\n ]"; @@ -224,8 +234,8 @@ let createSarifOutput f = BatPrintf.fprintf f "{\n "; BatPrintf.fprintf f "\"tool\": {\n "; BatPrintf.fprintf f "\ \"driver\": {\n "; - BatPrintf.fprintf f "\"name\": \"%s\",\n " "goblint"; - BatPrintf.fprintf f "\"fullName\": \"%s\",\n " "goblint static analyser"; + BatPrintf.fprintf f "\"name\": \"%s\",\n " "Goblint"; + BatPrintf.fprintf f "\"fullName\": \"%s\",\n " "Goblint static analyser"; BatPrintf.fprintf f "\"informationUri\": \"%s\",\n " "https://goblint.in.tum.de/home"; BatPrintf.fprintf f "\"organization\": \"%s\",\n " "TUM "; BatPrintf.fprintf f "\"version\": \"%s\",\n " Version.goblint; From 2ba31da398ad05b5e69cfba58182f865a4dd9421 Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Thu, 7 Oct 2021 10:45:48 +0200 Subject: [PATCH 03/56] fixed bug with multiLocations --- src/framework/sarif.ml | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/framework/sarif.ml b/src/framework/sarif.ml index 4dc0ed23b6..e3d0bdad65 100644 --- a/src/framework/sarif.ml +++ b/src/framework/sarif.ml @@ -167,13 +167,12 @@ let print_physicalLocationPiece f Messages.Piece.{loc; text = m; context=con;} = let toMessage Messages.Piece.{loc; text = m; _} =m in match pieces with | [] -> BatPrintf.fprintf f ""; - | x::xs -> BatPrintf.fprintf f "\n \"message\": {\n"; - (* (BatArray.print ~first:"" ~last:"" ~sep:"; ")*) - BatPrintf.fprintf f " \"text\": \"%s\"\n " (String.concat ";\n " (List.map toMessage pieces)) ; - BatPrintf.fprintf f " },\n"; + | x::xs -> BatPrintf.fprintf f "\n \"message\": {\n"; + BatPrintf.fprintf f " \"text\": \"%s\"\n " (String.concat "; " (List.map toMessage pieces)) ; + BatPrintf.fprintf f " }\n"; in let rec printPieces f (pieces:Messages.Piece.t list)= match pieces with - | [] -> BatPrintf.fprintf f " }\n"; + | [] -> BatPrintf.fprintf f ""; | x::[] -> print_physicalLocationPiece f x; | x::xs -> print_physicalLocationPiece f x; BatPrintf.fprintf f " },\n"; @@ -184,13 +183,14 @@ let print_physicalLocationPiece f Messages.Piece.{loc; text = m; context=con;} = | Single (piece: Messages.Piece.t) -> printMessageText f piece; BatPrintf.fprintf f "\n \"locations\": [\n {\n "; - print_physicalLocationPiece f piece; - BatPrintf.fprintf f " }\n"; + print_physicalLocationPiece f piece; + BatPrintf.fprintf f " }\n ]"; | Group {group_text = n; pieces = e} -> BatPrintf.fprintf f "\n \"locations\": [\n {\n "; - printPieces f e; - printMessages f e; - BatPrintf.fprintf f " },\n" + printPieces f e; + BatPrintf.fprintf f " }\n" ; + BatPrintf.fprintf f " }\n ],"; + printMessages f e let severityToLevel (severity:Messages.Severity.t)= match severity with | Error -> "error" @@ -209,8 +209,7 @@ let printSarifResults f = let printOneResult (message:Messages.Message.t )= printTags f message.tags; BatPrintf.fprintf f "\n \"level\": \"%s\"," (severityToLevel message.severity) ; - printMultipiece f message.multipiece; - BatPrintf.fprintf f " }\n ]"; + printMultipiece f message.multipiece; BatPrintf.fprintf f "\n }"; in let rec printResults (message_table:Messages.Message.t list)= From e707acce443a1ee3e1ed473286d139bde479c1dc Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Thu, 7 Oct 2021 11:02:18 +0200 Subject: [PATCH 04/56] fixed new single loc bug --- src/framework/sarif.ml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/framework/sarif.ml b/src/framework/sarif.ml index e3d0bdad65..fe0dd2948d 100644 --- a/src/framework/sarif.ml +++ b/src/framework/sarif.ml @@ -1,9 +1,6 @@ (** The Sarif format is a standardised output format for static analysis tools. https://docs.oasis-open.org/sarif/sarif/v2.1.0/sarif-v2.1.0.html *) -open Cil -open Pretty -open GobConfig module GU = Goblintutil @@ -184,6 +181,7 @@ let print_physicalLocationPiece f Messages.Piece.{loc; text = m; context=con;} = printMessageText f piece; BatPrintf.fprintf f "\n \"locations\": [\n {\n "; print_physicalLocationPiece f piece; + BatPrintf.fprintf f " }\n" ; BatPrintf.fprintf f " }\n ]"; | Group {group_text = n; pieces = e} -> BatPrintf.fprintf f "\n \"locations\": [\n {\n "; @@ -236,7 +234,7 @@ let createSarifOutput f = BatPrintf.fprintf f "\"name\": \"%s\",\n " "Goblint"; BatPrintf.fprintf f "\"fullName\": \"%s\",\n " "Goblint static analyser"; BatPrintf.fprintf f "\"informationUri\": \"%s\",\n " "https://goblint.in.tum.de/home"; - BatPrintf.fprintf f "\"organization\": \"%s\",\n " "TUM "; + BatPrintf.fprintf f "\"organization\": \"%s\",\n " "TUM - i2 and UTartu - SWS"; BatPrintf.fprintf f "\"version\": \"%s\",\n " Version.goblint; BatPrintf.fprintf f "\"downloadUri\": \"%s\",\n " "https://github.com/goblint/analyzer"; BatPrintf.fprintf f " \"rules\": [\n "; From 7804bcbcd18b36cfc9916e8fbd511c1de8278455 Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Thu, 7 Oct 2021 11:19:10 +0200 Subject: [PATCH 05/56] bugfix --- src/framework/sarif.ml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/framework/sarif.ml b/src/framework/sarif.ml index fe0dd2948d..4ac4e841a3 100644 --- a/src/framework/sarif.ml +++ b/src/framework/sarif.ml @@ -235,6 +235,7 @@ let createSarifOutput f = BatPrintf.fprintf f "\"fullName\": \"%s\",\n " "Goblint static analyser"; BatPrintf.fprintf f "\"informationUri\": \"%s\",\n " "https://goblint.in.tum.de/home"; BatPrintf.fprintf f "\"organization\": \"%s\",\n " "TUM - i2 and UTartu - SWS"; + (* Sarif prefers numerical Versions, this could be a future addition to Goblint. *) BatPrintf.fprintf f "\"version\": \"%s\",\n " Version.goblint; BatPrintf.fprintf f "\"downloadUri\": \"%s\",\n " "https://github.com/goblint/analyzer"; BatPrintf.fprintf f " \"rules\": [\n "; From 4ec8312d0b159001ad7d07bf9d8816634581c0e4 Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Thu, 7 Oct 2021 15:08:57 +0200 Subject: [PATCH 06/56] corrected rule display and matching --- src/framework/control.ml | 2 +- src/framework/sarif.ml | 116 ++++++++++++++++++++++++--------------- 2 files changed, 72 insertions(+), 46 deletions(-) diff --git a/src/framework/control.ml b/src/framework/control.ml index c89d127462..6b9b4a65a4 100644 --- a/src/framework/control.ml +++ b/src/framework/control.ml @@ -498,7 +498,7 @@ struct let cnt = Cilfacade.countLoc fn in uncalled_dead := !uncalled_dead + cnt; if get_bool "dbg.uncalled" then - M.warn ~loc ~category:Deadcode "Function \"%a\" will never be called: %dLoC" CilType.Fundec.pretty fn cnt + M.warn ~loc ~category:Deadcode "Function \'%a\' will never be called: %dLoC" CilType.Fundec.pretty fn cnt | _ -> () in List.iter print_and_calculate_uncalled file.globals; diff --git a/src/framework/sarif.ml b/src/framework/sarif.ml index 4ac4e841a3..4c4c0227f4 100644 --- a/src/framework/sarif.ml +++ b/src/framework/sarif.ml @@ -3,54 +3,58 @@ module GU = Goblintutil - - +module Category = MessageCategory module Information = struct - type t = { - shortDescription: String.t; - helpText:String.t; - helpUri:String.t; - fullDescription: String.t; - } +type t = { + description: String.t; + helpUri:String.t; +} end module Sarif = struct type t = { id: String.t; + category:Category.t; + cwe:Int.t; information:Information.t; } - (* returns (id,helpText,shortDescription,helpUri,longDescription) *) - let getDescription (category:string) = match category with - |"Analyzer" -> ("Analyzer","The category analyser describes ....","","https://goblint.in.tum.de/home",""); - |"119" -> ("GO"^category, - "Improper Restriction of Operations within the Bounds of a Memory Buffer" + + (* Given a Goblint Category or a CWE + returns (Ruleid,helpText,shortDescription,helpUri,longDescription) *) + let getDescription (id:string) = match id with + |"Analyzer" -> ("GO001","The category analyser describes ....","","https://goblint.in.tum.de/home",""); + |"119" -> ("GO002", + "CWE 119:Improper Restriction of Operations within the Bounds of a Memory Buffer" ,"The software performs operations on a memory buffer, but it can read from or write to a memory location that is outside of the intended boundary of the buffer. ", "https://cwe.mitre.org/data/definitions/119.html", "Certain languages allow direct addressing of memory locations and do not automatically ensure that these locations are valid for the memory buffer that is being referenced" ^"This can cause read or write operations to be performed on memory locations that may be associated with other variables, data structures, or internal program data." ^"As a result, an attacker may be able to execute arbitrary code, alter the intended control flow, read sensitive information, or cause the system to crash. "); - | "190" -> ("GO"^category , + | "190" -> ("GO003" , "The software performs a calculation that can produce an integer overflow or wraparound, when the logic assumes that the resulting value will always be larger than the original value." ^"This can introduce other weaknesses when the calculation is used for resource management or execution control. " ,"Integer Overflow or Wraparound","https://cwe.mitre.org/data/definitions/190.html", "An integer overflow or wraparound occurs when an integer value is incremented to a value that is too large to store in the associated representation. When this occurs, the value may wrap to become a very small or negative number. While this may be intended behavior in circumstances that rely on wrapping, it can have security consequences if the wrap is unexpected. This is especially the case if the integer overflow can be triggered using user-supplied inputs. This becomes security-critical when the result is used to control looping, make a security decision, or determine the offset or size in behaviors such as memory allocation, copying, concatenation, etc. "); - | "241" -> ("GO"^category,"Improper Handling of Unexpected Data Type", - "The software does not handle or incorrectly handles when a particular element is not the expected type, e.g. it expects a digit (0-9) but is provided with a letter (A-Z). ","https://cwe.mitre.org/data/definitions/241.html", - "") - | "362" -> ("GO"^category," Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')", + | "241" -> ("GO004", + "CWE 241:Improper Handling of Unexpected Data Type", + "The software does not handle or incorrectly handles when a particular element is not the expected type, e.g. it expects a digit (0-9) but is provided with a letter (A-Z). ", + "https://cwe.mitre.org/data/definitions/241.html", + "") + | "362"| "Race"-> ("GO005", + "CWE 362: Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')", "The program contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently. ", "https://cwe.mitre.org/data/definitions/362.html", "") - | "369" -> ("GO"^category," Divide By Zero", + | "369" -> ("GO006","CWE 369: Divide By Zero", "The product divides a value by zero. ", "https://cwe.mitre.org/data/definitions/369.html", "This weakness typically occurs when an unexpected value is provided to the product, or if an error occurs that is not properly detected. It frequently occurs in calculations involving physical dimensions such as size, length, width, and height. "); - | "416" -> ("GO"^category, - "Use After Free", + | "416" -> ("GO007", + "CWE 416:Use After Free", "Referencing memory after it has been freed can cause a program to crash, use unexpected values, or execute code. ", "https://cwe.mitre.org/data/definitions/416.html", "The use of previously-freed memory can have any number of adverse consequences, ranging from the corruption of valid data to the execution of arbitrary code, depending on the instantiation and timing of the flaw. " @@ -59,23 +63,38 @@ struct ^" Confusion over which part of the program is responsible for freeing the memory." ^"In this scenario, the memory in question is allocated to another pointer validly at some point after it has been freed. The original pointer to the freed memory is used again and points to somewhere within the new allocation. As the data is changed, it corrupts the validly used memory; this induces undefined behavior in the process." ^"If the newly allocated data chances to hold a class, in C++ for example, various function pointers may be scattered within the heap data. If one of these function pointers is overwritten with an address to valid shellcode, execution of arbitrary code can be achieved. "); - | "476" -> ("GO"^category,"NULL Pointer Dereference", + | "476" -> ("GO008","CWE 476:NULL Pointer Dereference", "A NULL pointer dereference occurs when the application dereferences a pointer that it expects to be valid, but is NULL, typically causing a crash or exit. ", "https://cwe.mitre.org/data/definitions/476.html", "NULL pointer dereference issues can occur through a number of flaws, including race conditions, and simple programming omissions. "); - | "787" -> ("GO"^category, - "Out-of-bounds Write", + | "561" |"DeadCode"-> ("GO009","CWE 561:Dead Code", + "The software contains dead code, which can never be executed. ", + "https://cwe.mitre.org/data/definitions/561.html", + "Dead code is source code that can never be executed in a running program. The surrounding code makes it impossible for a section of code to ever be executed. "); + | "570" -> ("GO0010","CWE 570:Expression is Always False", + "The software contains an expression that will always evaluate to false. ", + "https://cwe.mitre.org/data/definitions/570.html", + ""); + | "571" -> ("GO0011","CWE 571:Expression is Always True", + "The software contains an expression that will always evaluate to true. ", + "https://cwe.mitre.org/data/definitions/571.html", + ""); + | "787" -> ("GO012", + "CWE 787: Out-of-bounds Write", "The software writes data past the end, or before the beginning, of the intended buffer. ", "https://cwe.mitre.org/data/definitions/787.html", "Typically, this can result in corruption of data, a crash, or code execution. The software may modify an index or perform pointer arithmetic that references a memory location that is outside of the boundaries of the buffer. " ^" A subsequent write operation then produces undefined or unexpected results. "); - | "788" -> ("GO"^category, - "Access of Memory Location After End of Buffer", + | "788" -> ("GO013", + "CWE 788:Access of Memory Location After End of Buffer", "The software reads or writes to a buffer using an index or pointer that references a memory location after the end of the buffer. ", "https://cwe.mitre.org/data/definitions/788.html", "This typically occurs when a pointer or its index is decremented to a position before the buffer;" ^"when pointer arithmetic results in a position before the buffer; or when a negative index is used, which generates a position before the buffer. "); - | _ -> ("invalid","invalid","invalid","invalid","invalid") + | _ -> ("GO000","Unknown Category","Unknown Category","Unknown Category","Unknown Category") + + let getRuleID (id:string) = match (getDescription id ) with + | (ruleId,_,_,_,_) -> ruleId let rec printCategorieRules f (categories:string list) = let printSingleCategory f cat = match getDescription cat with @@ -100,10 +119,11 @@ struct | x::[] -> printSingleCategory f x; | x::xs -> printSingleCategory f x; (*BatPrintf.fprintf f ",";*) - BatPrintf.fprintf f "\n"; + BatPrintf.fprintf f ",\n"; printCategorieRules f xs let getBehaviorCategory (behavior:MessageCategory.behavior) = match behavior with + (* maybe CWE-589: Call to Non-ubiquitous API *) | Implementation-> "Implementation"; | Machine-> "Machine"; | Undefined u-> match u with @@ -114,13 +134,16 @@ struct | BeforeStart -> "786:"; | Unknown -> "119" - let returnCategory (cat:MessageCategory.category)= match cat with + let returnCategory (cat:MessageCategory.category)= match cat with + (* Assert is a category, that describer internal Goblint issues and has no real value in a Sarif output *) | MessageCategory.Assert -> "Assert"; - | MessageCategory.Deadcode -> "Deadcode"; + | MessageCategory.Deadcode -> "561"; | MessageCategory.Race -> "Race"; | MessageCategory.Unknown -> "Category Unknown"; + (* Analyzer is a category, that describer internal Goblint issues and has no real value in a Sarif output *) | MessageCategory.Analyzer -> "Analyzer"; | MessageCategory.Behavior b -> getBehaviorCategory b; + (* Cast is a category, that describer internal Goblint issues and has no real value in a Sarif output *) | MessageCategory.Cast c -> "241"; | MessageCategory.Integer i -> match i with | Overflow -> "190"; @@ -129,11 +152,7 @@ struct end let print_physicalLocationPiece f Messages.Piece.{loc; text = m; context=con;} = - let printContext f (context:Obj.t option) = match context with - | Some c -> BatPrintf.fprintf f "has context\n"; - BatPrintf.fprintf f "%d\n" (Obj.reachable_words c); - | None -> (); - in + (* The context can be important too, but at the moment the results of it can be quite confusing *) (* for the github action removes leading ./analysistarget/*) let trimFile (path:string) = Str.string_after path 17; @@ -151,8 +170,6 @@ let print_physicalLocationPiece f Messages.Piece.{loc; text = m; context=con;} = BatPrintf.fprintf f " \"endLine\":%d\n" l.line ; (*printContext f con;*) BatPrintf.fprintf f " }\n" - - let printMultipiece f (mp:Messages.MultiPiece.t)= @@ -197,12 +214,21 @@ let print_physicalLocationPiece f Messages.Piece.{loc; text = m; context=con;} = | Debug -> "none" | Success -> "none" -let printSarifResults f = - let rec printTags f (tags:Messages.Tags.t)= match tags with - | [] ->BatPrintf.fprintf f " Unexpected Error, empty tags in Messages.Tags"; - | x::xs -> match x with - | CWE cwe-> BatPrintf.fprintf f " {\n \"ruleId\": \"%s\"," (string_of_int cwe); - | Category cat -> BatPrintf.fprintf f " {\n \"ruleId\": \"%s\"," (Sarif.returnCategory cat ); +let printSarifResults f = + let getCWE (tag:Messages.Tag.t) = match tag with + | CWE cwe-> Some cwe; + | Category cat -> None; + in + let rec printTags f (tags:Messages.Tags.t)= + match List.find_map getCWE tags with + | Some cwe -> BatPrintf.fprintf f " {\n \"ruleId\": \"%s\"," (Sarif.getRuleID (string_of_int cwe)); + | None -> + match tags with + | [] ->BatPrintf.fprintf f " Unexpected Error, empty tags in Messages.Tags"; + | x::xs -> match x with + | CWE cwe-> BatPrintf.fprintf f " {\n \"ruleId\": \"%s\"," (Sarif.getRuleID (string_of_int cwe)); + | Category cat -> BatPrintf.fprintf f " {\n \"ruleId\": \"%s\"," (Sarif.getRuleID (Sarif.returnCategory cat) ); + in let printOneResult (message:Messages.Message.t )= printTags f message.tags; @@ -239,8 +265,8 @@ let createSarifOutput f = BatPrintf.fprintf f "\"version\": \"%s\",\n " Version.goblint; BatPrintf.fprintf f "\"downloadUri\": \"%s\",\n " "https://github.com/goblint/analyzer"; BatPrintf.fprintf f " \"rules\": [\n "; - Sarif.printCategorieRules f ["124";"190";"281"]; - BatPrintf.fprintf f " ]\n "; + Sarif.printCategorieRules f ["Analyzer"; "119"; "190";"241"; "362"; "369"; "416"; "476"; "561"; "570"; "571"; "787"; "788"]; + BatPrintf.fprintf f "\n ]\n "; BatPrintf.fprintf f " }\n "; BatPrintf.fprintf f "},\n"; BatPrintf.fprintf f "\ \"invocations\": [\n "; From f0620c2b1b0775fd9a0afe4454bed1a9961a0a92 Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Thu, 7 Oct 2021 15:20:40 +0200 Subject: [PATCH 07/56] minor changes --- src/framework/sarif.ml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/framework/sarif.ml b/src/framework/sarif.ml index 4c4c0227f4..a7ac942a91 100644 --- a/src/framework/sarif.ml +++ b/src/framework/sarif.ml @@ -29,12 +29,10 @@ struct |"Analyzer" -> ("GO001","The category analyser describes ....","","https://goblint.in.tum.de/home",""); |"119" -> ("GO002", "CWE 119:Improper Restriction of Operations within the Bounds of a Memory Buffer" - ,"The software performs operations on a memory buffer, but it can read from or write to a memory location that is outside of the intended boundary of the buffer. ", + ,"CWE119 ", "https://cwe.mitre.org/data/definitions/119.html", - "Certain languages allow direct addressing of memory locations and do not automatically ensure that these locations are valid for the memory buffer that is being referenced" - ^"This can cause read or write operations to be performed on memory locations that may be associated with other variables, data structures, or internal program data." - ^"As a result, an attacker may be able to execute arbitrary code, alter the intended control flow, read sensitive information, or cause the system to crash. "); - | "190" -> ("GO003" , + "The software performs operations on a memory buffer, but it can read from or write to a memory location that is outside of the intended boundary of the buffer."); + | "190" -> ("GO003" , "The software performs a calculation that can produce an integer overflow or wraparound, when the logic assumes that the resulting value will always be larger than the original value." ^"This can introduce other weaknesses when the calculation is used for resource management or execution control. " ,"Integer Overflow or Wraparound","https://cwe.mitre.org/data/definitions/190.html", @@ -99,9 +97,10 @@ struct let rec printCategorieRules f (categories:string list) = let printSingleCategory f cat = match getDescription cat with | ("invalid","invalid","invalid","invalid","invalid") -> BatPrintf.fprintf f ""; - | (id,shortDescription,helpText,helpUri,longDescription) -> + | (id,helpText,shortDescription,helpUri,longDescription) -> BatPrintf.fprintf f " {\n"; BatPrintf.fprintf f " \"id\": \"%s\",\n" id; + BatPrintf.fprintf f " \"name\": \"%s\",\n" shortDescription; BatPrintf.fprintf f " \"helpUri\": \"%s\",\n" helpUri; BatPrintf.fprintf f " \"help\": {\n"; BatPrintf.fprintf f " \"text\": \"%s\"\n" helpText; From 94766e2201c030529ddd5996c291fcf21adc85c3 Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Thu, 7 Oct 2021 19:05:20 +0200 Subject: [PATCH 08/56] minor changes --- src/framework/sarif.ml | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/framework/sarif.ml b/src/framework/sarif.ml index a7ac942a91..862d7330bb 100644 --- a/src/framework/sarif.ml +++ b/src/framework/sarif.ml @@ -5,21 +5,12 @@ module GU = Goblintutil module Category = MessageCategory -module Information = -struct -type t = { - description: String.t; - helpUri:String.t; - -} -end module Sarif = struct type t = { id: String.t; category:Category.t; - cwe:Int.t; - information:Information.t; + cwe:Int.t; } @@ -248,7 +239,7 @@ let printSarifResults f = printResults (List.rev !Messages.Table.messages_list) - +(* creates output in the Sarif format.*) let createSarifOutput f = BatPrintf.fprintf f "{\n \"$schema\": \"%s\",\n " "https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.5.json"; BatPrintf.fprintf f "\"version\": \"%s\",\n " "2.1.0"; From 54bfaba30e5f9670e0d228e1bd5e541a68edb494 Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Thu, 7 Oct 2021 19:09:19 +0200 Subject: [PATCH 09/56] github action location trimming --- src/framework/sarif.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/framework/sarif.ml b/src/framework/sarif.ml index 862d7330bb..adbbc78ef4 100644 --- a/src/framework/sarif.ml +++ b/src/framework/sarif.ml @@ -152,7 +152,7 @@ let print_physicalLocationPiece f Messages.Piece.{loc; text = m; context=con;} = BatPrintf.fprintf f ""; | Some l -> BatPrintf.fprintf f " \"physicalLocation\": " ; - BatPrintf.fprintf f "{\n \"artifactLocation\": {\n \"uri\":\"%s\"\n },\n" ( l.file) ; + BatPrintf.fprintf f "{\n \"artifactLocation\": {\n \"uri\":\"%s\"\n },\n" (trimFile l.file) ; BatPrintf.fprintf f " \"region\": {\n"; BatPrintf.fprintf f " \"startLine\":%d,\n" l.line ; BatPrintf.fprintf f " \"startColumn\":%d,\n" l.column ; From e3de78685b3e27836ece06200f1801292e9baa39 Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Thu, 7 Oct 2021 21:06:15 +0200 Subject: [PATCH 10/56] removed useless struct --- src/framework/sarif.ml | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/framework/sarif.ml b/src/framework/sarif.ml index adbbc78ef4..d8e0174702 100644 --- a/src/framework/sarif.ml +++ b/src/framework/sarif.ml @@ -5,13 +5,7 @@ module GU = Goblintutil module Category = MessageCategory -module Sarif = -struct - type t = { - id: String.t; - category:Category.t; - cwe:Int.t; - } + (* Given a Goblint Category or a CWE @@ -139,7 +133,7 @@ struct | Overflow -> "190"; | DivByZero -> "369" -end + let print_physicalLocationPiece f Messages.Piece.{loc; text = m; context=con;} = (* The context can be important too, but at the moment the results of it can be quite confusing *) @@ -211,13 +205,13 @@ let printSarifResults f = in let rec printTags f (tags:Messages.Tags.t)= match List.find_map getCWE tags with - | Some cwe -> BatPrintf.fprintf f " {\n \"ruleId\": \"%s\"," (Sarif.getRuleID (string_of_int cwe)); + | Some cwe -> BatPrintf.fprintf f " {\n \"ruleId\": \"%s\"," (getRuleID (string_of_int cwe)); | None -> match tags with | [] ->BatPrintf.fprintf f " Unexpected Error, empty tags in Messages.Tags"; | x::xs -> match x with - | CWE cwe-> BatPrintf.fprintf f " {\n \"ruleId\": \"%s\"," (Sarif.getRuleID (string_of_int cwe)); - | Category cat -> BatPrintf.fprintf f " {\n \"ruleId\": \"%s\"," (Sarif.getRuleID (Sarif.returnCategory cat) ); + | CWE cwe-> BatPrintf.fprintf f " {\n \"ruleId\": \"%s\"," (getRuleID (string_of_int cwe)); + | Category cat -> BatPrintf.fprintf f " {\n \"ruleId\": \"%s\"," (getRuleID (returnCategory cat) ); in let printOneResult (message:Messages.Message.t )= @@ -255,7 +249,7 @@ let createSarifOutput f = BatPrintf.fprintf f "\"version\": \"%s\",\n " Version.goblint; BatPrintf.fprintf f "\"downloadUri\": \"%s\",\n " "https://github.com/goblint/analyzer"; BatPrintf.fprintf f " \"rules\": [\n "; - Sarif.printCategorieRules f ["Analyzer"; "119"; "190";"241"; "362"; "369"; "416"; "476"; "561"; "570"; "571"; "787"; "788"]; + printCategorieRules f ["Analyzer"; "119"; "190";"241"; "362"; "369"; "416"; "476"; "561"; "570"; "571"; "787"; "788"]; BatPrintf.fprintf f "\n ]\n "; BatPrintf.fprintf f " }\n "; BatPrintf.fprintf f "},\n"; @@ -267,7 +261,7 @@ let createSarifOutput f = BatPrintf.fprintf f " ],\n" ; BatPrintf.fprintf f " \"defaultSourceLanguage\": \"%s\",\n" "C"; BatPrintf.fprintf f " \"results\": [\n"; - printSarifResults f; + printSarifResults f; BatPrintf.fprintf f " ]\n" ; BatPrintf.fprintf f " }\n " ; BatPrintf.fprintf f "]\n" ; From 6e78b1d2cdd32adfde4302ff90787ce297a32867 Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Thu, 7 Oct 2021 21:17:49 +0200 Subject: [PATCH 11/56] removed useless struct --- src/framework/sarif.ml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/framework/sarif.ml b/src/framework/sarif.ml index d8e0174702..6bf5907327 100644 --- a/src/framework/sarif.ml +++ b/src/framework/sarif.ml @@ -149,9 +149,7 @@ let print_physicalLocationPiece f Messages.Piece.{loc; text = m; context=con;} = BatPrintf.fprintf f "{\n \"artifactLocation\": {\n \"uri\":\"%s\"\n },\n" (trimFile l.file) ; BatPrintf.fprintf f " \"region\": {\n"; BatPrintf.fprintf f " \"startLine\":%d,\n" l.line ; - BatPrintf.fprintf f " \"startColumn\":%d,\n" l.column ; - BatPrintf.fprintf f " \"endColumn\":%d,\n" l.column ; - BatPrintf.fprintf f " \"endLine\":%d\n" l.line ; + BatPrintf.fprintf f " \"startColumn\":%d\n" l.column ; (*printContext f con;*) BatPrintf.fprintf f " }\n" From 28a3c8bc78f4b3a4d5c2980bf3a84a340babf228 Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Thu, 7 Oct 2021 22:19:11 +0200 Subject: [PATCH 12/56] refactoring --- src/framework/sarif.ml | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/framework/sarif.ml b/src/framework/sarif.ml index 6bf5907327..a4b589717d 100644 --- a/src/framework/sarif.ml +++ b/src/framework/sarif.ml @@ -11,13 +11,13 @@ module Category = MessageCategory (* Given a Goblint Category or a CWE returns (Ruleid,helpText,shortDescription,helpUri,longDescription) *) let getDescription (id:string) = match id with - |"Analyzer" -> ("GO001","The category analyser describes ....","","https://goblint.in.tum.de/home",""); - |"119" -> ("GO002", - "CWE 119:Improper Restriction of Operations within the Bounds of a Memory Buffer" + |"Analyzer" -> ("GO001","The category analyser describes ....","","https://goblint.in.tum.de/home",""); + |"119" -> ("GO002", + "CWE 119:Improper Restriction of Operations within the Bounds of a Memory Buffer" ,"CWE119 ", - "https://cwe.mitre.org/data/definitions/119.html", + "https://cwe.mitre.org/data/definitions/119.html", "The software performs operations on a memory buffer, but it can read from or write to a memory location that is outside of the intended boundary of the buffer."); - | "190" -> ("GO003" , + | "190" -> ("GO003" , "The software performs a calculation that can produce an integer overflow or wraparound, when the logic assumes that the resulting value will always be larger than the original value." ^"This can introduce other weaknesses when the calculation is used for resource management or execution control. " ,"Integer Overflow or Wraparound","https://cwe.mitre.org/data/definitions/190.html", @@ -79,6 +79,7 @@ module Category = MessageCategory let getRuleID (id:string) = match (getDescription id ) with | (ruleId,_,_,_,_) -> ruleId +(* prints the reportingDescriptor object for each category that is given. *) let rec printCategorieRules f (categories:string list) = let printSingleCategory f cat = match getDescription cat with | ("invalid","invalid","invalid","invalid","invalid") -> BatPrintf.fprintf f ""; @@ -102,12 +103,11 @@ module Category = MessageCategory | [] -> BatPrintf.fprintf f ""; | x::[] -> printSingleCategory f x; | x::xs -> printSingleCategory f x; - (*BatPrintf.fprintf f ",";*) BatPrintf.fprintf f ",\n"; - printCategorieRules f xs + printCategorieRules f xs let getBehaviorCategory (behavior:MessageCategory.behavior) = match behavior with - (* maybe CWE-589: Call to Non-ubiquitous API *) + (* maybe CWE-589: Call to Non-ubiquitous API https://cwe.mitre.org/data/definitions/589.html*) | Implementation-> "Implementation"; | Machine-> "Machine"; | Undefined u-> match u with @@ -127,7 +127,7 @@ module Category = MessageCategory (* Analyzer is a category, that describer internal Goblint issues and has no real value in a Sarif output *) | MessageCategory.Analyzer -> "Analyzer"; | MessageCategory.Behavior b -> getBehaviorCategory b; - (* Cast is a category, that describer internal Goblint issues and has no real value in a Sarif output *) + (* Cast of Type Missmatch is equal to the CWE 241. If MessageCategory.Cast is just an describing an internal Goblint issue, this CWE should be removed. *) | MessageCategory.Cast c -> "241"; | MessageCategory.Integer i -> match i with | Overflow -> "190"; @@ -139,8 +139,12 @@ let print_physicalLocationPiece f Messages.Piece.{loc; text = m; context=con;} = (* The context can be important too, but at the moment the results of it can be quite confusing *) (* for the github action removes leading ./analysistarget/*) let trimFile (path:string) = - Str.string_after path 17; + + match String.sub path 0 16 with + | "./analysistarget/" -> Str.string_after path 17; + |_ ->path; in + match loc with | None -> BatPrintf.fprintf f ""; @@ -197,10 +201,13 @@ let print_physicalLocationPiece f Messages.Piece.{loc; text = m; context=con;} = | Success -> "none" let printSarifResults f = + let getCWE (tag:Messages.Tag.t) = match tag with | CWE cwe-> Some cwe; | Category cat -> None; in + (* if a CWE is present only the CWE is used, since using multiple ones for the same result doesn' make sense. + If only Categorys are present, all of them are displayed.*) let rec printTags f (tags:Messages.Tags.t)= match List.find_map getCWE tags with | Some cwe -> BatPrintf.fprintf f " {\n \"ruleId\": \"%s\"," (getRuleID (string_of_int cwe)); @@ -227,7 +234,6 @@ let printSarifResults f = BatPrintf.fprintf f ",\n"; printResults xs; in - (*BatPrintf.fprintf f "MessageTable length %d"(List.length !Messages.Table.messages_list) ; *) printResults (List.rev !Messages.Table.messages_list) From b12907d717fafd52372ac02e44c1c57bbb1fd9b9 Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Thu, 7 Oct 2021 22:30:22 +0200 Subject: [PATCH 13/56] path changes --- src/framework/sarif.ml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/framework/sarif.ml b/src/framework/sarif.ml index a4b589717d..b7f0289dcb 100644 --- a/src/framework/sarif.ml +++ b/src/framework/sarif.ml @@ -142,7 +142,9 @@ let print_physicalLocationPiece f Messages.Piece.{loc; text = m; context=con;} = match String.sub path 0 16 with | "./analysistarget/" -> Str.string_after path 17; - |_ ->path; + | "/analysistarget/" -> Str.string_after path 16; + | "analysistarget/" -> Str.string_after path 15; + |_ -> path; in match loc with From 8c1794b40907811769a5c2d14bdb84fe0854ba4c Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Thu, 7 Oct 2021 22:39:23 +0200 Subject: [PATCH 14/56] path testing --- src/framework/sarif.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/framework/sarif.ml b/src/framework/sarif.ml index b7f0289dcb..4837d2b961 100644 --- a/src/framework/sarif.ml +++ b/src/framework/sarif.ml @@ -140,7 +140,7 @@ let print_physicalLocationPiece f Messages.Piece.{loc; text = m; context=con;} = (* for the github action removes leading ./analysistarget/*) let trimFile (path:string) = - match String.sub path 0 16 with + match String.sub path 0 17 with | "./analysistarget/" -> Str.string_after path 17; | "/analysistarget/" -> Str.string_after path 16; | "analysistarget/" -> Str.string_after path 15; From 4a07649b9991f98ebe5e201be3f409ec395eb93e Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Thu, 7 Oct 2021 23:02:31 +0200 Subject: [PATCH 15/56] last refactoring --- src/framework/sarif.ml | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/framework/sarif.ml b/src/framework/sarif.ml index 4837d2b961..4804e654cb 100644 --- a/src/framework/sarif.ml +++ b/src/framework/sarif.ml @@ -2,7 +2,6 @@ -module GU = Goblintutil module Category = MessageCategory @@ -136,14 +135,11 @@ module Category = MessageCategory let print_physicalLocationPiece f Messages.Piece.{loc; text = m; context=con;} = - (* The context can be important too, but at the moment the results of it can be quite confusing *) - (* for the github action removes leading ./analysistarget/*) - let trimFile (path:string) = - + (* The context can be important too, but at the moment displaying it's value in a useful way is hard. *) + (* for the github action removes leading ./analysistarget/ the trimFile function will most likely change a bit.*) + let trimFile (path:string) = match String.sub path 0 17 with | "./analysistarget/" -> Str.string_after path 17; - | "/analysistarget/" -> Str.string_after path 16; - | "analysistarget/" -> Str.string_after path 15; |_ -> path; in @@ -156,7 +152,6 @@ let print_physicalLocationPiece f Messages.Piece.{loc; text = m; context=con;} = BatPrintf.fprintf f " \"region\": {\n"; BatPrintf.fprintf f " \"startLine\":%d,\n" l.line ; BatPrintf.fprintf f " \"startColumn\":%d\n" l.column ; - (*printContext f con;*) BatPrintf.fprintf f " }\n" @@ -195,6 +190,7 @@ let print_physicalLocationPiece f Messages.Piece.{loc; text = m; context=con;} = BatPrintf.fprintf f " }\n ],"; printMessages f e +(*matches the Goblint severity to the Sarif property level.*) let severityToLevel (severity:Messages.Severity.t)= match severity with | Error -> "error" | Warning -> "warning" @@ -210,7 +206,7 @@ let printSarifResults f = in (* if a CWE is present only the CWE is used, since using multiple ones for the same result doesn' make sense. If only Categorys are present, all of them are displayed.*) - let rec printTags f (tags:Messages.Tags.t)= + let printTags f (tags:Messages.Tags.t)= match List.find_map getCWE tags with | Some cwe -> BatPrintf.fprintf f " {\n \"ruleId\": \"%s\"," (getRuleID (string_of_int cwe)); | None -> From 5cb218154043d5d202401c82cf47894a2aaabf0c Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Thu, 7 Oct 2021 23:12:58 +0200 Subject: [PATCH 16/56] added testScript and GithubAction --- gitHubActionCreateSarif/goblintAnalysis.yml | 67 +++++++++++++++++++++ scripts/createSarifTestOutput.sh | 16 +++++ 2 files changed, 83 insertions(+) create mode 100644 gitHubActionCreateSarif/goblintAnalysis.yml create mode 100755 scripts/createSarifTestOutput.sh diff --git a/gitHubActionCreateSarif/goblintAnalysis.yml b/gitHubActionCreateSarif/goblintAnalysis.yml new file mode 100644 index 0000000000..0c961b4aa9 --- /dev/null +++ b/gitHubActionCreateSarif/goblintAnalysis.yml @@ -0,0 +1,67 @@ +name: goblintAnalysis + +on: + push: + pull_request: + +jobs: + generate-Sarif: + env: + # ./analysisTarget/main.c needs to be replaced with ./analysisTarget/PATH_TO_MAIN + #the prefix ./analysisTarget/ is removed in Goblint, so the location shows correctly in Github + MAIN_NAME: './analysisTarget/05-inf_loop.c' + strategy: + fail-fast: false + matrix: + os: + - ubuntu-latest + ocaml-compiler: + - 4.12.0 # matches opam lock file + # don't add any other because they won't be used + + runs-on: ${{ matrix.os }} + permissions: + security-events: write + steps: + - name: Checkout Goblint repository + uses: actions/checkout@v2 + with: + repository: AlexanderEichler/analyzer + #this path needs to be changed to the main branch + ref: integrationSarif + - name: PWD + run: pwd + + - name: Set up OCaml ${{ matrix.ocaml-compiler }} + env: + # otherwise setup-ocaml pins non-locked dependencies + # https://github.com/ocaml/setup-ocaml/issues/166 + OPAMLOCKED: locked + uses: ocaml/setup-ocaml@v2 + with: + ocaml-compiler: ${{ matrix.ocaml-compiler }} + - name: PWD + run: pwd + + - name: Install dependencies + run: | + pwd + opam install . --deps-only --locked + - name: Build + run: | + pwd + ./make.sh nat + - name: Checkout code + uses: actions/checkout@v2 + with: + path: analysisTarget + - name: Generate the Sarif output + run: | + pwd + ls + ./goblint --sarif -o GitHubSarif.sarif ${{env.MAIN_NAME}} + - name: Upload the generated Sarif File + uses: github/codeql-action/upload-sarif@v1 + with: + # Path to SARIF file relative to the root of the repository + sarif_file: GitHubSarif.sarif diff --git a/scripts/createSarifTestOutput.sh b/scripts/createSarifTestOutput.sh new file mode 100755 index 0000000000..a6ec7fcb71 --- /dev/null +++ b/scripts/createSarifTestOutput.sh @@ -0,0 +1,16 @@ +#!/bin/bash +clear +echo "Generating output of test runs of tests/regression/*" +mkdir "/home/alex/Documents/git/analyzer/testResults" +dstpath=/home/alex/Documents/git/analyzer/testResults/ +for folder in "/home/alex/Documents/git/analyzer/tests/regression"/*; do + foldername=$(basename "$folder") + echo "$foldername" + mkdir "/home/alex/Documents/git/analyzer/testResults"/$foldername + for entry in "/home/alex/Documents/git/analyzer/tests/regression"/$foldername/*; do + + basename=$(basename "$entry") + dst="${dstpath}"$foldername"/"${basename::-2}".sarif" + ../goblint --sarif -o "$dst" "$entry" + done +done From 886e20a293be83166c55eb71954b187673b2b88f Mon Sep 17 00:00:00 2001 From: Alexander Eichler Date: Thu, 7 Oct 2021 23:35:05 +0200 Subject: [PATCH 17/56] Update goblintAnalysis.yml renamed file --- gitHubActionCreateSarif/goblintAnalysis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitHubActionCreateSarif/goblintAnalysis.yml b/gitHubActionCreateSarif/goblintAnalysis.yml index 0c961b4aa9..68875f9e72 100644 --- a/gitHubActionCreateSarif/goblintAnalysis.yml +++ b/gitHubActionCreateSarif/goblintAnalysis.yml @@ -9,7 +9,7 @@ jobs: env: # ./analysisTarget/main.c needs to be replaced with ./analysisTarget/PATH_TO_MAIN #the prefix ./analysisTarget/ is removed in Goblint, so the location shows correctly in Github - MAIN_NAME: './analysisTarget/05-inf_loop.c' + MAIN_NAME: './analysisTarget/main.c' strategy: fail-fast: false matrix: From 819b29ae0c1b48f13f57569aeaeb6bf298c49b3f Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Fri, 8 Oct 2021 13:16:41 +0200 Subject: [PATCH 18/56] improved indentation --- src/framework/sarif.ml | 488 ++++++++++++++++++++--------------------- 1 file changed, 244 insertions(+), 244 deletions(-) diff --git a/src/framework/sarif.ml b/src/framework/sarif.ml index 4804e654cb..ecb7db989a 100644 --- a/src/framework/sarif.ml +++ b/src/framework/sarif.ml @@ -6,265 +6,265 @@ module Category = MessageCategory - - (* Given a Goblint Category or a CWE - returns (Ruleid,helpText,shortDescription,helpUri,longDescription) *) - let getDescription (id:string) = match id with - |"Analyzer" -> ("GO001","The category analyser describes ....","","https://goblint.in.tum.de/home",""); - |"119" -> ("GO002", - "CWE 119:Improper Restriction of Operations within the Bounds of a Memory Buffer" - ,"CWE119 ", - "https://cwe.mitre.org/data/definitions/119.html", - "The software performs operations on a memory buffer, but it can read from or write to a memory location that is outside of the intended boundary of the buffer."); - | "190" -> ("GO003" , - "The software performs a calculation that can produce an integer overflow or wraparound, when the logic assumes that the resulting value will always be larger than the original value." - ^"This can introduce other weaknesses when the calculation is used for resource management or execution control. " - ,"Integer Overflow or Wraparound","https://cwe.mitre.org/data/definitions/190.html", - "An integer overflow or wraparound occurs when an integer value is incremented to a value that is too large to store in the associated representation. When this occurs, the value may wrap to become a very small or negative number. While this may be intended behavior in circumstances that rely on wrapping, it can have security consequences if the wrap is unexpected. This is especially the case if the integer overflow can be triggered using user-supplied inputs. This becomes security-critical when the result is used to control looping, make a security decision, or determine the offset or size in behaviors such as memory allocation, copying, concatenation, etc. "); - | "241" -> ("GO004", - "CWE 241:Improper Handling of Unexpected Data Type", - "The software does not handle or incorrectly handles when a particular element is not the expected type, e.g. it expects a digit (0-9) but is provided with a letter (A-Z). ", - "https://cwe.mitre.org/data/definitions/241.html", - "") - | "362"| "Race"-> ("GO005", - "CWE 362: Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')", - "The program contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently. ", - "https://cwe.mitre.org/data/definitions/362.html", - "") - | "369" -> ("GO006","CWE 369: Divide By Zero", - "The product divides a value by zero. ", - "https://cwe.mitre.org/data/definitions/369.html", - "This weakness typically occurs when an unexpected value is provided to the product, or if an error occurs that is not properly detected. It frequently occurs in calculations involving physical dimensions such as size, length, width, and height. "); - | "416" -> ("GO007", - "CWE 416:Use After Free", - "Referencing memory after it has been freed can cause a program to crash, use unexpected values, or execute code. ", - "https://cwe.mitre.org/data/definitions/416.html", - "The use of previously-freed memory can have any number of adverse consequences, ranging from the corruption of valid data to the execution of arbitrary code, depending on the instantiation and timing of the flaw. " - ^"The simplest way data corruption may occur involves the system's reuse of the freed memory. Use-after-free errors have two common and sometimes overlapping causes:" - ^" Error conditions and other exceptional circumstances." - ^" Confusion over which part of the program is responsible for freeing the memory." - ^"In this scenario, the memory in question is allocated to another pointer validly at some point after it has been freed. The original pointer to the freed memory is used again and points to somewhere within the new allocation. As the data is changed, it corrupts the validly used memory; this induces undefined behavior in the process." - ^"If the newly allocated data chances to hold a class, in C++ for example, various function pointers may be scattered within the heap data. If one of these function pointers is overwritten with an address to valid shellcode, execution of arbitrary code can be achieved. "); - | "476" -> ("GO008","CWE 476:NULL Pointer Dereference", - "A NULL pointer dereference occurs when the application dereferences a pointer that it expects to be valid, but is NULL, typically causing a crash or exit. ", - "https://cwe.mitre.org/data/definitions/476.html", - "NULL pointer dereference issues can occur through a number of flaws, including race conditions, and simple programming omissions. "); - | "561" |"DeadCode"-> ("GO009","CWE 561:Dead Code", - "The software contains dead code, which can never be executed. ", - "https://cwe.mitre.org/data/definitions/561.html", - "Dead code is source code that can never be executed in a running program. The surrounding code makes it impossible for a section of code to ever be executed. "); - | "570" -> ("GO0010","CWE 570:Expression is Always False", - "The software contains an expression that will always evaluate to false. ", - "https://cwe.mitre.org/data/definitions/570.html", - ""); - | "571" -> ("GO0011","CWE 571:Expression is Always True", - "The software contains an expression that will always evaluate to true. ", - "https://cwe.mitre.org/data/definitions/571.html", - ""); - | "787" -> ("GO012", - "CWE 787: Out-of-bounds Write", - "The software writes data past the end, or before the beginning, of the intended buffer. ", - "https://cwe.mitre.org/data/definitions/787.html", - "Typically, this can result in corruption of data, a crash, or code execution. The software may modify an index or perform pointer arithmetic that references a memory location that is outside of the boundaries of the buffer. " - ^" A subsequent write operation then produces undefined or unexpected results. "); - | "788" -> ("GO013", - "CWE 788:Access of Memory Location After End of Buffer", - "The software reads or writes to a buffer using an index or pointer that references a memory location after the end of the buffer. ", - "https://cwe.mitre.org/data/definitions/788.html", - "This typically occurs when a pointer or its index is decremented to a position before the buffer;" - ^"when pointer arithmetic results in a position before the buffer; or when a negative index is used, which generates a position before the buffer. "); - | _ -> ("GO000","Unknown Category","Unknown Category","Unknown Category","Unknown Category") - let getRuleID (id:string) = match (getDescription id ) with - | (ruleId,_,_,_,_) -> ruleId +(* Given a Goblint Category or a CWE + returns (Ruleid,helpText,shortDescription,helpUri,longDescription) *) +let getDescription (id:string) = match id with + |"Analyzer" -> ("GO001","The category analyser describes ....","","https://goblint.in.tum.de/home",""); + |"119" -> ("GO002", + "CWE 119:Improper Restriction of Operations within the Bounds of a Memory Buffer" + ,"CWE119 ", + "https://cwe.mitre.org/data/definitions/119.html", + "The software performs operations on a memory buffer, but it can read from or write to a memory location that is outside of the intended boundary of the buffer."); + | "190" -> ("GO003" , + "The software performs a calculation that can produce an integer overflow or wraparound, when the logic assumes that the resulting value will always be larger than the original value." + ^"This can introduce other weaknesses when the calculation is used for resource management or execution control. " + ,"Integer Overflow or Wraparound","https://cwe.mitre.org/data/definitions/190.html", + "An integer overflow or wraparound occurs when an integer value is incremented to a value that is too large to store in the associated representation. When this occurs, the value may wrap to become a very small or negative number. While this may be intended behavior in circumstances that rely on wrapping, it can have security consequences if the wrap is unexpected. This is especially the case if the integer overflow can be triggered using user-supplied inputs. This becomes security-critical when the result is used to control looping, make a security decision, or determine the offset or size in behaviors such as memory allocation, copying, concatenation, etc. "); + | "241" -> ("GO004", + "CWE 241:Improper Handling of Unexpected Data Type", + "The software does not handle or incorrectly handles when a particular element is not the expected type, e.g. it expects a digit (0-9) but is provided with a letter (A-Z). ", + "https://cwe.mitre.org/data/definitions/241.html", + "") + | "362"| "Race"-> ("GO005", + "CWE 362: Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')", + "The program contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently. ", + "https://cwe.mitre.org/data/definitions/362.html", + "") + | "369" -> ("GO006","CWE 369: Divide By Zero", + "The product divides a value by zero. ", + "https://cwe.mitre.org/data/definitions/369.html", + "This weakness typically occurs when an unexpected value is provided to the product, or if an error occurs that is not properly detected. It frequently occurs in calculations involving physical dimensions such as size, length, width, and height. "); + | "416" -> ("GO007", + "CWE 416:Use After Free", + "Referencing memory after it has been freed can cause a program to crash, use unexpected values, or execute code. ", + "https://cwe.mitre.org/data/definitions/416.html", + "The use of previously-freed memory can have any number of adverse consequences, ranging from the corruption of valid data to the execution of arbitrary code, depending on the instantiation and timing of the flaw. " + ^"The simplest way data corruption may occur involves the system's reuse of the freed memory. Use-after-free errors have two common and sometimes overlapping causes:" + ^" Error conditions and other exceptional circumstances." + ^" Confusion over which part of the program is responsible for freeing the memory." + ^"In this scenario, the memory in question is allocated to another pointer validly at some point after it has been freed. The original pointer to the freed memory is used again and points to somewhere within the new allocation. As the data is changed, it corrupts the validly used memory; this induces undefined behavior in the process." + ^"If the newly allocated data chances to hold a class, in C++ for example, various function pointers may be scattered within the heap data. If one of these function pointers is overwritten with an address to valid shellcode, execution of arbitrary code can be achieved. "); + | "476" -> ("GO008","CWE 476:NULL Pointer Dereference", + "A NULL pointer dereference occurs when the application dereferences a pointer that it expects to be valid, but is NULL, typically causing a crash or exit. ", + "https://cwe.mitre.org/data/definitions/476.html", + "NULL pointer dereference issues can occur through a number of flaws, including race conditions, and simple programming omissions. "); + | "561" |"DeadCode"-> ("GO009","CWE 561:Dead Code", + "The software contains dead code, which can never be executed. ", + "https://cwe.mitre.org/data/definitions/561.html", + "Dead code is source code that can never be executed in a running program. The surrounding code makes it impossible for a section of code to ever be executed. "); + | "570" -> ("GO0010","CWE 570:Expression is Always False", + "The software contains an expression that will always evaluate to false. ", + "https://cwe.mitre.org/data/definitions/570.html", + ""); + | "571" -> ("GO0011","CWE 571:Expression is Always True", + "The software contains an expression that will always evaluate to true. ", + "https://cwe.mitre.org/data/definitions/571.html", + ""); + | "787" -> ("GO012", + "CWE 787: Out-of-bounds Write", + "The software writes data past the end, or before the beginning, of the intended buffer. ", + "https://cwe.mitre.org/data/definitions/787.html", + "Typically, this can result in corruption of data, a crash, or code execution. The software may modify an index or perform pointer arithmetic that references a memory location that is outside of the boundaries of the buffer. " + ^" A subsequent write operation then produces undefined or unexpected results. "); + | "788" -> ("GO013", + "CWE 788:Access of Memory Location After End of Buffer", + "The software reads or writes to a buffer using an index or pointer that references a memory location after the end of the buffer. ", + "https://cwe.mitre.org/data/definitions/788.html", + "This typically occurs when a pointer or its index is decremented to a position before the buffer;" + ^"when pointer arithmetic results in a position before the buffer; or when a negative index is used, which generates a position before the buffer. "); + | _ -> ("GO000","Unknown Category","Unknown Category","Unknown Category","Unknown Category") + +let getRuleID (id:string) = match (getDescription id ) with + | (ruleId,_,_,_,_) -> ruleId (* prints the reportingDescriptor object for each category that is given. *) - let rec printCategorieRules f (categories:string list) = - let printSingleCategory f cat = match getDescription cat with - | ("invalid","invalid","invalid","invalid","invalid") -> BatPrintf.fprintf f ""; - | (id,helpText,shortDescription,helpUri,longDescription) -> - BatPrintf.fprintf f " {\n"; - BatPrintf.fprintf f " \"id\": \"%s\",\n" id; - BatPrintf.fprintf f " \"name\": \"%s\",\n" shortDescription; - BatPrintf.fprintf f " \"helpUri\": \"%s\",\n" helpUri; - BatPrintf.fprintf f " \"help\": {\n"; - BatPrintf.fprintf f " \"text\": \"%s\"\n" helpText; - BatPrintf.fprintf f " },\n"; - BatPrintf.fprintf f " \"shortDescription\": {\n"; - BatPrintf.fprintf f " \"text\": \"%s\"\n" shortDescription; - BatPrintf.fprintf f " },\n"; - BatPrintf.fprintf f " \"fullDescription\": {\n"; - BatPrintf.fprintf f " \"text\": \"%s\"\n" longDescription; - BatPrintf.fprintf f " }\n "; - BatPrintf.fprintf f " }" - in - match categories with - | [] -> BatPrintf.fprintf f ""; - | x::[] -> printSingleCategory f x; - | x::xs -> printSingleCategory f x; - BatPrintf.fprintf f ",\n"; - printCategorieRules f xs - - let getBehaviorCategory (behavior:MessageCategory.behavior) = match behavior with - (* maybe CWE-589: Call to Non-ubiquitous API https://cwe.mitre.org/data/definitions/589.html*) - | Implementation-> "Implementation"; - | Machine-> "Machine"; - | Undefined u-> match u with - | NullPointerDereference -> "476"; - | UseAfterFree -> "416" - | ArrayOutOfBounds arrayOutOfBounds -> match arrayOutOfBounds with - | PastEnd -> "788"; - | BeforeStart -> "786:"; - | Unknown -> "119" - - let returnCategory (cat:MessageCategory.category)= match cat with +let rec printCategorieRules f (categories:string list) = + let printSingleCategory f cat = match getDescription cat with + | ("invalid","invalid","invalid","invalid","invalid") -> BatPrintf.fprintf f ""; + | (id,helpText,shortDescription,helpUri,longDescription) -> + BatPrintf.fprintf f " {\n"; + BatPrintf.fprintf f " \"id\": \"%s\",\n" id; + BatPrintf.fprintf f " \"name\": \"%s\",\n" shortDescription; + BatPrintf.fprintf f " \"helpUri\": \"%s\",\n" helpUri; + BatPrintf.fprintf f " \"help\": {\n"; + BatPrintf.fprintf f " \"text\": \"%s\"\n" helpText; + BatPrintf.fprintf f " },\n"; + BatPrintf.fprintf f " \"shortDescription\": {\n"; + BatPrintf.fprintf f " \"text\": \"%s\"\n" shortDescription; + BatPrintf.fprintf f " },\n"; + BatPrintf.fprintf f " \"fullDescription\": {\n"; + BatPrintf.fprintf f " \"text\": \"%s\"\n" longDescription; + BatPrintf.fprintf f " }\n "; + BatPrintf.fprintf f " }" + in + match categories with + | [] -> BatPrintf.fprintf f ""; + | x::[] -> printSingleCategory f x; + | x::xs -> printSingleCategory f x; + BatPrintf.fprintf f ",\n"; + printCategorieRules f xs + +let getBehaviorCategory (behavior:MessageCategory.behavior) = match behavior with + (* maybe CWE-589: Call to Non-ubiquitous API https://cwe.mitre.org/data/definitions/589.html*) + | Implementation-> "Implementation"; + | Machine-> "Machine"; + | Undefined u-> match u with + | NullPointerDereference -> "476"; + | UseAfterFree -> "416" + | ArrayOutOfBounds arrayOutOfBounds -> match arrayOutOfBounds with + | PastEnd -> "788"; + | BeforeStart -> "786:"; + | Unknown -> "119" + +let returnCategory (cat:MessageCategory.category)= match cat with (* Assert is a category, that describer internal Goblint issues and has no real value in a Sarif output *) - | MessageCategory.Assert -> "Assert"; - | MessageCategory.Deadcode -> "561"; - | MessageCategory.Race -> "Race"; - | MessageCategory.Unknown -> "Category Unknown"; + | MessageCategory.Assert -> "Assert"; + | MessageCategory.Deadcode -> "561"; + | MessageCategory.Race -> "Race"; + | MessageCategory.Unknown -> "Category Unknown"; (* Analyzer is a category, that describer internal Goblint issues and has no real value in a Sarif output *) - | MessageCategory.Analyzer -> "Analyzer"; - | MessageCategory.Behavior b -> getBehaviorCategory b; + | MessageCategory.Analyzer -> "Analyzer"; + | MessageCategory.Behavior b -> getBehaviorCategory b; (* Cast of Type Missmatch is equal to the CWE 241. If MessageCategory.Cast is just an describing an internal Goblint issue, this CWE should be removed. *) - | MessageCategory.Cast c -> "241"; - | MessageCategory.Integer i -> match i with - | Overflow -> "190"; - | DivByZero -> "369" - + | MessageCategory.Cast c -> "241"; + | MessageCategory.Integer i -> match i with + | Overflow -> "190"; + | DivByZero -> "369" + let print_physicalLocationPiece f Messages.Piece.{loc; text = m; context=con;} = - (* The context can be important too, but at the moment displaying it's value in a useful way is hard. *) - (* for the github action removes leading ./analysistarget/ the trimFile function will most likely change a bit.*) - let trimFile (path:string) = - match String.sub path 0 17 with - | "./analysistarget/" -> Str.string_after path 17; - |_ -> path; - in - - match loc with - | None -> - BatPrintf.fprintf f ""; - | Some l -> - BatPrintf.fprintf f " \"physicalLocation\": " ; - BatPrintf.fprintf f "{\n \"artifactLocation\": {\n \"uri\":\"%s\"\n },\n" (trimFile l.file) ; - BatPrintf.fprintf f " \"region\": {\n"; - BatPrintf.fprintf f " \"startLine\":%d,\n" l.line ; - BatPrintf.fprintf f " \"startColumn\":%d\n" l.column ; - BatPrintf.fprintf f " }\n" - - - let printMultipiece f (mp:Messages.MultiPiece.t)= + (* The context can be important too, but at the moment displaying it's value in a useful way is hard. *) + (* for the github action removes leading ./analysistarget/ the trimFile function will most likely change a bit.*) + let trimFile (path:string) = + match String.sub path 0 17 with + | "./analysistarget/" -> Str.string_after path 17; + |_ -> path; + in + + match loc with + | None -> + BatPrintf.fprintf f ""; + | Some l -> + BatPrintf.fprintf f " \"physicalLocation\": " ; + BatPrintf.fprintf f "{\n \"artifactLocation\": {\n \"uri\":\"%s\"\n },\n" (trimFile l.file) ; + BatPrintf.fprintf f " \"region\": {\n"; + BatPrintf.fprintf f " \"startLine\":%d,\n" l.line ; + BatPrintf.fprintf f " \"startColumn\":%d\n" l.column ; + BatPrintf.fprintf f " }\n" - let printMessageText f Messages.Piece.{loc; text = m; _} = - BatPrintf.fprintf f "\n \"message\": {\n \"text\": \"%s\"\n }," m ; - in - let printMessages f (pieces:Messages.Piece.t list) = - let toMessage Messages.Piece.{loc; text = m; _} =m in - match pieces with - | [] -> BatPrintf.fprintf f ""; - | x::xs -> BatPrintf.fprintf f "\n \"message\": {\n"; - BatPrintf.fprintf f " \"text\": \"%s\"\n " (String.concat "; " (List.map toMessage pieces)) ; - BatPrintf.fprintf f " }\n"; - in - let rec printPieces f (pieces:Messages.Piece.t list)= match pieces with - | [] -> BatPrintf.fprintf f ""; - | x::[] -> print_physicalLocationPiece f x; - | x::xs -> print_physicalLocationPiece f x; - BatPrintf.fprintf f " },\n"; - printPieces f xs; - - in - match mp with - | Single (piece: Messages.Piece.t) -> - printMessageText f piece; - BatPrintf.fprintf f "\n \"locations\": [\n {\n "; - print_physicalLocationPiece f piece; - BatPrintf.fprintf f " }\n" ; - BatPrintf.fprintf f " }\n ]"; - | Group {group_text = n; pieces = e} -> - BatPrintf.fprintf f "\n \"locations\": [\n {\n "; - printPieces f e; - BatPrintf.fprintf f " }\n" ; - BatPrintf.fprintf f " }\n ],"; - printMessages f e + +let printMultipiece f (mp:Messages.MultiPiece.t)= + + let printMessageText f Messages.Piece.{loc; text = m; _} = + BatPrintf.fprintf f "\n \"message\": {\n \"text\": \"%s\"\n }," m ; + in + let printMessages f (pieces:Messages.Piece.t list) = + let toMessage Messages.Piece.{loc; text = m; _} =m in + match pieces with + | [] -> BatPrintf.fprintf f ""; + | x::xs -> BatPrintf.fprintf f "\n \"message\": {\n"; + BatPrintf.fprintf f " \"text\": \"%s\"\n " (String.concat "; " (List.map toMessage pieces)) ; + BatPrintf.fprintf f " }\n"; + in + let rec printPieces f (pieces:Messages.Piece.t list)= match pieces with + | [] -> BatPrintf.fprintf f ""; + | x::[] -> print_physicalLocationPiece f x; + | x::xs -> print_physicalLocationPiece f x; + BatPrintf.fprintf f " },\n"; + printPieces f xs; + + in + match mp with + | Single (piece: Messages.Piece.t) -> + printMessageText f piece; + BatPrintf.fprintf f "\n \"locations\": [\n {\n "; + print_physicalLocationPiece f piece; + BatPrintf.fprintf f " }\n" ; + BatPrintf.fprintf f " }\n ]"; + | Group {group_text = n; pieces = e} -> + BatPrintf.fprintf f "\n \"locations\": [\n {\n "; + printPieces f e; + BatPrintf.fprintf f " }\n" ; + BatPrintf.fprintf f " }\n ],"; + printMessages f e (*matches the Goblint severity to the Sarif property level.*) - let severityToLevel (severity:Messages.Severity.t)= match severity with - | Error -> "error" - | Warning -> "warning" - | Info -> "note" - | Debug -> "none" - | Success -> "none" +let severityToLevel (severity:Messages.Severity.t)= match severity with + | Error -> "error" + | Warning -> "warning" + | Info -> "note" + | Debug -> "none" + | Success -> "none" let printSarifResults f = - - let getCWE (tag:Messages.Tag.t) = match tag with - | CWE cwe-> Some cwe; - | Category cat -> None; - in - (* if a CWE is present only the CWE is used, since using multiple ones for the same result doesn' make sense. - If only Categorys are present, all of them are displayed.*) - let printTags f (tags:Messages.Tags.t)= - match List.find_map getCWE tags with - | Some cwe -> BatPrintf.fprintf f " {\n \"ruleId\": \"%s\"," (getRuleID (string_of_int cwe)); - | None -> - match tags with - | [] ->BatPrintf.fprintf f " Unexpected Error, empty tags in Messages.Tags"; - | x::xs -> match x with - | CWE cwe-> BatPrintf.fprintf f " {\n \"ruleId\": \"%s\"," (getRuleID (string_of_int cwe)); - | Category cat -> BatPrintf.fprintf f " {\n \"ruleId\": \"%s\"," (getRuleID (returnCategory cat) ); - - in - let printOneResult (message:Messages.Message.t )= - printTags f message.tags; - BatPrintf.fprintf f "\n \"level\": \"%s\"," (severityToLevel message.severity) ; - printMultipiece f message.multipiece; - BatPrintf.fprintf f "\n }"; - in - let rec printResults (message_table:Messages.Message.t list)= - match message_table with - [] -> BatPrintf.fprintf f "\n"; - |x::[] -> printOneResult x; - BatPrintf.fprintf f "\n"; - | x::xs ->printOneResult x; - BatPrintf.fprintf f ",\n"; - printResults xs; - in - printResults (List.rev !Messages.Table.messages_list) + + let getCWE (tag:Messages.Tag.t) = match tag with + | CWE cwe-> Some cwe; + | Category cat -> None; + in + (* if a CWE is present only the CWE is used, since using multiple ones for the same result doesn' make sense. + If only Categorys are present, all of them are displayed.*) + let printTags f (tags:Messages.Tags.t)= + match List.find_map getCWE tags with + | Some cwe -> BatPrintf.fprintf f " {\n \"ruleId\": \"%s\"," (getRuleID (string_of_int cwe)); + | None -> + match tags with + | [] ->BatPrintf.fprintf f " Unexpected Error, empty tags in Messages.Tags"; + | x::xs -> match x with + | CWE cwe-> BatPrintf.fprintf f " {\n \"ruleId\": \"%s\"," (getRuleID (string_of_int cwe)); + | Category cat -> BatPrintf.fprintf f " {\n \"ruleId\": \"%s\"," (getRuleID (returnCategory cat) ); + + in + let printOneResult (message:Messages.Message.t )= + printTags f message.tags; + BatPrintf.fprintf f "\n \"level\": \"%s\"," (severityToLevel message.severity) ; + printMultipiece f message.multipiece; + BatPrintf.fprintf f "\n }"; + in + let rec printResults (message_table:Messages.Message.t list)= + match message_table with + [] -> BatPrintf.fprintf f "\n"; + |x::[] -> printOneResult x; + BatPrintf.fprintf f "\n"; + | x::xs ->printOneResult x; + BatPrintf.fprintf f ",\n"; + printResults xs; + in + printResults (List.rev !Messages.Table.messages_list) (* creates output in the Sarif format.*) let createSarifOutput f = - BatPrintf.fprintf f "{\n \"$schema\": \"%s\",\n " "https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.5.json"; - BatPrintf.fprintf f "\"version\": \"%s\",\n " "2.1.0"; - BatPrintf.fprintf f "\"runs\": [\n "; - BatPrintf.fprintf f "{\n "; - BatPrintf.fprintf f "\"tool\": {\n "; - BatPrintf.fprintf f "\ \"driver\": {\n "; - BatPrintf.fprintf f "\"name\": \"%s\",\n " "Goblint"; - BatPrintf.fprintf f "\"fullName\": \"%s\",\n " "Goblint static analyser"; - BatPrintf.fprintf f "\"informationUri\": \"%s\",\n " "https://goblint.in.tum.de/home"; - BatPrintf.fprintf f "\"organization\": \"%s\",\n " "TUM - i2 and UTartu - SWS"; - (* Sarif prefers numerical Versions, this could be a future addition to Goblint. *) - BatPrintf.fprintf f "\"version\": \"%s\",\n " Version.goblint; - BatPrintf.fprintf f "\"downloadUri\": \"%s\",\n " "https://github.com/goblint/analyzer"; - BatPrintf.fprintf f " \"rules\": [\n "; - printCategorieRules f ["Analyzer"; "119"; "190";"241"; "362"; "369"; "416"; "476"; "561"; "570"; "571"; "787"; "788"]; - BatPrintf.fprintf f "\n ]\n "; - BatPrintf.fprintf f " }\n "; - BatPrintf.fprintf f "},\n"; - BatPrintf.fprintf f "\ \"invocations\": [\n "; - BatPrintf.fprintf f "{\n"; - BatPrintf.fprintf f " \"commandLine\": \"%a\",\n" (BatArray.print ~first:"" ~last:"" ~sep:" " BatString.print) BatSys.argv; - BatPrintf.fprintf f " \"executionSuccessful\": %B\n " true; - BatPrintf.fprintf f " }\n"; - BatPrintf.fprintf f " ],\n" ; - BatPrintf.fprintf f " \"defaultSourceLanguage\": \"%s\",\n" "C"; - BatPrintf.fprintf f " \"results\": [\n"; - printSarifResults f; - BatPrintf.fprintf f " ]\n" ; - BatPrintf.fprintf f " }\n " ; - BatPrintf.fprintf f "]\n" ; - BatPrintf.fprintf f "}\n"; + BatPrintf.fprintf f "{\n \"$schema\": \"%s\",\n " "https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.5.json"; + BatPrintf.fprintf f "\"version\": \"%s\",\n " "2.1.0"; + BatPrintf.fprintf f "\"runs\": [\n "; + BatPrintf.fprintf f "{\n "; + BatPrintf.fprintf f "\"tool\": {\n "; + BatPrintf.fprintf f "\ \"driver\": {\n "; + BatPrintf.fprintf f "\"name\": \"%s\",\n " "Goblint"; + BatPrintf.fprintf f "\"fullName\": \"%s\",\n " "Goblint static analyser"; + BatPrintf.fprintf f "\"informationUri\": \"%s\",\n " "https://goblint.in.tum.de/home"; + BatPrintf.fprintf f "\"organization\": \"%s\",\n " "TUM - i2 and UTartu - SWS"; + (* Sarif prefers numerical Versions, this could be a future addition to Goblint. *) + BatPrintf.fprintf f "\"version\": \"%s\",\n " Version.goblint; + BatPrintf.fprintf f "\"downloadUri\": \"%s\",\n " "https://github.com/goblint/analyzer"; + BatPrintf.fprintf f " \"rules\": [\n "; + printCategorieRules f ["Analyzer"; "119"; "190";"241"; "362"; "369"; "416"; "476"; "561"; "570"; "571"; "787"; "788"]; + BatPrintf.fprintf f "\n ]\n "; + BatPrintf.fprintf f " }\n "; + BatPrintf.fprintf f "},\n"; + BatPrintf.fprintf f "\ \"invocations\": [\n "; + BatPrintf.fprintf f "{\n"; + BatPrintf.fprintf f " \"commandLine\": \"%a\",\n" (BatArray.print ~first:"" ~last:"" ~sep:" " BatString.print) BatSys.argv; + BatPrintf.fprintf f " \"executionSuccessful\": %B\n " true; + BatPrintf.fprintf f " }\n"; + BatPrintf.fprintf f " ],\n" ; + BatPrintf.fprintf f " \"defaultSourceLanguage\": \"%s\",\n" "C"; + BatPrintf.fprintf f " \"results\": [\n"; + printSarifResults f; + BatPrintf.fprintf f " ]\n" ; + BatPrintf.fprintf f " }\n " ; + BatPrintf.fprintf f "]\n" ; + BatPrintf.fprintf f "}\n"; From 71c5d00423f2b9d43fdefb72b3ee5effd17100c1 Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Fri, 8 Oct 2021 14:38:07 +0200 Subject: [PATCH 19/56] removed unneeded flags, and some other minor refactoring --- {gitHubActionCreateSarif => scripts}/goblintAnalysis.yml | 5 +---- src/maingoblint.ml | 3 --- 2 files changed, 1 insertion(+), 7 deletions(-) rename {gitHubActionCreateSarif => scripts}/goblintAnalysis.yml (96%) diff --git a/gitHubActionCreateSarif/goblintAnalysis.yml b/scripts/goblintAnalysis.yml similarity index 96% rename from gitHubActionCreateSarif/goblintAnalysis.yml rename to scripts/goblintAnalysis.yml index 68875f9e72..772eb335f9 100644 --- a/gitHubActionCreateSarif/goblintAnalysis.yml +++ b/scripts/goblintAnalysis.yml @@ -28,10 +28,7 @@ jobs: with: repository: AlexanderEichler/analyzer #this path needs to be changed to the main branch - ref: integrationSarif - - name: PWD - run: pwd - + ref: integrationSarif - name: Set up OCaml ${{ matrix.ocaml-compiler }} env: # otherwise setup-ocaml pins non-locked dependencies diff --git a/src/maingoblint.ml b/src/maingoblint.ml index 1774f74c20..3f31f2e17a 100644 --- a/src/maingoblint.ml +++ b/src/maingoblint.ml @@ -89,9 +89,6 @@ let option_spec_list = set_bool "exp.cfgdot" true; set_bool "g2html" false; set_bool "dbg.verbose" true; - set_bool "gobview" true; - set_bool "warn.race" true; - set_string "warn_at" "early"; set_string "result" "sarif" in let tmp_arg = ref "" in From 36019f834aa3993a89de2621ffb10bd4539202e9 Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Sat, 9 Oct 2021 14:28:47 +0200 Subject: [PATCH 20/56] usage of yojson for Sarif output --- src/framework/analyses.ml | 6 ++ src/framework/sarif.ml | 185 +++++++++++++++++++++++++++++++++++--- src/maingoblint.ml | 12 +++ 3 files changed, 193 insertions(+), 10 deletions(-) diff --git a/src/framework/analyses.ml b/src/framework/analyses.ml index efcb1f2611..972a44c1af 100644 --- a/src/framework/analyses.ml +++ b/src/framework/analyses.ml @@ -6,6 +6,10 @@ open GobConfig module GU = Goblintutil module M = Messages +module S = Sarif +module SarifProperty = Sarif.SarifProperty + +module SarifLog = Sarif.SarifLog (** Analysis starts from lists of functions: start functions, exit functions, and * other functions. *) @@ -268,6 +272,8 @@ struct iter insert (Lazy.force table); let t1 = Unix.gettimeofday () -. t in Printf.printf "Done in %fs!\n" t1 *) + | "sarifTest" -> + Yojson.Safe.pretty_to_channel ~std:true out (Sarif.to_yojson ()) | "json-messages" -> Yojson.Safe.pretty_to_channel ~std:true out (Messages.Table.to_yojson ()) | "none" -> () diff --git a/src/framework/sarif.ml b/src/framework/sarif.ml index ecb7db989a..df5342ad65 100644 --- a/src/framework/sarif.ml +++ b/src/framework/sarif.ml @@ -1,12 +1,114 @@ (** The Sarif format is a standardised output format for static analysis tools. https://docs.oasis-open.org/sarif/sarif/v2.1.0/sarif-v2.1.0.html *) - +open GobConfig +module GU = Goblintutil module Category = MessageCategory +module SarifProperty = +struct + type t = + | Version + | Schema of string + | ToolName + | ToolFullName + | InformationUri + | Organization + | ToolVersion + + [@@deriving yojson] + + let value = function + |Version -> "2.1.0"; + |ToolName ->"Goblint" + |ToolFullName -> "Goblint static analyser" + |InformationUri -> "https://goblint.in.tum.de/home" + |Organization -> "TUM - i2 and UTartu - SWS" + |ToolVersion-> Version.goblint + + let to_yojson x = `String (value x) + +end +module SairfMessageObject = +struct + type t = { + text:string; + + } [@@deriving to_yojson] + + +end +module ReportingDescriptor = +struct + type t = { + ruleId:string; [@key "id"] + ruleName:string; [@key "name"] + helpUri:string; + help:SairfMessageObject.t; + shortDescription:SairfMessageObject.t; + fullDescription:SairfMessageObject.t; + + } [@@deriving to_yojson] + + +end + +module Driver = +struct + type t = { + name:SarifProperty.t; + fullName:SarifProperty.t; + informationUri:SarifProperty.t; + organization:SarifProperty.t; + version:SarifProperty.t; + rules:ReportingDescriptor.t list + } [@@deriving to_yojson] + + +end +module Tool = +struct + type t = { + driver:Driver.t; + } [@@deriving to_yojson] + + +end + +module ResultObject = +struct + type t = { + ruleId:string; + level:string; + message:SairfMessageObject.t; + } [@@deriving to_yojson] + +end + +module Run = +struct + type t = { + tool:Tool.t; + defaultSourceLanguage:string; + results:ResultObject.t list + }[@@deriving to_yojson] + + +end + + +module SarifLog = +struct + type t = { + version:SarifProperty.t [@name "2.1.0"]; + schema :string [@key "$schema"]; + runs:Run.t list ; + } [@@deriving to_yojson] + +end (* Given a Goblint Category or a CWE returns (Ruleid,helpText,shortDescription,helpUri,longDescription) *) let getDescription (id:string) = match id with @@ -75,6 +177,75 @@ let getDescription (id:string) = match id with ^"when pointer arithmetic results in a position before the buffer; or when a negative index is used, which generates a position before the buffer. "); | _ -> ("GO000","Unknown Category","Unknown Category","Unknown Category","Unknown Category") +let createMessageObject (text:String.t) = + { + SairfMessageObject.text=text; + } +let createDescriptor name = + match getDescription name with + | (id,helpText,shortDescription,helpUri,longDescription) -> + { + ReportingDescriptor.ruleId=id; + ReportingDescriptor.ruleName=name; + ReportingDescriptor.helpUri=helpUri; + ReportingDescriptor.help=(createMessageObject helpText); + ReportingDescriptor.shortDescription=(createMessageObject shortDescription); + ReportingDescriptor.fullDescription=(createMessageObject longDescription); + } +let transformToReportingDescriptor (id:String.t)= + createDescriptor id + +let (driverObject:Driver.t) = + { + Driver.name=SarifProperty.ToolName; + Driver.fullName=SarifProperty.ToolFullName; + Driver.informationUri=SarifProperty.InformationUri; + Driver.organization=SarifProperty.Organization; + Driver.version=SarifProperty.ToolVersion; + Driver.rules=List.map transformToReportingDescriptor ["Analyzer";"119"] + } +let (toolObject:Tool.t) = + { + Tool.driver=driverObject; + } +(*matches the Goblint severity to the Sarif property level.*) +let severityToLevel (severity:Messages.Severity.t)= match severity with + | Error -> "error" + | Warning -> "warning" + | Info -> "note" + | Debug -> "none" + | Success -> "none" + +let createResult (message:Messages.Message.t) = + { + ResultObject.ruleId=""; + ResultObject.level=severityToLevel message.severity; + ResultObject.message=createMessageObject ""; + } +module Sarif = +struct + + type t = + | SarifLog (*[@name "sarifLog"]*) + [@@deriving yojson] + + let (runObject:Run.t) = { + Run.tool=toolObject; + Run.defaultSourceLanguage="C"; + Run.results=List.map createResult (List.rev !Messages.Table.messages_list); + } + + + + let sarifObject={SarifLog.version=Version; + SarifLog.schema="https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.5.json"; + SarifLog.runs=[runObject] }; +end + + +let to_yojson () = [%to_yojson: SarifLog.t] Sarif.sarifObject + + let getRuleID (id:string) = match (getDescription id ) with | (ruleId,_,_,_,_) -> ruleId @@ -139,7 +310,7 @@ let print_physicalLocationPiece f Messages.Piece.{loc; text = m; context=con;} = (* for the github action removes leading ./analysistarget/ the trimFile function will most likely change a bit.*) let trimFile (path:string) = match String.sub path 0 17 with - | "./analysistarget/" -> Str.string_after path 17; + | "./analysisTarget" -> Str.string_after path 17; |_ -> path; in @@ -190,14 +361,6 @@ let printMultipiece f (mp:Messages.MultiPiece.t)= BatPrintf.fprintf f " }\n ],"; printMessages f e -(*matches the Goblint severity to the Sarif property level.*) -let severityToLevel (severity:Messages.Severity.t)= match severity with - | Error -> "error" - | Warning -> "warning" - | Info -> "note" - | Debug -> "none" - | Success -> "none" - let printSarifResults f = let getCWE (tag:Messages.Tag.t) = match tag with @@ -268,3 +431,5 @@ let createSarifOutput f = BatPrintf.fprintf f " }\n " ; BatPrintf.fprintf f "]\n" ; BatPrintf.fprintf f "}\n"; + + diff --git a/src/maingoblint.ml b/src/maingoblint.ml index 3f31f2e17a..e71eab3aab 100644 --- a/src/maingoblint.ml +++ b/src/maingoblint.ml @@ -91,6 +91,17 @@ let option_spec_list = set_bool "dbg.verbose" true; set_string "result" "sarif" in + let configure_sarifTest () = + if (get_string "outfile" = "") then + set_string "outfile" "test.sarif"; + if get_string "exp.g2html_path" = "" then + set_string "exp.g2html_path" exe_dir; + set_bool "dbg.print_dead_code" true; + set_bool "exp.cfgdot" true; + set_bool "g2html" false; + set_bool "dbg.verbose" true; + set_string "result" "sarifTest" + in let tmp_arg = ref "" in [ "-o" , Arg.String (set_string "outfile"), "" ; "-v" , Arg.Unit (fun () -> set_bool "dbg.verbose" true; set_bool "printstats" true), "" @@ -111,6 +122,7 @@ let option_spec_list = ; "--help" , Arg.Unit (fun _ -> print_help stdout),"" ; "--html" , Arg.Unit (fun _ -> configure_html ()),"" ; "--sarif" , Arg.Unit (fun _ -> configure_sarif ()),"" + ; "--sarif2" , Arg.Unit (fun _ -> configure_sarifTest ()),"" ; "--compare_runs" , Arg.Tuple [Arg.Set_string tmp_arg; Arg.String (fun x -> set_auto "compare_runs" (sprintf "['%s','%s']" !tmp_arg x))], "" ; "--oil" , Arg.String oil, "" (* ; "--tramp" , Arg.String (set_string "ana.osek.tramp"), "" *) From 7fc41760eb0e32a5e2551c3b56208e970cf822e8 Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Sat, 9 Oct 2021 20:02:50 +0200 Subject: [PATCH 21/56] added locationObject for yojson --- src/framework/analyses.ml | 12 +- src/framework/sarif.ml | 310 +++++++++++++++++++++++++------------- src/maingoblint.ml | 6 +- 3 files changed, 215 insertions(+), 113 deletions(-) diff --git a/src/framework/analyses.ml b/src/framework/analyses.ml index 972a44c1af..9a8ab32ef3 100644 --- a/src/framework/analyses.ml +++ b/src/framework/analyses.ml @@ -217,7 +217,7 @@ struct else let f = BatIO.output_channel out in write_file f (get_string "outfile") - | "sarif" -> + | "sarifOld" -> let open BatPrintf in @@ -272,8 +272,14 @@ struct iter insert (Lazy.force table); let t1 = Unix.gettimeofday () -. t in Printf.printf "Done in %fs!\n" t1 *) - | "sarifTest" -> - Yojson.Safe.pretty_to_channel ~std:true out (Sarif.to_yojson ()) + | "sarif" -> + let open BatPrintf in + let debugMessage= + printf "Writing sarif to temp. file: %s\n%!" (get_string "outfile"); + printf "Messages.Table.messages_list length: %d\n%!" (List.length (List.rev !Messages.Table.messages_list)); + in + debugMessage; + Yojson.Safe.pretty_to_channel ~std:true out (Sarif.to_yojson (List.rev !Messages.Table.messages_list)); | "json-messages" -> Yojson.Safe.pretty_to_channel ~std:true out (Messages.Table.to_yojson ()) | "none" -> () diff --git a/src/framework/sarif.ml b/src/framework/sarif.ml index df5342ad65..c401b08c00 100644 --- a/src/framework/sarif.ml +++ b/src/framework/sarif.ml @@ -6,6 +6,85 @@ module GU = Goblintutil module Category = MessageCategory + +(* Given a Goblint Category or a CWE + returns (Ruleid,helpText,shortDescription,helpUri,longDescription) *) +let getDescription (id:string) = match id with + |"Analyzer" -> ("GO001","The category analyser describes ....","","https://goblint.in.tum.de/home",""); + |"119" -> ("GO002", + "CWE 119:Improper Restriction of Operations within the Bounds of a Memory Buffer" + ,"CWE119 ", + "https://cwe.mitre.org/data/definitions/119.html", + "The software performs operations on a memory buffer, but it can read from or write to a memory location that is outside of the intended boundary of the buffer."); + | "190" -> ("GO003" , + "The software performs a calculation that can produce an integer overflow or wraparound, when the logic assumes that the resulting value will always be larger than the original value." + ^"This can introduce other weaknesses when the calculation is used for resource management or execution control. " + ,"Integer Overflow or Wraparound","https://cwe.mitre.org/data/definitions/190.html", + "An integer overflow or wraparound occurs when an integer value is incremented to a value that is too large to store in the associated representation. When this occurs, the value may wrap to become a very small or negative number. While this may be intended behavior in circumstances that rely on wrapping, it can have security consequences if the wrap is unexpected. This is especially the case if the integer overflow can be triggered using user-supplied inputs. This becomes security-critical when the result is used to control looping, make a security decision, or determine the offset or size in behaviors such as memory allocation, copying, concatenation, etc. "); + | "241" -> ("GO004", + "CWE 241:Improper Handling of Unexpected Data Type", + "The software does not handle or incorrectly handles when a particular element is not the expected type, e.g. it expects a digit (0-9) but is provided with a letter (A-Z). ", + "https://cwe.mitre.org/data/definitions/241.html", + "") + | "362"| "Race"-> ("GO005", + "CWE 362: Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')", + "The program contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently. ", + "https://cwe.mitre.org/data/definitions/362.html", + "") + | "369" -> ("GO006","CWE 369: Divide By Zero", + "The product divides a value by zero. ", + "https://cwe.mitre.org/data/definitions/369.html", + "This weakness typically occurs when an unexpected value is provided to the product, or if an error occurs that is not properly detected. It frequently occurs in calculations involving physical dimensions such as size, length, width, and height. "); + | "416" -> ("GO007", + "CWE 416:Use After Free", + "Referencing memory after it has been freed can cause a program to crash, use unexpected values, or execute code. ", + "https://cwe.mitre.org/data/definitions/416.html", + "The use of previously-freed memory can have any number of adverse consequences, ranging from the corruption of valid data to the execution of arbitrary code, depending on the instantiation and timing of the flaw. " + ^"The simplest way data corruption may occur involves the system's reuse of the freed memory. Use-after-free errors have two common and sometimes overlapping causes:" + ^" Error conditions and other exceptional circumstances." + ^" Confusion over which part of the program is responsible for freeing the memory." + ^"In this scenario, the memory in question is allocated to another pointer validly at some point after it has been freed. The original pointer to the freed memory is used again and points to somewhere within the new allocation. As the data is changed, it corrupts the validly used memory; this induces undefined behavior in the process." + ^"If the newly allocated data chances to hold a class, in C++ for example, various function pointers may be scattered within the heap data. If one of these function pointers is overwritten with an address to valid shellcode, execution of arbitrary code can be achieved. "); + | "476" -> ("GO008","CWE 476:NULL Pointer Dereference", + "A NULL pointer dereference occurs when the application dereferences a pointer that it expects to be valid, but is NULL, typically causing a crash or exit. ", + "https://cwe.mitre.org/data/definitions/476.html", + "NULL pointer dereference issues can occur through a number of flaws, including race conditions, and simple programming omissions. "); + | "561" |"DeadCode"-> ("GO009","CWE 561:Dead Code", + "The software contains dead code, which can never be executed. ", + "https://cwe.mitre.org/data/definitions/561.html", + "Dead code is source code that can never be executed in a running program. The surrounding code makes it impossible for a section of code to ever be executed. "); + | "570" -> ("GO0010","CWE 570:Expression is Always False", + "The software contains an expression that will always evaluate to false. ", + "https://cwe.mitre.org/data/definitions/570.html", + ""); + | "571" -> ("GO0011","CWE 571:Expression is Always True", + "The software contains an expression that will always evaluate to true. ", + "https://cwe.mitre.org/data/definitions/571.html", + ""); + | "787" -> ("GO012", + "CWE 787: Out-of-bounds Write", + "The software writes data past the end, or before the beginning, of the intended buffer. ", + "https://cwe.mitre.org/data/definitions/787.html", + "Typically, this can result in corruption of data, a crash, or code execution. The software may modify an index or perform pointer arithmetic that references a memory location that is outside of the boundaries of the buffer. " + ^" A subsequent write operation then produces undefined or unexpected results. "); + | "788" -> ("GO013", + "CWE 788:Access of Memory Location After End of Buffer", + "The software reads or writes to a buffer using an index or pointer that references a memory location after the end of the buffer. ", + "https://cwe.mitre.org/data/definitions/788.html", + "This typically occurs when a pointer or its index is decremented to a position before the buffer;" + ^"when pointer arithmetic results in a position before the buffer; or when a negative index is used, which generates a position before the buffer. "); + | _ -> ("GO000","Unknown Category","Unknown Category","Unknown Category","Unknown Category") + + +let getRuleIDOld (id:string) = match (getDescription id ) with + | (ruleId,_,_,_,_) -> ruleId +(*matches the Goblint severity to the Sarif property level.*) +let severityToLevel (severity:Messages.Severity.t)= match severity with + | Error -> "error" + | Warning -> "warning" + | Info -> "note" + | Debug -> "none" + | Success -> "none" module SarifProperty = struct type t = @@ -29,6 +108,44 @@ struct let to_yojson x = `String (value x) +end +module Region = +struct + type t = { + startLine:int; + startColumn:int; + } [@@deriving to_yojson] + + +end +module ArtifactLocation = +struct + type t = { + uri:string; + + } [@@deriving to_yojson] + + +end +module PhysicalLocation = +struct + type t = { + artifactLocation:ArtifactLocation.t; + region:Region.t; + + } [@@deriving to_yojson] + +end + + +module Locations = +struct + type t = { + + physicalLocation:PhysicalLocation.t; + + } [@@deriving to_yojson] + end module SairfMessageObject = struct @@ -83,6 +200,7 @@ struct ruleId:string; level:string; message:SairfMessageObject.t; + locations:Locations.t list; } [@@deriving to_yojson] @@ -100,88 +218,12 @@ struct end -module SarifLog = -struct - type t = { - version:SarifProperty.t [@name "2.1.0"]; - schema :string [@key "$schema"]; - runs:Run.t list ; - } [@@deriving to_yojson] - -end -(* Given a Goblint Category or a CWE - returns (Ruleid,helpText,shortDescription,helpUri,longDescription) *) -let getDescription (id:string) = match id with - |"Analyzer" -> ("GO001","The category analyser describes ....","","https://goblint.in.tum.de/home",""); - |"119" -> ("GO002", - "CWE 119:Improper Restriction of Operations within the Bounds of a Memory Buffer" - ,"CWE119 ", - "https://cwe.mitre.org/data/definitions/119.html", - "The software performs operations on a memory buffer, but it can read from or write to a memory location that is outside of the intended boundary of the buffer."); - | "190" -> ("GO003" , - "The software performs a calculation that can produce an integer overflow or wraparound, when the logic assumes that the resulting value will always be larger than the original value." - ^"This can introduce other weaknesses when the calculation is used for resource management or execution control. " - ,"Integer Overflow or Wraparound","https://cwe.mitre.org/data/definitions/190.html", - "An integer overflow or wraparound occurs when an integer value is incremented to a value that is too large to store in the associated representation. When this occurs, the value may wrap to become a very small or negative number. While this may be intended behavior in circumstances that rely on wrapping, it can have security consequences if the wrap is unexpected. This is especially the case if the integer overflow can be triggered using user-supplied inputs. This becomes security-critical when the result is used to control looping, make a security decision, or determine the offset or size in behaviors such as memory allocation, copying, concatenation, etc. "); - | "241" -> ("GO004", - "CWE 241:Improper Handling of Unexpected Data Type", - "The software does not handle or incorrectly handles when a particular element is not the expected type, e.g. it expects a digit (0-9) but is provided with a letter (A-Z). ", - "https://cwe.mitre.org/data/definitions/241.html", - "") - | "362"| "Race"-> ("GO005", - "CWE 362: Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')", - "The program contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently. ", - "https://cwe.mitre.org/data/definitions/362.html", - "") - | "369" -> ("GO006","CWE 369: Divide By Zero", - "The product divides a value by zero. ", - "https://cwe.mitre.org/data/definitions/369.html", - "This weakness typically occurs when an unexpected value is provided to the product, or if an error occurs that is not properly detected. It frequently occurs in calculations involving physical dimensions such as size, length, width, and height. "); - | "416" -> ("GO007", - "CWE 416:Use After Free", - "Referencing memory after it has been freed can cause a program to crash, use unexpected values, or execute code. ", - "https://cwe.mitre.org/data/definitions/416.html", - "The use of previously-freed memory can have any number of adverse consequences, ranging from the corruption of valid data to the execution of arbitrary code, depending on the instantiation and timing of the flaw. " - ^"The simplest way data corruption may occur involves the system's reuse of the freed memory. Use-after-free errors have two common and sometimes overlapping causes:" - ^" Error conditions and other exceptional circumstances." - ^" Confusion over which part of the program is responsible for freeing the memory." - ^"In this scenario, the memory in question is allocated to another pointer validly at some point after it has been freed. The original pointer to the freed memory is used again and points to somewhere within the new allocation. As the data is changed, it corrupts the validly used memory; this induces undefined behavior in the process." - ^"If the newly allocated data chances to hold a class, in C++ for example, various function pointers may be scattered within the heap data. If one of these function pointers is overwritten with an address to valid shellcode, execution of arbitrary code can be achieved. "); - | "476" -> ("GO008","CWE 476:NULL Pointer Dereference", - "A NULL pointer dereference occurs when the application dereferences a pointer that it expects to be valid, but is NULL, typically causing a crash or exit. ", - "https://cwe.mitre.org/data/definitions/476.html", - "NULL pointer dereference issues can occur through a number of flaws, including race conditions, and simple programming omissions. "); - | "561" |"DeadCode"-> ("GO009","CWE 561:Dead Code", - "The software contains dead code, which can never be executed. ", - "https://cwe.mitre.org/data/definitions/561.html", - "Dead code is source code that can never be executed in a running program. The surrounding code makes it impossible for a section of code to ever be executed. "); - | "570" -> ("GO0010","CWE 570:Expression is Always False", - "The software contains an expression that will always evaluate to false. ", - "https://cwe.mitre.org/data/definitions/570.html", - ""); - | "571" -> ("GO0011","CWE 571:Expression is Always True", - "The software contains an expression that will always evaluate to true. ", - "https://cwe.mitre.org/data/definitions/571.html", - ""); - | "787" -> ("GO012", - "CWE 787: Out-of-bounds Write", - "The software writes data past the end, or before the beginning, of the intended buffer. ", - "https://cwe.mitre.org/data/definitions/787.html", - "Typically, this can result in corruption of data, a crash, or code execution. The software may modify an index or perform pointer arithmetic that references a memory location that is outside of the boundaries of the buffer. " - ^" A subsequent write operation then produces undefined or unexpected results. "); - | "788" -> ("GO013", - "CWE 788:Access of Memory Location After End of Buffer", - "The software reads or writes to a buffer using an index or pointer that references a memory location after the end of the buffer. ", - "https://cwe.mitre.org/data/definitions/788.html", - "This typically occurs when a pointer or its index is decremented to a position before the buffer;" - ^"when pointer arithmetic results in a position before the buffer; or when a negative index is used, which generates a position before the buffer. "); - | _ -> ("GO000","Unknown Category","Unknown Category","Unknown Category","Unknown Category") - let createMessageObject (text:String.t) = { SairfMessageObject.text=text; } -let createDescriptor name = +(*A reportingDescriptor offers a lot of information about a Goblint rule *) +let createReportingDescriptor name = match getDescription name with | (id,helpText,shortDescription,helpUri,longDescription) -> { @@ -193,7 +235,7 @@ let createDescriptor name = ReportingDescriptor.fullDescription=(createMessageObject longDescription); } let transformToReportingDescriptor (id:String.t)= - createDescriptor id + createReportingDescriptor id let (driverObject:Driver.t) = { @@ -203,51 +245,105 @@ let (driverObject:Driver.t) = Driver.organization=SarifProperty.Organization; Driver.version=SarifProperty.ToolVersion; Driver.rules=List.map transformToReportingDescriptor ["Analyzer";"119"] - } + } let (toolObject:Tool.t) = { Tool.driver=driverObject; } -(*matches the Goblint severity to the Sarif property level.*) -let severityToLevel (severity:Messages.Severity.t)= match severity with - | Error -> "error" - | Warning -> "warning" - | Info -> "note" - | Debug -> "none" - | Success -> "none" + + +(*returns the Rule corresponding to a message entry *) +let getRuleID (tags:Messages.Tags.t) = + let getCWE (tag:Messages.Tag.t) = match tag with + | CWE cwe-> Some cwe; + | Category cat -> None; + in + (* if a CWE is present only the CWE is used, since using multiple ones for the same result doesn' make sense. + If only Categorys are present, all of them are displayed.*) + match List.find_map getCWE tags with + | Some cwe -> string_of_int cwe; + | None -> "" +let createPhysicalLocationObject (piece:Messages.Piece.t) = + let createRegionObject (line,column)= + { + Region.startLine=line; + Region.startColumn=column; + } + in + match piece.loc with + | None -> { + Locations.physicalLocation={ + PhysicalLocation.artifactLocation= { + ArtifactLocation.uri="no fileLocation was provided"; + }; + PhysicalLocation.region=createRegionObject (0,0); + } + }; + | Some loc ->{ + Locations.physicalLocation={ + PhysicalLocation.artifactLocation= { + ArtifactLocation.uri=loc.file; + }; + PhysicalLocation.region=createRegionObject (loc.line,loc.column); + } + } + + + +let createLocationsObject (multiPiece:Messages.MultiPiece.t) = match multiPiece with + | Single piece ->[createPhysicalLocationObject piece]; + | Group {group_text = n; pieces = e} ->List.map createPhysicalLocationObject e + + let createResult (message:Messages.Message.t) = +let rec getMessage (multiPiece:Messages.MultiPiece.t)= +match multiPiece with + | Single piece ->piece.text; + | Group {group_text = n; pieces = e} ->n + in { - ResultObject.ruleId=""; + ResultObject.ruleId=getRuleID message.tags; ResultObject.level=severityToLevel message.severity; - ResultObject.message=createMessageObject ""; + ResultObject.message=createMessageObject (getMessage message.multipiece); + ResultObject.locations=createLocationsObject message.multipiece; } + +let runObject msgList= +{ + Run.tool=toolObject; + Run.defaultSourceLanguage="C"; + Run.results=List.map createResult msgList; +} +module SarifLog = +struct + type t = { + version:string; + schema :string [@key "$schema"]; + runs:Run.t list ; + } [@@deriving to_yojson] + +end + + module Sarif = struct type t = | SarifLog (*[@name "sarifLog"]*) - [@@deriving yojson] - - let (runObject:Run.t) = { - Run.tool=toolObject; - Run.defaultSourceLanguage="C"; - Run.results=List.map createResult (List.rev !Messages.Table.messages_list); - } - - - - let sarifObject={SarifLog.version=Version; + [@@deriving yojson] + let sarifObject msgList={SarifLog.version="2.1.0"; SarifLog.schema="https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.5.json"; - SarifLog.runs=[runObject] }; + SarifLog.runs=[runObject msgList] }; + end -let to_yojson () = [%to_yojson: SarifLog.t] Sarif.sarifObject +let to_yojson msgList= + + [%to_yojson: SarifLog.t] (Sarif.sarifObject msgList) -let getRuleID (id:string) = match (getDescription id ) with - | (ruleId,_,_,_,_) -> ruleId (* prints the reportingDescriptor object for each category that is given. *) let rec printCategorieRules f (categories:string list) = @@ -371,13 +467,13 @@ let printSarifResults f = If only Categorys are present, all of them are displayed.*) let printTags f (tags:Messages.Tags.t)= match List.find_map getCWE tags with - | Some cwe -> BatPrintf.fprintf f " {\n \"ruleId\": \"%s\"," (getRuleID (string_of_int cwe)); + | Some cwe -> BatPrintf.fprintf f " {\n \"ruleId\": \"%s\"," (getRuleIDOld (string_of_int cwe)); | None -> match tags with | [] ->BatPrintf.fprintf f " Unexpected Error, empty tags in Messages.Tags"; | x::xs -> match x with - | CWE cwe-> BatPrintf.fprintf f " {\n \"ruleId\": \"%s\"," (getRuleID (string_of_int cwe)); - | Category cat -> BatPrintf.fprintf f " {\n \"ruleId\": \"%s\"," (getRuleID (returnCategory cat) ); + | CWE cwe-> BatPrintf.fprintf f " {\n \"ruleId\": \"%s\"," (getRuleIDOld (string_of_int cwe)); + | Category cat -> BatPrintf.fprintf f " {\n \"ruleId\": \"%s\"," (getRuleIDOld (returnCategory cat) ); in let printOneResult (message:Messages.Message.t )= diff --git a/src/maingoblint.ml b/src/maingoblint.ml index e71eab3aab..11d276b555 100644 --- a/src/maingoblint.ml +++ b/src/maingoblint.ml @@ -91,7 +91,7 @@ let option_spec_list = set_bool "dbg.verbose" true; set_string "result" "sarif" in - let configure_sarifTest () = + let configure_sarifOld () = if (get_string "outfile" = "") then set_string "outfile" "test.sarif"; if get_string "exp.g2html_path" = "" then @@ -100,7 +100,7 @@ let option_spec_list = set_bool "exp.cfgdot" true; set_bool "g2html" false; set_bool "dbg.verbose" true; - set_string "result" "sarifTest" + set_string "result" "sarifOld" in let tmp_arg = ref "" in [ "-o" , Arg.String (set_string "outfile"), "" @@ -122,7 +122,7 @@ let option_spec_list = ; "--help" , Arg.Unit (fun _ -> print_help stdout),"" ; "--html" , Arg.Unit (fun _ -> configure_html ()),"" ; "--sarif" , Arg.Unit (fun _ -> configure_sarif ()),"" - ; "--sarif2" , Arg.Unit (fun _ -> configure_sarifTest ()),"" + ; "--sarif2" , Arg.Unit (fun _ -> configure_sarifOld ()),"" ; "--compare_runs" , Arg.Tuple [Arg.Set_string tmp_arg; Arg.String (fun x -> set_auto "compare_runs" (sprintf "['%s','%s']" !tmp_arg x))], "" ; "--oil" , Arg.String oil, "" (* ; "--tramp" , Arg.String (set_string "ana.osek.tramp"), "" *) From 3f5028012d1bb79cc1c8a62f20035b60181c18fb Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Sun, 10 Oct 2021 14:22:02 +0200 Subject: [PATCH 22/56] bugfix location --- src/framework/analyses.ml | 1 - src/framework/sarif.ml | 91 ++++++++++++++++++--------------------- 2 files changed, 43 insertions(+), 49 deletions(-) diff --git a/src/framework/analyses.ml b/src/framework/analyses.ml index 9a8ab32ef3..53bd1cbc9c 100644 --- a/src/framework/analyses.ml +++ b/src/framework/analyses.ml @@ -7,7 +7,6 @@ open GobConfig module GU = Goblintutil module M = Messages module S = Sarif -module SarifProperty = Sarif.SarifProperty module SarifLog = Sarif.SarifLog diff --git a/src/framework/sarif.ml b/src/framework/sarif.ml index c401b08c00..e8a53d169f 100644 --- a/src/framework/sarif.ml +++ b/src/framework/sarif.ml @@ -7,10 +7,20 @@ module Category = MessageCategory +type categoryInformation = { + name:string; + ruleId:string; + helpText:string; + shortDescription:string; + helpUri:string; + longDescription:string; +} + + (* Given a Goblint Category or a CWE returns (Ruleid,helpText,shortDescription,helpUri,longDescription) *) let getDescription (id:string) = match id with - |"Analyzer" -> ("GO001","The category analyser describes ....","","https://goblint.in.tum.de/home",""); + |"Analyzer" -> ("GO001","TODO description","","https://goblint.in.tum.de/home",""); |"119" -> ("GO002", "CWE 119:Improper Restriction of Operations within the Bounds of a Memory Buffer" ,"CWE119 ", @@ -76,6 +86,7 @@ let getDescription (id:string) = match id with | _ -> ("GO000","Unknown Category","Unknown Category","Unknown Category","Unknown Category") + let getRuleIDOld (id:string) = match (getDescription id ) with | (ruleId,_,_,_,_) -> ruleId (*matches the Goblint severity to the Sarif property level.*) @@ -85,30 +96,7 @@ let severityToLevel (severity:Messages.Severity.t)= match severity with | Info -> "note" | Debug -> "none" | Success -> "none" -module SarifProperty = -struct - type t = - | Version - | Schema of string - | ToolName - | ToolFullName - | InformationUri - | Organization - | ToolVersion - - [@@deriving yojson] - - let value = function - |Version -> "2.1.0"; - |ToolName ->"Goblint" - |ToolFullName -> "Goblint static analyser" - |InformationUri -> "https://goblint.in.tum.de/home" - |Organization -> "TUM - i2 and UTartu - SWS" - |ToolVersion-> Version.goblint - - let to_yojson x = `String (value x) - -end + module Region = struct type t = { @@ -174,11 +162,11 @@ end module Driver = struct type t = { - name:SarifProperty.t; - fullName:SarifProperty.t; - informationUri:SarifProperty.t; - organization:SarifProperty.t; - version:SarifProperty.t; + name:string; + fullName:string; + informationUri:string; + organization:string; + version:string; rules:ReportingDescriptor.t list } [@@deriving to_yojson] @@ -236,14 +224,14 @@ let createReportingDescriptor name = } let transformToReportingDescriptor (id:String.t)= createReportingDescriptor id - + let (driverObject:Driver.t) = { - Driver.name=SarifProperty.ToolName; - Driver.fullName=SarifProperty.ToolFullName; - Driver.informationUri=SarifProperty.InformationUri; - Driver.organization=SarifProperty.Organization; - Driver.version=SarifProperty.ToolVersion; + Driver.name="Goblint"; + Driver.fullName= "Goblint static analyser"; + Driver.informationUri="https://goblint.in.tum.de/home"; + Driver.organization="TUM - i2 and UTartu - SWS"; + Driver.version=Version.goblint; Driver.rules=List.map transformToReportingDescriptor ["Analyzer";"119"] } let (toolObject:Tool.t) = @@ -262,7 +250,14 @@ let getRuleID (tags:Messages.Tags.t) = If only Categorys are present, all of them are displayed.*) match List.find_map getCWE tags with | Some cwe -> string_of_int cwe; - | None -> "" + | None -> match tags with + | [] -> "" + | x::xs -> match x with + |Category cat-> MessageCategory.show cat + | CWE c-> "" (*this case should not be reachable *) + + + let createPhysicalLocationObject (piece:Messages.Piece.t) = let createRegionObject (line,column)= { @@ -271,10 +266,11 @@ let createPhysicalLocationObject (piece:Messages.Piece.t) = } in match piece.loc with + (*This case is filtered out in hasLocation, but the compiler complains if it is not matched here. *) | None -> { Locations.physicalLocation={ PhysicalLocation.artifactLocation= { - ArtifactLocation.uri="no fileLocation was provided"; + ArtifactLocation.uri="no file was provided"; }; PhysicalLocation.region=createRegionObject (0,0); } @@ -288,19 +284,20 @@ let createPhysicalLocationObject (piece:Messages.Piece.t) = } } - +let hasLocation (piece:Messages.Piece.t) = match piece.loc with + |Some loc -> true + |None -> false let createLocationsObject (multiPiece:Messages.MultiPiece.t) = match multiPiece with - | Single piece ->[createPhysicalLocationObject piece]; - | Group {group_text = n; pieces = e} ->List.map createPhysicalLocationObject e + | Single piece ->List.map createPhysicalLocationObject (List.filter hasLocation [piece]); + | Group {group_text = n; pieces = e} ->List.map createPhysicalLocationObject (List.filter hasLocation e) let createResult (message:Messages.Message.t) = -let rec getMessage (multiPiece:Messages.MultiPiece.t)= -match multiPiece with - | Single piece ->piece.text; - | Group {group_text = n; pieces = e} ->n + let rec getMessage (multiPiece:Messages.MultiPiece.t)= match multiPiece with + | Single piece ->piece.text; + | Group {group_text = n; pieces = e} ->n in { ResultObject.ruleId=getRuleID message.tags; @@ -339,9 +336,7 @@ struct end -let to_yojson msgList= - - [%to_yojson: SarifLog.t] (Sarif.sarifObject msgList) +let to_yojson msgList= [%to_yojson: SarifLog.t] (Sarif.sarifObject msgList) From 38e5ce012b274050ffd7448391098393f9ca1b59 Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Sun, 10 Oct 2021 16:23:37 +0200 Subject: [PATCH 23/56] added invocationsObject --- src/framework/sarif.ml | 65 ++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/src/framework/sarif.ml b/src/framework/sarif.ml index e8a53d169f..9f91f55db8 100644 --- a/src/framework/sarif.ml +++ b/src/framework/sarif.ml @@ -17,34 +17,29 @@ type categoryInformation = { } +let getCWEDescription (cwe:int) = match cwe with + | 570 -> ("GO0010","CWE 570:Expression is Always False", + "The software contains an expression that will always evaluate to false. ", + "https://cwe.mitre.org/data/definitions/570.html", + ""); + | 571 -> ("GO0011","CWE 571:Expression is Always True", + "The software contains an expression that will always evaluate to true. ", + "https://cwe.mitre.org/data/definitions/571.html", + ""); + | _ -> ("GO"^(string_of_int cwe),"CWE"^(string_of_int cwe), + "", + "https://cwe.mitre.org/data/definitions/"^(string_of_int cwe)^".html", + "") (* Given a Goblint Category or a CWE returns (Ruleid,helpText,shortDescription,helpUri,longDescription) *) let getDescription (id:string) = match id with - |"Analyzer" -> ("GO001","TODO description","","https://goblint.in.tum.de/home",""); - |"119" -> ("GO002", - "CWE 119:Improper Restriction of Operations within the Bounds of a Memory Buffer" - ,"CWE119 ", - "https://cwe.mitre.org/data/definitions/119.html", - "The software performs operations on a memory buffer, but it can read from or write to a memory location that is outside of the intended boundary of the buffer."); - | "190" -> ("GO003" , - "The software performs a calculation that can produce an integer overflow or wraparound, when the logic assumes that the resulting value will always be larger than the original value." - ^"This can introduce other weaknesses when the calculation is used for resource management or execution control. " - ,"Integer Overflow or Wraparound","https://cwe.mitre.org/data/definitions/190.html", - "An integer overflow or wraparound occurs when an integer value is incremented to a value that is too large to store in the associated representation. When this occurs, the value may wrap to become a very small or negative number. While this may be intended behavior in circumstances that rely on wrapping, it can have security consequences if the wrap is unexpected. This is especially the case if the integer overflow can be triggered using user-supplied inputs. This becomes security-critical when the result is used to control looping, make a security decision, or determine the offset or size in behaviors such as memory allocation, copying, concatenation, etc. "); - | "241" -> ("GO004", - "CWE 241:Improper Handling of Unexpected Data Type", - "The software does not handle or incorrectly handles when a particular element is not the expected type, e.g. it expects a digit (0-9) but is provided with a letter (A-Z). ", - "https://cwe.mitre.org/data/definitions/241.html", - "") - | "362"| "Race"-> ("GO005", + |"Analyzer" -> ("GO001","Goblint Category Analyzer","","https://goblint.in.tum.de/home",""); + |"Assert" -> ("GO002","Goblint Category Assert","","https://goblint.in.tum.de/home",""); + | "362"-> ("GO005", "CWE 362: Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')", "The program contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently. ", "https://cwe.mitre.org/data/definitions/362.html", - "") - | "369" -> ("GO006","CWE 369: Divide By Zero", - "The product divides a value by zero. ", - "https://cwe.mitre.org/data/definitions/369.html", - "This weakness typically occurs when an unexpected value is provided to the product, or if an error occurs that is not properly detected. It frequently occurs in calculations involving physical dimensions such as size, length, width, and height. "); + "") | "416" -> ("GO007", "CWE 416:Use After Free", "Referencing memory after it has been freed can cause a program to crash, use unexpected values, or execute code. ", @@ -63,14 +58,7 @@ let getDescription (id:string) = match id with "The software contains dead code, which can never be executed. ", "https://cwe.mitre.org/data/definitions/561.html", "Dead code is source code that can never be executed in a running program. The surrounding code makes it impossible for a section of code to ever be executed. "); - | "570" -> ("GO0010","CWE 570:Expression is Always False", - "The software contains an expression that will always evaluate to false. ", - "https://cwe.mitre.org/data/definitions/570.html", - ""); - | "571" -> ("GO0011","CWE 571:Expression is Always True", - "The software contains an expression that will always evaluate to true. ", - "https://cwe.mitre.org/data/definitions/571.html", - ""); + | "787" -> ("GO012", "CWE 787: Out-of-bounds Write", "The software writes data past the end, or before the beginning, of the intended buffer. ", @@ -97,6 +85,16 @@ let severityToLevel (severity:Messages.Severity.t)= match severity with | Debug -> "none" | Success -> "none" +module InvocationObject = +struct + type t = { + commandLine:string; + executionSuccessful:string; + + } [@@deriving to_yojson] + + +end module Region = struct type t = { @@ -199,6 +197,7 @@ struct type t = { tool:Tool.t; defaultSourceLanguage:string; + invocations:InvocationObject.t; results:ResultObject.t list }[@@deriving to_yojson] @@ -308,8 +307,12 @@ let createResult (message:Messages.Message.t) = let runObject msgList= { + Run.invocations={ + InvocationObject.commandLine=String.concat ", " (BatArray.to_list BatSys.argv) ; + InvocationObject.executionSuccessful="true"; + }; Run.tool=toolObject; - Run.defaultSourceLanguage="C"; + Run.defaultSourceLanguage="C"; Run.results=List.map createResult msgList; } module SarifLog = From 0200afd051da218f6fd397432792da8f7e85a9cd Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Sun, 10 Oct 2021 19:06:21 +0200 Subject: [PATCH 24/56] removed obsolete code --- src/framework/analyses.ml | 14 +-- src/framework/sarif.ml | 196 ++------------------------------------ src/maingoblint.ml | 12 --- 3 files changed, 9 insertions(+), 213 deletions(-) diff --git a/src/framework/analyses.ml b/src/framework/analyses.ml index 53bd1cbc9c..b9acb9c8d4 100644 --- a/src/framework/analyses.ml +++ b/src/framework/analyses.ml @@ -215,18 +215,7 @@ struct BatFile.with_temporary_out ~mode:[`create;`text;`delete_on_exit] write_file else let f = BatIO.output_channel out in - write_file f (get_string "outfile") - | "sarifOld" -> - let open BatPrintf in - - - let write_file f fn = - printf "Writing sarif to temp. file: %s\n%!" fn; - Sarif.createSarifOutput f; - - in - let f = BatIO.output_channel out in - write_file f (get_string "outfile") + write_file f (get_string "outfile") | "json" -> let open BatPrintf in let module SH = BatHashtbl.Make (Basetype.RawStrings) in @@ -275,7 +264,6 @@ struct let open BatPrintf in let debugMessage= printf "Writing sarif to temp. file: %s\n%!" (get_string "outfile"); - printf "Messages.Table.messages_list length: %d\n%!" (List.length (List.rev !Messages.Table.messages_list)); in debugMessage; Yojson.Safe.pretty_to_channel ~std:true out (Sarif.to_yojson (List.rev !Messages.Table.messages_list)); diff --git a/src/framework/sarif.ml b/src/framework/sarif.ml index 9f91f55db8..00b4b31a5f 100644 --- a/src/framework/sarif.ml +++ b/src/framework/sarif.ml @@ -30,7 +30,8 @@ let getCWEDescription (cwe:int) = match cwe with "", "https://cwe.mitre.org/data/definitions/"^(string_of_int cwe)^".html", "") -(* Given a Goblint Category or a CWE + +(* Given a Goblint Category returns (Ruleid,helpText,shortDescription,helpUri,longDescription) *) let getDescription (id:string) = match id with |"Analyzer" -> ("GO001","Goblint Category Analyzer","","https://goblint.in.tum.de/home",""); @@ -89,7 +90,7 @@ module InvocationObject = struct type t = { commandLine:string; - executionSuccessful:string; + executionSuccessful:bool; } [@@deriving to_yojson] @@ -197,7 +198,7 @@ struct type t = { tool:Tool.t; defaultSourceLanguage:string; - invocations:InvocationObject.t; + invocations:InvocationObject.t list; results:ResultObject.t list }[@@deriving to_yojson] @@ -307,10 +308,10 @@ let createResult (message:Messages.Message.t) = let runObject msgList= { - Run.invocations={ + Run.invocations=[{ InvocationObject.commandLine=String.concat ", " (BatArray.to_list BatSys.argv) ; - InvocationObject.executionSuccessful="true"; - }; + InvocationObject.executionSuccessful=true; + }]; Run.tool=toolObject; Run.defaultSourceLanguage="C"; Run.results=List.map createResult msgList; @@ -318,6 +319,7 @@ let runObject msgList= module SarifLog = struct type t = { + (* Sarif prefers numerical Versions, this could be a future addition to Goblint. *) version:string; schema :string [@key "$schema"]; runs:Run.t list ; @@ -343,187 +345,5 @@ let to_yojson msgList= [%to_yojson: SarifLog.t] (Sarif.sarifObject msgList) -(* prints the reportingDescriptor object for each category that is given. *) -let rec printCategorieRules f (categories:string list) = - let printSingleCategory f cat = match getDescription cat with - | ("invalid","invalid","invalid","invalid","invalid") -> BatPrintf.fprintf f ""; - | (id,helpText,shortDescription,helpUri,longDescription) -> - BatPrintf.fprintf f " {\n"; - BatPrintf.fprintf f " \"id\": \"%s\",\n" id; - BatPrintf.fprintf f " \"name\": \"%s\",\n" shortDescription; - BatPrintf.fprintf f " \"helpUri\": \"%s\",\n" helpUri; - BatPrintf.fprintf f " \"help\": {\n"; - BatPrintf.fprintf f " \"text\": \"%s\"\n" helpText; - BatPrintf.fprintf f " },\n"; - BatPrintf.fprintf f " \"shortDescription\": {\n"; - BatPrintf.fprintf f " \"text\": \"%s\"\n" shortDescription; - BatPrintf.fprintf f " },\n"; - BatPrintf.fprintf f " \"fullDescription\": {\n"; - BatPrintf.fprintf f " \"text\": \"%s\"\n" longDescription; - BatPrintf.fprintf f " }\n "; - BatPrintf.fprintf f " }" - in - match categories with - | [] -> BatPrintf.fprintf f ""; - | x::[] -> printSingleCategory f x; - | x::xs -> printSingleCategory f x; - BatPrintf.fprintf f ",\n"; - printCategorieRules f xs - -let getBehaviorCategory (behavior:MessageCategory.behavior) = match behavior with - (* maybe CWE-589: Call to Non-ubiquitous API https://cwe.mitre.org/data/definitions/589.html*) - | Implementation-> "Implementation"; - | Machine-> "Machine"; - | Undefined u-> match u with - | NullPointerDereference -> "476"; - | UseAfterFree -> "416" - | ArrayOutOfBounds arrayOutOfBounds -> match arrayOutOfBounds with - | PastEnd -> "788"; - | BeforeStart -> "786:"; - | Unknown -> "119" - -let returnCategory (cat:MessageCategory.category)= match cat with - (* Assert is a category, that describer internal Goblint issues and has no real value in a Sarif output *) - | MessageCategory.Assert -> "Assert"; - | MessageCategory.Deadcode -> "561"; - | MessageCategory.Race -> "Race"; - | MessageCategory.Unknown -> "Category Unknown"; - (* Analyzer is a category, that describer internal Goblint issues and has no real value in a Sarif output *) - | MessageCategory.Analyzer -> "Analyzer"; - | MessageCategory.Behavior b -> getBehaviorCategory b; - (* Cast of Type Missmatch is equal to the CWE 241. If MessageCategory.Cast is just an describing an internal Goblint issue, this CWE should be removed. *) - | MessageCategory.Cast c -> "241"; - | MessageCategory.Integer i -> match i with - | Overflow -> "190"; - | DivByZero -> "369" - - - -let print_physicalLocationPiece f Messages.Piece.{loc; text = m; context=con;} = - (* The context can be important too, but at the moment displaying it's value in a useful way is hard. *) - (* for the github action removes leading ./analysistarget/ the trimFile function will most likely change a bit.*) - let trimFile (path:string) = - match String.sub path 0 17 with - | "./analysisTarget" -> Str.string_after path 17; - |_ -> path; - in - - match loc with - | None -> - BatPrintf.fprintf f ""; - | Some l -> - BatPrintf.fprintf f " \"physicalLocation\": " ; - BatPrintf.fprintf f "{\n \"artifactLocation\": {\n \"uri\":\"%s\"\n },\n" (trimFile l.file) ; - BatPrintf.fprintf f " \"region\": {\n"; - BatPrintf.fprintf f " \"startLine\":%d,\n" l.line ; - BatPrintf.fprintf f " \"startColumn\":%d\n" l.column ; - BatPrintf.fprintf f " }\n" - - -let printMultipiece f (mp:Messages.MultiPiece.t)= - - let printMessageText f Messages.Piece.{loc; text = m; _} = - BatPrintf.fprintf f "\n \"message\": {\n \"text\": \"%s\"\n }," m ; - in - let printMessages f (pieces:Messages.Piece.t list) = - let toMessage Messages.Piece.{loc; text = m; _} =m in - match pieces with - | [] -> BatPrintf.fprintf f ""; - | x::xs -> BatPrintf.fprintf f "\n \"message\": {\n"; - BatPrintf.fprintf f " \"text\": \"%s\"\n " (String.concat "; " (List.map toMessage pieces)) ; - BatPrintf.fprintf f " }\n"; - in - let rec printPieces f (pieces:Messages.Piece.t list)= match pieces with - | [] -> BatPrintf.fprintf f ""; - | x::[] -> print_physicalLocationPiece f x; - | x::xs -> print_physicalLocationPiece f x; - BatPrintf.fprintf f " },\n"; - printPieces f xs; - - in - match mp with - | Single (piece: Messages.Piece.t) -> - printMessageText f piece; - BatPrintf.fprintf f "\n \"locations\": [\n {\n "; - print_physicalLocationPiece f piece; - BatPrintf.fprintf f " }\n" ; - BatPrintf.fprintf f " }\n ]"; - | Group {group_text = n; pieces = e} -> - BatPrintf.fprintf f "\n \"locations\": [\n {\n "; - printPieces f e; - BatPrintf.fprintf f " }\n" ; - BatPrintf.fprintf f " }\n ],"; - printMessages f e - -let printSarifResults f = - - let getCWE (tag:Messages.Tag.t) = match tag with - | CWE cwe-> Some cwe; - | Category cat -> None; - in - (* if a CWE is present only the CWE is used, since using multiple ones for the same result doesn' make sense. - If only Categorys are present, all of them are displayed.*) - let printTags f (tags:Messages.Tags.t)= - match List.find_map getCWE tags with - | Some cwe -> BatPrintf.fprintf f " {\n \"ruleId\": \"%s\"," (getRuleIDOld (string_of_int cwe)); - | None -> - match tags with - | [] ->BatPrintf.fprintf f " Unexpected Error, empty tags in Messages.Tags"; - | x::xs -> match x with - | CWE cwe-> BatPrintf.fprintf f " {\n \"ruleId\": \"%s\"," (getRuleIDOld (string_of_int cwe)); - | Category cat -> BatPrintf.fprintf f " {\n \"ruleId\": \"%s\"," (getRuleIDOld (returnCategory cat) ); - - in - let printOneResult (message:Messages.Message.t )= - printTags f message.tags; - BatPrintf.fprintf f "\n \"level\": \"%s\"," (severityToLevel message.severity) ; - printMultipiece f message.multipiece; - BatPrintf.fprintf f "\n }"; - in - let rec printResults (message_table:Messages.Message.t list)= - match message_table with - [] -> BatPrintf.fprintf f "\n"; - |x::[] -> printOneResult x; - BatPrintf.fprintf f "\n"; - | x::xs ->printOneResult x; - BatPrintf.fprintf f ",\n"; - printResults xs; - in - printResults (List.rev !Messages.Table.messages_list) - - -(* creates output in the Sarif format.*) -let createSarifOutput f = - BatPrintf.fprintf f "{\n \"$schema\": \"%s\",\n " "https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.5.json"; - BatPrintf.fprintf f "\"version\": \"%s\",\n " "2.1.0"; - BatPrintf.fprintf f "\"runs\": [\n "; - BatPrintf.fprintf f "{\n "; - BatPrintf.fprintf f "\"tool\": {\n "; - BatPrintf.fprintf f "\ \"driver\": {\n "; - BatPrintf.fprintf f "\"name\": \"%s\",\n " "Goblint"; - BatPrintf.fprintf f "\"fullName\": \"%s\",\n " "Goblint static analyser"; - BatPrintf.fprintf f "\"informationUri\": \"%s\",\n " "https://goblint.in.tum.de/home"; - BatPrintf.fprintf f "\"organization\": \"%s\",\n " "TUM - i2 and UTartu - SWS"; - (* Sarif prefers numerical Versions, this could be a future addition to Goblint. *) - BatPrintf.fprintf f "\"version\": \"%s\",\n " Version.goblint; - BatPrintf.fprintf f "\"downloadUri\": \"%s\",\n " "https://github.com/goblint/analyzer"; - BatPrintf.fprintf f " \"rules\": [\n "; - printCategorieRules f ["Analyzer"; "119"; "190";"241"; "362"; "369"; "416"; "476"; "561"; "570"; "571"; "787"; "788"]; - BatPrintf.fprintf f "\n ]\n "; - BatPrintf.fprintf f " }\n "; - BatPrintf.fprintf f "},\n"; - BatPrintf.fprintf f "\ \"invocations\": [\n "; - BatPrintf.fprintf f "{\n"; - BatPrintf.fprintf f " \"commandLine\": \"%a\",\n" (BatArray.print ~first:"" ~last:"" ~sep:" " BatString.print) BatSys.argv; - BatPrintf.fprintf f " \"executionSuccessful\": %B\n " true; - BatPrintf.fprintf f " }\n"; - BatPrintf.fprintf f " ],\n" ; - BatPrintf.fprintf f " \"defaultSourceLanguage\": \"%s\",\n" "C"; - BatPrintf.fprintf f " \"results\": [\n"; - printSarifResults f; - BatPrintf.fprintf f " ]\n" ; - BatPrintf.fprintf f " }\n " ; - BatPrintf.fprintf f "]\n" ; - BatPrintf.fprintf f "}\n"; diff --git a/src/maingoblint.ml b/src/maingoblint.ml index 11d276b555..3f31f2e17a 100644 --- a/src/maingoblint.ml +++ b/src/maingoblint.ml @@ -91,17 +91,6 @@ let option_spec_list = set_bool "dbg.verbose" true; set_string "result" "sarif" in - let configure_sarifOld () = - if (get_string "outfile" = "") then - set_string "outfile" "test.sarif"; - if get_string "exp.g2html_path" = "" then - set_string "exp.g2html_path" exe_dir; - set_bool "dbg.print_dead_code" true; - set_bool "exp.cfgdot" true; - set_bool "g2html" false; - set_bool "dbg.verbose" true; - set_string "result" "sarifOld" - in let tmp_arg = ref "" in [ "-o" , Arg.String (set_string "outfile"), "" ; "-v" , Arg.Unit (fun () -> set_bool "dbg.verbose" true; set_bool "printstats" true), "" @@ -122,7 +111,6 @@ let option_spec_list = ; "--help" , Arg.Unit (fun _ -> print_help stdout),"" ; "--html" , Arg.Unit (fun _ -> configure_html ()),"" ; "--sarif" , Arg.Unit (fun _ -> configure_sarif ()),"" - ; "--sarif2" , Arg.Unit (fun _ -> configure_sarifOld ()),"" ; "--compare_runs" , Arg.Tuple [Arg.Set_string tmp_arg; Arg.String (fun x -> set_auto "compare_runs" (sprintf "['%s','%s']" !tmp_arg x))], "" ; "--oil" , Arg.String oil, "" (* ; "--tramp" , Arg.String (set_string "ana.osek.tramp"), "" *) From 2ff8c0beea807b56961fdea549ff748bc5f0f3d9 Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Sun, 10 Oct 2021 23:51:09 +0200 Subject: [PATCH 25/56] added location object to toolComponent --- src/framework/sarif.ml | 251 +++++++++++++++++++++++++++++------------ 1 file changed, 176 insertions(+), 75 deletions(-) diff --git a/src/framework/sarif.ml b/src/framework/sarif.ml index 00b4b31a5f..4655cc07ae 100644 --- a/src/framework/sarif.ml +++ b/src/framework/sarif.ml @@ -15,43 +15,91 @@ type categoryInformation = { helpUri:string; longDescription:string; } - - -let getCWEDescription (cwe:int) = match cwe with - | 570 -> ("GO0010","CWE 570:Expression is Always False", - "The software contains an expression that will always evaluate to false. ", - "https://cwe.mitre.org/data/definitions/570.html", - ""); - | 571 -> ("GO0011","CWE 571:Expression is Always True", - "The software contains an expression that will always evaluate to true. ", - "https://cwe.mitre.org/data/definitions/571.html", - ""); - | _ -> ("GO"^(string_of_int cwe),"CWE"^(string_of_int cwe), - "", - "https://cwe.mitre.org/data/definitions/"^(string_of_int cwe)^".html", - "") - -(* Given a Goblint Category - returns (Ruleid,helpText,shortDescription,helpUri,longDescription) *) -let getDescription (id:string) = match id with - |"Analyzer" -> ("GO001","Goblint Category Analyzer","","https://goblint.in.tum.de/home",""); - |"Assert" -> ("GO002","Goblint Category Assert","","https://goblint.in.tum.de/home",""); - | "362"-> ("GO005", - "CWE 362: Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')", - "The program contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently. ", - "https://cwe.mitre.org/data/definitions/362.html", - "") - | "416" -> ("GO007", - "CWE 416:Use After Free", - "Referencing memory after it has been freed can cause a program to crash, use unexpected values, or execute code. ", - "https://cwe.mitre.org/data/definitions/416.html", - "The use of previously-freed memory can have any number of adverse consequences, ranging from the corruption of valid data to the execution of arbitrary code, depending on the instantiation and timing of the flaw. " - ^"The simplest way data corruption may occur involves the system's reuse of the freed memory. Use-after-free errors have two common and sometimes overlapping causes:" - ^" Error conditions and other exceptional circumstances." - ^" Confusion over which part of the program is responsible for freeing the memory." - ^"In this scenario, the memory in question is allocated to another pointer validly at some point after it has been freed. The original pointer to the freed memory is used again and points to somewhere within the new allocation. As the data is changed, it corrupts the validly used memory; this induces undefined behavior in the process." - ^"If the newly allocated data chances to hold a class, in C++ for example, various function pointers may be scattered within the heap data. If one of these function pointers is overwritten with an address to valid shellcode, execution of arbitrary code can be achieved. "); - | "476" -> ("GO008","CWE 476:NULL Pointer Dereference", +let unknownRule = { + name="Unknown"; + ruleId="GO000"; + helpText=""; + shortDescription=""; + helpUri=""; + longDescription=""; +} + +let rules = [ + { + name="Assert"; + ruleId="GO0001"; + helpText="Assert Error"; + shortDescription="This is an internal Goblint Category"; + helpUri="https://goblint.in.tum.de/home"; + longDescription=""; + }; + { + name="Analyzer"; + ruleId="GO0002"; + helpText="Analyzer Error"; + shortDescription="This is an internal Goblint Category"; + helpUri="https://goblint.in.tum.de/home"; + longDescription=""; + }; + { + name="Cast"; + ruleId="GO0003"; + helpText="Cast Error"; + shortDescription="This is an internal Goblint Cast Error, most likely not indicating a problem in the analyzed program."; + helpUri="https://goblint.in.tum.de/home"; + longDescription=""; + }; + { + name="Deadcode"; + ruleId="GO0004"; + helpText="Deadcode"; + shortDescription="This code is never used in the program."; + helpUri="https://goblint.in.tum.de/home"; + longDescription=""; + }; + { + name="Race"; + ruleId="GO0005"; + helpText="A race condition"; + shortDescription="The program contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently. "; + helpUri="https://goblint.in.tum.de/home"; + longDescription=""; + }; + { + name="362"; + ruleId="GO005"; + helpText="Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')"; + shortDescription="The program contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently. "; + helpUri="https://cwe.mitre.org/data/definitions/362.html"; + longDescription=""; + }; + { + name="416"; + ruleId="GO007"; + helpText="Use After Free"; + shortDescription="Referencing memory after it has been freed can cause a program to crash, use unexpected values, or execute code. "; + helpUri="https://cwe.mitre.org/data/definitions/416.html"; + longDescription=""; + }; + { + name="570"; + ruleId="GO0010"; + helpText="Expression is Always False"; + shortDescription="The software contains an expression that will always evaluate to false."; + helpUri="https://cwe.mitre.org/data/definitions/570.html"; + longDescription=""; + }; + { + name="571"; + ruleId="GO0011"; + helpText="Expression is Always True"; + shortDescription="The software contains an expression that will always evaluate to true."; + helpUri="https://cwe.mitre.org/data/definitions/571.html"; + longDescription=""; + } +] +(* + | "476" -> ("GO008","CWE 476:NULL Pointer Dereference", "A NULL pointer dereference occurs when the application dereferences a pointer that it expects to be valid, but is NULL, typically causing a crash or exit. ", "https://cwe.mitre.org/data/definitions/476.html", "NULL pointer dereference issues can occur through a number of flaws, including race conditions, and simple programming omissions. "); @@ -72,12 +120,35 @@ let getDescription (id:string) = match id with "https://cwe.mitre.org/data/definitions/788.html", "This typically occurs when a pointer or its index is decremented to a position before the buffer;" ^"when pointer arithmetic results in a position before the buffer; or when a negative index is used, which generates a position before the buffer. "); - | _ -> ("GO000","Unknown Category","Unknown Category","Unknown Category","Unknown Category") +*) +let getCategoryInformation (searchName:string) = + match List.find_opt (fun rule -> rule.name=searchName) rules with + | None ->unknownRule ; + | Some rule -> rule +let getCWEDescription (cwe:int) = match cwe with + | 570 -> ("GO0010","CWE 570:Expression is Always False", + "The software contains an expression that will always evaluate to false. ", + "https://cwe.mitre.org/data/definitions/570.html", + ""); + | 571 -> ("GO0011","CWE 571:Expression is Always True", + "The software contains an expression that will always evaluate to true. ", + "https://cwe.mitre.org/data/definitions/571.html", + ""); + | _ -> ("GO"^(string_of_int cwe),"CWE"^(string_of_int cwe), + "", + "https://cwe.mitre.org/data/definitions/"^(string_of_int cwe)^".html", + "") + +(* Given a Goblint Category + returns (Ruleid,helpText,shortDescription,helpUri,longDescription) *) +let getDescription (id:string) = match id with + |"Analyzer" -> ("GO001","Goblint Category Analyzer","","https://goblint.in.tum.de/home",""); + |"Assert" -> ("GO002","Goblint Category Assert","","https://goblint.in.tum.de/home",""); + + | _ -> ("GO000","Unknown Category","Unknown Category","Unknown Category","Unknown Category") -let getRuleIDOld (id:string) = match (getDescription id ) with - | (ruleId,_,_,_,_) -> ruleId (*matches the Goblint severity to the Sarif property level.*) let severityToLevel (severity:Messages.Severity.t)= match severity with | Error -> "error" @@ -120,8 +191,16 @@ struct artifactLocation:ArtifactLocation.t; region:Region.t; - } [@@deriving to_yojson] - + } [@@deriving to_yojson] +end + +(*This type represents the Sarif locationProperty. +It is needed twice, since Sarif requires differen keys names, depending on where it is used.*) +module LocationObject = +struct type t = { + location:ArtifactLocation.t; + + } [@@deriving to_yojson] end @@ -199,6 +278,7 @@ struct tool:Tool.t; defaultSourceLanguage:string; invocations:InvocationObject.t list; + artifacts:LocationObject.t list; results:ResultObject.t list }[@@deriving to_yojson] @@ -211,20 +291,19 @@ let createMessageObject (text:String.t) = SairfMessageObject.text=text; } (*A reportingDescriptor offers a lot of information about a Goblint rule *) -let createReportingDescriptor name = - match getDescription name with - | (id,helpText,shortDescription,helpUri,longDescription) -> +let createReportingDescriptor categoryInformation = { - ReportingDescriptor.ruleId=id; - ReportingDescriptor.ruleName=name; - ReportingDescriptor.helpUri=helpUri; - ReportingDescriptor.help=(createMessageObject helpText); - ReportingDescriptor.shortDescription=(createMessageObject shortDescription); - ReportingDescriptor.fullDescription=(createMessageObject longDescription); + ReportingDescriptor.ruleId=categoryInformation.ruleId; + ReportingDescriptor.ruleName=categoryInformation.name; + ReportingDescriptor.helpUri=categoryInformation.helpUri; + ReportingDescriptor.help=(createMessageObject categoryInformation.helpText); + ReportingDescriptor.shortDescription=(createMessageObject categoryInformation.shortDescription); + ReportingDescriptor.fullDescription=(createMessageObject categoryInformation.longDescription); } + let transformToReportingDescriptor (id:String.t)= - createReportingDescriptor id - + createReportingDescriptor (getCategoryInformation id) + let (driverObject:Driver.t) = { Driver.name="Goblint"; @@ -232,7 +311,7 @@ let (driverObject:Driver.t) = Driver.informationUri="https://goblint.in.tum.de/home"; Driver.organization="TUM - i2 and UTartu - SWS"; Driver.version=Version.goblint; - Driver.rules=List.map transformToReportingDescriptor ["Analyzer";"119"] + Driver.rules=List.map transformToReportingDescriptor (List.map (fun rule -> rule.name) rules) } let (toolObject:Tool.t) = { @@ -241,7 +320,7 @@ let (toolObject:Tool.t) = (*returns the Rule corresponding to a message entry *) -let getRuleID (tags:Messages.Tags.t) = +let getCategoryInformationID (tags:Messages.Tags.t) = let getCWE (tag:Messages.Tag.t) = match tag with | CWE cwe-> Some cwe; | Category cat -> None; @@ -256,7 +335,23 @@ let getRuleID (tags:Messages.Tags.t) = |Category cat-> MessageCategory.show cat | CWE c-> "" (*this case should not be reachable *) - +let createArtifactLocationObject (uri:string) = +{ + LocationObject.location={ + ArtifactLocation.uri=uri; + } +} +let createArtifactObject (uri:string) = + { + ArtifactLocation.uri=uri; + } +let hasLocation (piece:Messages.Piece.t) = match piece.loc with + |Some loc -> true + |None -> false +(*should only be called after hasLocation*) +let deOptionalizeLocation (piece:Messages.Piece.t)= match piece.loc with + | Some loc ->loc + | None -> assert false let createPhysicalLocationObject (piece:Messages.Piece.t) = let createRegionObject (line,column)= @@ -265,28 +360,13 @@ let createPhysicalLocationObject (piece:Messages.Piece.t) = Region.startColumn=column; } in - match piece.loc with - (*This case is filtered out in hasLocation, but the compiler complains if it is not matched here. *) - | None -> { - Locations.physicalLocation={ - PhysicalLocation.artifactLocation= { - ArtifactLocation.uri="no file was provided"; - }; - PhysicalLocation.region=createRegionObject (0,0); - } - }; - | Some loc ->{ + { Locations.physicalLocation={ - PhysicalLocation.artifactLocation= { - ArtifactLocation.uri=loc.file; - }; - PhysicalLocation.region=createRegionObject (loc.line,loc.column); + PhysicalLocation.artifactLocation= createArtifactObject (deOptionalizeLocation piece).file; + PhysicalLocation.region=createRegionObject ((deOptionalizeLocation piece).line,(deOptionalizeLocation piece).column); } } -let hasLocation (piece:Messages.Piece.t) = match piece.loc with - |Some loc -> true - |None -> false let createLocationsObject (multiPiece:Messages.MultiPiece.t) = match multiPiece with | Single piece ->List.map createPhysicalLocationObject (List.filter hasLocation [piece]); @@ -300,18 +380,39 @@ let createResult (message:Messages.Message.t) = | Group {group_text = n; pieces = e} ->n in { - ResultObject.ruleId=getRuleID message.tags; + ResultObject.ruleId=(getCategoryInformation (getCategoryInformationID message.tags)).ruleId; ResultObject.level=severityToLevel message.severity; ResultObject.message=createMessageObject (getMessage message.multipiece); ResultObject.locations=createLocationsObject message.multipiece; } + +let getFileLocation (multipiece:Messages.MultiPiece.t)= + let getFile (loc:Cil.location) = + loc.file + in + let toLocation = match multipiece with + + | Single piece ->[deOptionalizeLocation piece]; + | Group {group_text = n; pieces = e} -> + List.map deOptionalizeLocation (List.filter hasLocation e); + in + List.map getFile toLocation + +let collectAllFileLocations (msgList:Messages.Message.t list)= + let getUris= + List.flatten (List.map (fun (msg:Messages.Message.t)-> getFileLocation msg.multipiece) msgList) + in + let uniques x xs = if List.mem x xs then xs else x::xs; + in + List.fold_right uniques getUris [] let runObject msgList= { Run.invocations=[{ InvocationObject.commandLine=String.concat ", " (BatArray.to_list BatSys.argv) ; InvocationObject.executionSuccessful=true; }]; + Run.artifacts= List.map createArtifactLocationObject (collectAllFileLocations msgList); Run.tool=toolObject; Run.defaultSourceLanguage="C"; Run.results=List.map createResult msgList; From 538b0a14731420679c993af89ad3e0eb6bf3a83f Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Mon, 11 Oct 2021 00:21:30 +0200 Subject: [PATCH 26/56] code cleanup --- src/framework/sarif.ml | 164 +++++++++++++++++++++++++++-------------- 1 file changed, 108 insertions(+), 56 deletions(-) diff --git a/src/framework/sarif.ml b/src/framework/sarif.ml index 4655cc07ae..81c3bc3782 100644 --- a/src/framework/sarif.ml +++ b/src/framework/sarif.ml @@ -1,8 +1,5 @@ (** The Sarif format is a standardised output format for static analysis tools. https://docs.oasis-open.org/sarif/sarif/v2.1.0/sarif-v2.1.0.html *) - -open GobConfig -module GU = Goblintutil module Category = MessageCategory @@ -64,10 +61,83 @@ let rules = [ shortDescription="The program contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently. "; helpUri="https://goblint.in.tum.de/home"; longDescription=""; + }; + { + name="Overflow"; + ruleId="GO0006"; + helpText="Integer Overflow"; + shortDescription="Result of arithmetic operation might be outside of the valid range. "; + helpUri="https://en.wikipedia.org/wiki/Integer_overflow"; + longDescription=""; + }; + { + name="DivByZero"; + ruleId="GO0007"; + helpText="Division by zero"; + shortDescription="Division by zero can result in undefined behaviour."; + helpUri="https://goblint.in.tum.de/home"; + longDescription=""; + }; + { + name="Implementation"; + ruleId="GO0008"; + (*TODO is this correct? *) + helpText="Implementation of function might not be present on all versions of the target platform."; + shortDescription=" Implementation of function might not be present on all versions of the target platform."; + helpUri=""; + longDescription=""; + }; + { + name="Machine"; + ruleId="GO0009"; + helpText="TODO"; + shortDescription="TODO "; + helpUri="https://goblint.in.tum.de/home"; + longDescription=""; + }; + { + name="NullPointerDereference"; + ruleId="GO0010"; + helpText="Nullpointer dereference"; + shortDescription="A NULL pointer dereference occurs when the application dereferences a pointer that it expects to be valid, but is NULL, typically causing a crash or exit. "; + helpUri="https://cwe.mitre.org/data/definitions/476.html"; + longDescription=""; + }; + { + name="UseAfterFree"; + ruleId="GO0011"; + helpText="TODO"; + shortDescription="TODO "; + helpUri="https://goblint.in.tum.de/home"; + longDescription=""; + }; + { + name="PastEnd"; + ruleId="GO0012"; + helpText="TODO"; + shortDescription="TODO "; + helpUri="https://goblint.in.tum.de/home"; + longDescription=""; + }; + { + name="BeforeStart"; + ruleId="GO0013"; + helpText="TODO"; + shortDescription="TODO "; + helpUri="https://goblint.in.tum.de/home"; + longDescription=""; + }; + { + name="Unknown Aob"; + ruleId="GO0014"; + helpText="Array out of Bounds Error"; + shortDescription="Array out of Bounds Error "; + helpUri="https://goblint.in.tum.de/home"; + longDescription=""; }; { name="362"; - ruleId="GO005"; + ruleId="GO015"; helpText="Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')"; shortDescription="The program contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently. "; helpUri="https://cwe.mitre.org/data/definitions/362.html"; @@ -75,15 +145,23 @@ let rules = [ }; { name="416"; - ruleId="GO007"; + ruleId="GO0016"; helpText="Use After Free"; shortDescription="Referencing memory after it has been freed can cause a program to crash, use unexpected values, or execute code. "; helpUri="https://cwe.mitre.org/data/definitions/416.html"; longDescription=""; + }; + { + name="476"; + ruleId="GO0017"; + helpText="NULL Pointer Dereference"; + shortDescription="A NULL pointer dereference occurs when the application dereferences a pointer that it expects to be valid, but is NULL, typically causing a crash or exit. "; + helpUri="https://cwe.mitre.org/data/definitions/476.html"; + longDescription=""; }; { name="570"; - ruleId="GO0010"; + ruleId="GO0018"; helpText="Expression is Always False"; shortDescription="The software contains an expression that will always evaluate to false."; helpUri="https://cwe.mitre.org/data/definitions/570.html"; @@ -91,63 +169,37 @@ let rules = [ }; { name="571"; - ruleId="GO0011"; + ruleId="GO0019"; helpText="Expression is Always True"; shortDescription="The software contains an expression that will always evaluate to true."; helpUri="https://cwe.mitre.org/data/definitions/571.html"; longDescription=""; + }; + { + name="787"; + ruleId="GO0020"; + helpText="Out-of-bounds Write"; + shortDescription="The software writes data past the end, or before the beginning, of the intended buffer. "; + helpUri="https://cwe.mitre.org/data/definitions/787.html"; + longDescription=""; + }; + { + name="788"; + ruleId="GO0021"; + helpText="Access of Memory Location After End of Buffer"; + shortDescription="The software reads or writes to a buffer using an index or pointer that references a memory location after the end of the buffer. "; + helpUri="https://cwe.mitre.org/data/definitions/788.html"; + longDescription=""; } ] -(* - | "476" -> ("GO008","CWE 476:NULL Pointer Dereference", - "A NULL pointer dereference occurs when the application dereferences a pointer that it expects to be valid, but is NULL, typically causing a crash or exit. ", - "https://cwe.mitre.org/data/definitions/476.html", - "NULL pointer dereference issues can occur through a number of flaws, including race conditions, and simple programming omissions. "); - | "561" |"DeadCode"-> ("GO009","CWE 561:Dead Code", - "The software contains dead code, which can never be executed. ", - "https://cwe.mitre.org/data/definitions/561.html", - "Dead code is source code that can never be executed in a running program. The surrounding code makes it impossible for a section of code to ever be executed. "); - - | "787" -> ("GO012", - "CWE 787: Out-of-bounds Write", - "The software writes data past the end, or before the beginning, of the intended buffer. ", - "https://cwe.mitre.org/data/definitions/787.html", - "Typically, this can result in corruption of data, a crash, or code execution. The software may modify an index or perform pointer arithmetic that references a memory location that is outside of the boundaries of the buffer. " - ^" A subsequent write operation then produces undefined or unexpected results. "); - | "788" -> ("GO013", - "CWE 788:Access of Memory Location After End of Buffer", - "The software reads or writes to a buffer using an index or pointer that references a memory location after the end of the buffer. ", - "https://cwe.mitre.org/data/definitions/788.html", - "This typically occurs when a pointer or its index is decremented to a position before the buffer;" - ^"when pointer arithmetic results in a position before the buffer; or when a negative index is used, which generates a position before the buffer. "); -*) - -let getCategoryInformation (searchName:string) = + +(*Returns the information about a Rule. If the rule is not found, a default rule will be returned. *) +let getRuleInformation (searchName:string) = match List.find_opt (fun rule -> rule.name=searchName) rules with | None ->unknownRule ; | Some rule -> rule -let getCWEDescription (cwe:int) = match cwe with - | 570 -> ("GO0010","CWE 570:Expression is Always False", - "The software contains an expression that will always evaluate to false. ", - "https://cwe.mitre.org/data/definitions/570.html", - ""); - | 571 -> ("GO0011","CWE 571:Expression is Always True", - "The software contains an expression that will always evaluate to true. ", - "https://cwe.mitre.org/data/definitions/571.html", - ""); - | _ -> ("GO"^(string_of_int cwe),"CWE"^(string_of_int cwe), - "", - "https://cwe.mitre.org/data/definitions/"^(string_of_int cwe)^".html", - "") - -(* Given a Goblint Category - returns (Ruleid,helpText,shortDescription,helpUri,longDescription) *) -let getDescription (id:string) = match id with - |"Analyzer" -> ("GO001","Goblint Category Analyzer","","https://goblint.in.tum.de/home",""); - |"Assert" -> ("GO002","Goblint Category Assert","","https://goblint.in.tum.de/home",""); - - | _ -> ("GO000","Unknown Category","Unknown Category","Unknown Category","Unknown Category") + (*matches the Goblint severity to the Sarif property level.*) let severityToLevel (severity:Messages.Severity.t)= match severity with @@ -302,7 +354,7 @@ let createReportingDescriptor categoryInformation = } let transformToReportingDescriptor (id:String.t)= - createReportingDescriptor (getCategoryInformation id) + createReportingDescriptor (getRuleInformation id) let (driverObject:Driver.t) = { @@ -375,12 +427,12 @@ let createLocationsObject (multiPiece:Messages.MultiPiece.t) = match multiPiece let createResult (message:Messages.Message.t) = - let rec getMessage (multiPiece:Messages.MultiPiece.t)= match multiPiece with + let getMessage (multiPiece:Messages.MultiPiece.t)= match multiPiece with | Single piece ->piece.text; | Group {group_text = n; pieces = e} ->n in { - ResultObject.ruleId=(getCategoryInformation (getCategoryInformationID message.tags)).ruleId; + ResultObject.ruleId=(getRuleInformation (getCategoryInformationID message.tags)).ruleId; ResultObject.level=severityToLevel message.severity; ResultObject.message=createMessageObject (getMessage message.multipiece); ResultObject.locations=createLocationsObject message.multipiece; From ce8c08d452b662dcb0a585d22a7aa05f8b2185f9 Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Mon, 11 Oct 2021 00:22:46 +0200 Subject: [PATCH 27/56] code cleanup --- src/framework/sarif.ml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/framework/sarif.ml b/src/framework/sarif.ml index 81c3bc3782..33644c13e3 100644 --- a/src/framework/sarif.ml +++ b/src/framework/sarif.ml @@ -17,7 +17,7 @@ let unknownRule = { ruleId="GO000"; helpText=""; shortDescription=""; - helpUri=""; + helpUri="https://goblint.in.tum.de/home"; longDescription=""; } @@ -84,7 +84,7 @@ let rules = [ (*TODO is this correct? *) helpText="Implementation of function might not be present on all versions of the target platform."; shortDescription=" Implementation of function might not be present on all versions of the target platform."; - helpUri=""; + helpUri="https://goblint.in.tum.de/home"; longDescription=""; }; { From d8e0ced8f0b0c5610431f325c01e2dbd109a23a5 Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Mon, 11 Oct 2021 00:25:38 +0200 Subject: [PATCH 28/56] formatting --- src/framework/control.ml | 2 +- src/framework/sarif.ml | 450 +++++++++++++++++++-------------------- 2 files changed, 226 insertions(+), 226 deletions(-) diff --git a/src/framework/control.ml b/src/framework/control.ml index 6b9b4a65a4..c89d127462 100644 --- a/src/framework/control.ml +++ b/src/framework/control.ml @@ -498,7 +498,7 @@ struct let cnt = Cilfacade.countLoc fn in uncalled_dead := !uncalled_dead + cnt; if get_bool "dbg.uncalled" then - M.warn ~loc ~category:Deadcode "Function \'%a\' will never be called: %dLoC" CilType.Fundec.pretty fn cnt + M.warn ~loc ~category:Deadcode "Function \"%a\" will never be called: %dLoC" CilType.Fundec.pretty fn cnt | _ -> () in List.iter print_and_calculate_uncalled file.globals; diff --git a/src/framework/sarif.ml b/src/framework/sarif.ml index 33644c13e3..e13ad18711 100644 --- a/src/framework/sarif.ml +++ b/src/framework/sarif.ml @@ -23,181 +23,181 @@ let unknownRule = { let rules = [ { - name="Assert"; - ruleId="GO0001"; - helpText="Assert Error"; - shortDescription="This is an internal Goblint Category"; - helpUri="https://goblint.in.tum.de/home"; - longDescription=""; + name="Assert"; + ruleId="GO0001"; + helpText="Assert Error"; + shortDescription="This is an internal Goblint Category"; + helpUri="https://goblint.in.tum.de/home"; + longDescription=""; }; { - name="Analyzer"; - ruleId="GO0002"; - helpText="Analyzer Error"; - shortDescription="This is an internal Goblint Category"; - helpUri="https://goblint.in.tum.de/home"; - longDescription=""; + name="Analyzer"; + ruleId="GO0002"; + helpText="Analyzer Error"; + shortDescription="This is an internal Goblint Category"; + helpUri="https://goblint.in.tum.de/home"; + longDescription=""; }; { - name="Cast"; - ruleId="GO0003"; - helpText="Cast Error"; - shortDescription="This is an internal Goblint Cast Error, most likely not indicating a problem in the analyzed program."; - helpUri="https://goblint.in.tum.de/home"; - longDescription=""; + name="Cast"; + ruleId="GO0003"; + helpText="Cast Error"; + shortDescription="This is an internal Goblint Cast Error, most likely not indicating a problem in the analyzed program."; + helpUri="https://goblint.in.tum.de/home"; + longDescription=""; }; { - name="Deadcode"; - ruleId="GO0004"; - helpText="Deadcode"; - shortDescription="This code is never used in the program."; - helpUri="https://goblint.in.tum.de/home"; - longDescription=""; + name="Deadcode"; + ruleId="GO0004"; + helpText="Deadcode"; + shortDescription="This code is never used in the program."; + helpUri="https://goblint.in.tum.de/home"; + longDescription=""; }; { - name="Race"; - ruleId="GO0005"; - helpText="A race condition"; - shortDescription="The program contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently. "; - helpUri="https://goblint.in.tum.de/home"; - longDescription=""; + name="Race"; + ruleId="GO0005"; + helpText="A race condition"; + shortDescription="The program contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently. "; + helpUri="https://goblint.in.tum.de/home"; + longDescription=""; }; - { - name="Overflow"; - ruleId="GO0006"; - helpText="Integer Overflow"; - shortDescription="Result of arithmetic operation might be outside of the valid range. "; - helpUri="https://en.wikipedia.org/wiki/Integer_overflow"; - longDescription=""; + { + name="Overflow"; + ruleId="GO0006"; + helpText="Integer Overflow"; + shortDescription="Result of arithmetic operation might be outside of the valid range. "; + helpUri="https://en.wikipedia.org/wiki/Integer_overflow"; + longDescription=""; }; - { - name="DivByZero"; - ruleId="GO0007"; - helpText="Division by zero"; - shortDescription="Division by zero can result in undefined behaviour."; - helpUri="https://goblint.in.tum.de/home"; - longDescription=""; + { + name="DivByZero"; + ruleId="GO0007"; + helpText="Division by zero"; + shortDescription="Division by zero can result in undefined behaviour."; + helpUri="https://goblint.in.tum.de/home"; + longDescription=""; }; - { - name="Implementation"; - ruleId="GO0008"; - (*TODO is this correct? *) - helpText="Implementation of function might not be present on all versions of the target platform."; - shortDescription=" Implementation of function might not be present on all versions of the target platform."; - helpUri="https://goblint.in.tum.de/home"; - longDescription=""; + { + name="Implementation"; + ruleId="GO0008"; + (*TODO is this correct? *) + helpText="Implementation of function might not be present on all versions of the target platform."; + shortDescription=" Implementation of function might not be present on all versions of the target platform."; + helpUri="https://goblint.in.tum.de/home"; + longDescription=""; }; - { - name="Machine"; - ruleId="GO0009"; - helpText="TODO"; - shortDescription="TODO "; - helpUri="https://goblint.in.tum.de/home"; - longDescription=""; + { + name="Machine"; + ruleId="GO0009"; + helpText="TODO"; + shortDescription="TODO "; + helpUri="https://goblint.in.tum.de/home"; + longDescription=""; }; - { - name="NullPointerDereference"; - ruleId="GO0010"; - helpText="Nullpointer dereference"; - shortDescription="A NULL pointer dereference occurs when the application dereferences a pointer that it expects to be valid, but is NULL, typically causing a crash or exit. "; - helpUri="https://cwe.mitre.org/data/definitions/476.html"; - longDescription=""; + { + name="NullPointerDereference"; + ruleId="GO0010"; + helpText="Nullpointer dereference"; + shortDescription="A NULL pointer dereference occurs when the application dereferences a pointer that it expects to be valid, but is NULL, typically causing a crash or exit. "; + helpUri="https://cwe.mitre.org/data/definitions/476.html"; + longDescription=""; }; - { - name="UseAfterFree"; - ruleId="GO0011"; - helpText="TODO"; - shortDescription="TODO "; - helpUri="https://goblint.in.tum.de/home"; - longDescription=""; + { + name="UseAfterFree"; + ruleId="GO0011"; + helpText="TODO"; + shortDescription="TODO "; + helpUri="https://goblint.in.tum.de/home"; + longDescription=""; }; - { - name="PastEnd"; - ruleId="GO0012"; - helpText="TODO"; - shortDescription="TODO "; - helpUri="https://goblint.in.tum.de/home"; - longDescription=""; + { + name="PastEnd"; + ruleId="GO0012"; + helpText="TODO"; + shortDescription="TODO "; + helpUri="https://goblint.in.tum.de/home"; + longDescription=""; }; - { - name="BeforeStart"; - ruleId="GO0013"; - helpText="TODO"; - shortDescription="TODO "; - helpUri="https://goblint.in.tum.de/home"; - longDescription=""; + { + name="BeforeStart"; + ruleId="GO0013"; + helpText="TODO"; + shortDescription="TODO "; + helpUri="https://goblint.in.tum.de/home"; + longDescription=""; }; - { - name="Unknown Aob"; - ruleId="GO0014"; - helpText="Array out of Bounds Error"; - shortDescription="Array out of Bounds Error "; - helpUri="https://goblint.in.tum.de/home"; - longDescription=""; + { + name="Unknown Aob"; + ruleId="GO0014"; + helpText="Array out of Bounds Error"; + shortDescription="Array out of Bounds Error "; + helpUri="https://goblint.in.tum.de/home"; + longDescription=""; }; { - name="362"; - ruleId="GO015"; - helpText="Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')"; - shortDescription="The program contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently. "; - helpUri="https://cwe.mitre.org/data/definitions/362.html"; - longDescription=""; + name="362"; + ruleId="GO015"; + helpText="Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')"; + shortDescription="The program contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently. "; + helpUri="https://cwe.mitre.org/data/definitions/362.html"; + longDescription=""; }; { - name="416"; - ruleId="GO0016"; - helpText="Use After Free"; - shortDescription="Referencing memory after it has been freed can cause a program to crash, use unexpected values, or execute code. "; - helpUri="https://cwe.mitre.org/data/definitions/416.html"; - longDescription=""; + name="416"; + ruleId="GO0016"; + helpText="Use After Free"; + shortDescription="Referencing memory after it has been freed can cause a program to crash, use unexpected values, or execute code. "; + helpUri="https://cwe.mitre.org/data/definitions/416.html"; + longDescription=""; }; - { - name="476"; - ruleId="GO0017"; - helpText="NULL Pointer Dereference"; - shortDescription="A NULL pointer dereference occurs when the application dereferences a pointer that it expects to be valid, but is NULL, typically causing a crash or exit. "; - helpUri="https://cwe.mitre.org/data/definitions/476.html"; - longDescription=""; + { + name="476"; + ruleId="GO0017"; + helpText="NULL Pointer Dereference"; + shortDescription="A NULL pointer dereference occurs when the application dereferences a pointer that it expects to be valid, but is NULL, typically causing a crash or exit. "; + helpUri="https://cwe.mitre.org/data/definitions/476.html"; + longDescription=""; }; { - name="570"; - ruleId="GO0018"; - helpText="Expression is Always False"; - shortDescription="The software contains an expression that will always evaluate to false."; - helpUri="https://cwe.mitre.org/data/definitions/570.html"; - longDescription=""; + name="570"; + ruleId="GO0018"; + helpText="Expression is Always False"; + shortDescription="The software contains an expression that will always evaluate to false."; + helpUri="https://cwe.mitre.org/data/definitions/570.html"; + longDescription=""; }; { - name="571"; - ruleId="GO0019"; - helpText="Expression is Always True"; - shortDescription="The software contains an expression that will always evaluate to true."; - helpUri="https://cwe.mitre.org/data/definitions/571.html"; - longDescription=""; + name="571"; + ruleId="GO0019"; + helpText="Expression is Always True"; + shortDescription="The software contains an expression that will always evaluate to true."; + helpUri="https://cwe.mitre.org/data/definitions/571.html"; + longDescription=""; }; - { - name="787"; - ruleId="GO0020"; - helpText="Out-of-bounds Write"; - shortDescription="The software writes data past the end, or before the beginning, of the intended buffer. "; - helpUri="https://cwe.mitre.org/data/definitions/787.html"; - longDescription=""; + { + name="787"; + ruleId="GO0020"; + helpText="Out-of-bounds Write"; + shortDescription="The software writes data past the end, or before the beginning, of the intended buffer. "; + helpUri="https://cwe.mitre.org/data/definitions/787.html"; + longDescription=""; }; - { - name="788"; - ruleId="GO0021"; - helpText="Access of Memory Location After End of Buffer"; - shortDescription="The software reads or writes to a buffer using an index or pointer that references a memory location after the end of the buffer. "; - helpUri="https://cwe.mitre.org/data/definitions/788.html"; - longDescription=""; + { + name="788"; + ruleId="GO0021"; + helpText="Access of Memory Location After End of Buffer"; + shortDescription="The software reads or writes to a buffer using an index or pointer that references a memory location after the end of the buffer. "; + helpUri="https://cwe.mitre.org/data/definitions/788.html"; + longDescription=""; } ] - + (*Returns the information about a Rule. If the rule is not found, a default rule will be returned. *) let getRuleInformation (searchName:string) = - match List.find_opt (fun rule -> rule.name=searchName) rules with - | None ->unknownRule ; - | Some rule -> rule + match List.find_opt (fun rule -> rule.name=searchName) rules with + | None ->unknownRule ; + | Some rule -> rule @@ -214,10 +214,10 @@ struct type t = { commandLine:string; executionSuccessful:bool; - + } [@@deriving to_yojson] - + end module Region = struct @@ -226,32 +226,32 @@ struct startColumn:int; } [@@deriving to_yojson] - + end module ArtifactLocation = struct type t = { uri:string; - + } [@@deriving to_yojson] - + end module PhysicalLocation = struct type t = { artifactLocation:ArtifactLocation.t; region:Region.t; - + } [@@deriving to_yojson] end (*This type represents the Sarif locationProperty. -It is needed twice, since Sarif requires differen keys names, depending on where it is used.*) + It is needed twice, since Sarif requires differen keys names, depending on where it is used.*) module LocationObject = struct type t = { location:ArtifactLocation.t; - + } [@@deriving to_yojson] end @@ -259,20 +259,20 @@ end module Locations = struct type t = { - + physicalLocation:PhysicalLocation.t; - + } [@@deriving to_yojson] - + end module SairfMessageObject = struct type t = { text:string; - + } [@@deriving to_yojson] - + end module ReportingDescriptor = struct @@ -286,7 +286,7 @@ struct } [@@deriving to_yojson] - + end module Driver = @@ -300,7 +300,7 @@ struct rules:ReportingDescriptor.t list } [@@deriving to_yojson] - + end module Tool = struct @@ -308,20 +308,20 @@ struct driver:Driver.t; } [@@deriving to_yojson] - + end module ResultObject = struct type t = { - ruleId:string; - level:string; - message:SairfMessageObject.t; - locations:Locations.t list; + ruleId:string; + level:string; + message:SairfMessageObject.t; + locations:Locations.t list; } [@@deriving to_yojson] - + end module Run = @@ -334,7 +334,7 @@ struct results:ResultObject.t list }[@@deriving to_yojson] - + end @@ -344,7 +344,7 @@ let createMessageObject (text:String.t) = } (*A reportingDescriptor offers a lot of information about a Goblint rule *) let createReportingDescriptor categoryInformation = - { + { ReportingDescriptor.ruleId=categoryInformation.ruleId; ReportingDescriptor.ruleName=categoryInformation.name; ReportingDescriptor.helpUri=categoryInformation.helpUri; @@ -352,22 +352,22 @@ let createReportingDescriptor categoryInformation = ReportingDescriptor.shortDescription=(createMessageObject categoryInformation.shortDescription); ReportingDescriptor.fullDescription=(createMessageObject categoryInformation.longDescription); } - + let transformToReportingDescriptor (id:String.t)= - createReportingDescriptor (getRuleInformation id) - + createReportingDescriptor (getRuleInformation id) + let (driverObject:Driver.t) = - { + { Driver.name="Goblint"; Driver.fullName= "Goblint static analyser"; Driver.informationUri="https://goblint.in.tum.de/home"; Driver.organization="TUM - i2 and UTartu - SWS"; Driver.version=Version.goblint; Driver.rules=List.map transformToReportingDescriptor (List.map (fun rule -> rule.name) rules) - } + } let (toolObject:Tool.t) = { - Tool.driver=driverObject; + Tool.driver=driverObject; } @@ -380,45 +380,45 @@ let getCategoryInformationID (tags:Messages.Tags.t) = (* if a CWE is present only the CWE is used, since using multiple ones for the same result doesn' make sense. If only Categorys are present, all of them are displayed.*) match List.find_map getCWE tags with - | Some cwe -> string_of_int cwe; - | None -> match tags with - | [] -> "" - | x::xs -> match x with - |Category cat-> MessageCategory.show cat - | CWE c-> "" (*this case should not be reachable *) + | Some cwe -> string_of_int cwe; + | None -> match tags with + | [] -> "" + | x::xs -> match x with + |Category cat-> MessageCategory.show cat + | CWE c-> "" (*this case should not be reachable *) let createArtifactLocationObject (uri:string) = -{ + { LocationObject.location={ ArtifactLocation.uri=uri; } -} + } let createArtifactObject (uri:string) = - { - ArtifactLocation.uri=uri; - } + { + ArtifactLocation.uri=uri; + } let hasLocation (piece:Messages.Piece.t) = match piece.loc with |Some loc -> true |None -> false (*should only be called after hasLocation*) let deOptionalizeLocation (piece:Messages.Piece.t)= match piece.loc with - | Some loc ->loc - | None -> assert false + | Some loc ->loc + | None -> assert false let createPhysicalLocationObject (piece:Messages.Piece.t) = - let createRegionObject (line,column)= + let createRegionObject (line,column)= { Region.startLine=line; Region.startColumn=column; } - in - { - Locations.physicalLocation={ - PhysicalLocation.artifactLocation= createArtifactObject (deOptionalizeLocation piece).file; - PhysicalLocation.region=createRegionObject ((deOptionalizeLocation piece).line,(deOptionalizeLocation piece).column); - } + in + { + Locations.physicalLocation={ + PhysicalLocation.artifactLocation= createArtifactObject (deOptionalizeLocation piece).file; + PhysicalLocation.region=createRegionObject ((deOptionalizeLocation piece).line,(deOptionalizeLocation piece).column); } - + } + let createLocationsObject (multiPiece:Messages.MultiPiece.t) = match multiPiece with | Single piece ->List.map createPhysicalLocationObject (List.filter hasLocation [piece]); @@ -431,66 +431,66 @@ let createResult (message:Messages.Message.t) = | Single piece ->piece.text; | Group {group_text = n; pieces = e} ->n in - { - ResultObject.ruleId=(getRuleInformation (getCategoryInformationID message.tags)).ruleId; - ResultObject.level=severityToLevel message.severity; - ResultObject.message=createMessageObject (getMessage message.multipiece); - ResultObject.locations=createLocationsObject message.multipiece; - } + { + ResultObject.ruleId=(getRuleInformation (getCategoryInformationID message.tags)).ruleId; + ResultObject.level=severityToLevel message.severity; + ResultObject.message=createMessageObject (getMessage message.multipiece); + ResultObject.locations=createLocationsObject message.multipiece; + } let getFileLocation (multipiece:Messages.MultiPiece.t)= - let getFile (loc:Cil.location) = - loc.file - in - let toLocation = match multipiece with + let getFile (loc:Cil.location) = + loc.file + in + let toLocation = match multipiece with | Single piece ->[deOptionalizeLocation piece]; | Group {group_text = n; pieces = e} -> - List.map deOptionalizeLocation (List.filter hasLocation e); - in - List.map getFile toLocation + List.map deOptionalizeLocation (List.filter hasLocation e); + in + List.map getFile toLocation let collectAllFileLocations (msgList:Messages.Message.t list)= - let getUris= + let getUris= List.flatten (List.map (fun (msg:Messages.Message.t)-> getFileLocation msg.multipiece) msgList) - in - let uniques x xs = if List.mem x xs then xs else x::xs; - in - List.fold_right uniques getUris [] + in + let uniques x xs = if List.mem x xs then xs else x::xs; + in + List.fold_right uniques getUris [] let runObject msgList= -{ + { Run.invocations=[{ InvocationObject.commandLine=String.concat ", " (BatArray.to_list BatSys.argv) ; InvocationObject.executionSuccessful=true; - }]; + }]; Run.artifacts= List.map createArtifactLocationObject (collectAllFileLocations msgList); Run.tool=toolObject; Run.defaultSourceLanguage="C"; Run.results=List.map createResult msgList; -} + } module SarifLog = struct type t = { - (* Sarif prefers numerical Versions, this could be a future addition to Goblint. *) - version:string; - schema :string [@key "$schema"]; - runs:Run.t list ; + (* Sarif prefers numerical Versions, this could be a future addition to Goblint. *) + version:string; + schema :string [@key "$schema"]; + runs:Run.t list ; } [@@deriving to_yojson] - + end - + module Sarif = struct type t = | SarifLog (*[@name "sarifLog"]*) - [@@deriving yojson] - let sarifObject msgList={SarifLog.version="2.1.0"; - SarifLog.schema="https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.5.json"; - SarifLog.runs=[runObject msgList] }; - + [@@deriving yojson] + let sarifObject msgList={SarifLog.version="2.1.0"; + SarifLog.schema="https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.5.json"; + SarifLog.runs=[runObject msgList] }; + end From dbdddbffed313bf5a0c423a7344eb9b7f2883999 Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Mon, 11 Oct 2021 11:08:10 +0200 Subject: [PATCH 29/56] added messageCategory toString --- src/framework/sarif.ml | 2 +- src/util/messageCategory.ml | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/framework/sarif.ml b/src/framework/sarif.ml index e13ad18711..086af1731f 100644 --- a/src/framework/sarif.ml +++ b/src/framework/sarif.ml @@ -384,7 +384,7 @@ let getCategoryInformationID (tags:Messages.Tags.t) = | None -> match tags with | [] -> "" | x::xs -> match x with - |Category cat-> MessageCategory.show cat + |Category cat-> MessageCategory.categoryName cat | CWE c-> "" (*this case should not be reachable *) let createArtifactLocationObject (uri:string) = diff --git a/src/util/messageCategory.ml b/src/util/messageCategory.ml index 37ee449fb7..2c274e81fc 100644 --- a/src/util/messageCategory.ml +++ b/src/util/messageCategory.ml @@ -179,6 +179,31 @@ let path_show e = let show x = String.concat " > " (path_show x) +let behaviorName = function + |Machine -> "Machine"; + |Implementation -> "Implementation" + |Undefined u -> match u with + |NullPointerDereference -> "NullPointerDereference" + |UseAfterFree -> "UseAfterFree" + | ArrayOutOfBounds aob -> match aob with + | PastEnd -> "PastEnd" + | BeforeStart -> "BeforeStart" + | Unknown -> "Unknown Aob" +let categoryName = function + | Assert -> "Assert" + + | Race -> "Race" + | Cast x -> "Cast" + | Deadcode -> "Deadcode" + | Unknown -> "Unknown" + | Analyzer -> "Analyzer" + + | Behavior x -> behaviorName x + | Integer x -> match x with + | Overflow -> "Overflow"; + | DivByZero -> "DivByZero" + + let from_string_list (s: string list) = match s with | [] -> Unknown From aeebcf911fa95902efad1d4165efd30a15ec175f Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Mon, 11 Oct 2021 12:52:46 +0200 Subject: [PATCH 30/56] added optional parameter -R to Goblint. This option removes the leading part of the URI in the Sarif output. This is needed for the Github action --- src/framework/sarif.ml | 15 ++++++++++----- src/maingoblint.ml | 3 +++ src/util/defaults.ml | 2 ++ 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/framework/sarif.ml b/src/framework/sarif.ml index 086af1731f..524b25daf4 100644 --- a/src/framework/sarif.ml +++ b/src/framework/sarif.ml @@ -1,5 +1,5 @@ (** The Sarif format is a standardised output format for static analysis tools. https://docs.oasis-open.org/sarif/sarif/v2.1.0/sarif-v2.1.0.html *) - +open GobConfig module Category = MessageCategory @@ -386,11 +386,17 @@ let getCategoryInformationID (tags:Messages.Tags.t) = | x::xs -> match x with |Category cat-> MessageCategory.categoryName cat | CWE c-> "" (*this case should not be reachable *) +(* for the github action. Removes leading directory.*) +let trimFile (path:string) = + let lengthRemove = (String.length (get_string "removePath")) + in + if get_string "removePath" == "" then path else + String.sub path lengthRemove ((String.length path)-lengthRemove) let createArtifactLocationObject (uri:string) = { LocationObject.location={ - ArtifactLocation.uri=uri; + ArtifactLocation.uri=trimFile uri; } } let createArtifactObject (uri:string) = @@ -414,7 +420,7 @@ let createPhysicalLocationObject (piece:Messages.Piece.t) = in { Locations.physicalLocation={ - PhysicalLocation.artifactLocation= createArtifactObject (deOptionalizeLocation piece).file; + PhysicalLocation.artifactLocation= createArtifactObject (trimFile (deOptionalizeLocation piece).file); PhysicalLocation.region=createRegionObject ((deOptionalizeLocation piece).line,(deOptionalizeLocation piece).column); } } @@ -436,8 +442,7 @@ let createResult (message:Messages.Message.t) = ResultObject.level=severityToLevel message.severity; ResultObject.message=createMessageObject (getMessage message.multipiece); ResultObject.locations=createLocationsObject message.multipiece; - } - + } let getFileLocation (multipiece:Messages.MultiPiece.t)= let getFile (loc:Cil.location) = diff --git a/src/maingoblint.ml b/src/maingoblint.ml index 3f31f2e17a..3055d357fc 100644 --- a/src/maingoblint.ml +++ b/src/maingoblint.ml @@ -83,6 +83,8 @@ let option_spec_list = let configure_sarif () = if (get_string "outfile" = "") then set_string "outfile" "test.sarif"; + if (get_string "removePath" = "") then + set_string "removePath" ""; if get_string "exp.g2html_path" = "" then set_string "exp.g2html_path" exe_dir; set_bool "dbg.print_dead_code" true; @@ -95,6 +97,7 @@ let option_spec_list = [ "-o" , Arg.String (set_string "outfile"), "" ; "-v" , Arg.Unit (fun () -> set_bool "dbg.verbose" true; set_bool "printstats" true), "" ; "-I" , Arg.String (set_string "includes[+]"), "" + ; "-R" , Arg.String (set_string "removePath"), "" ; "-IK" , Arg.String (set_string "kernel_includes[+]"), "" ; "--set" , Arg.Tuple [Arg.Set_string tmp_arg; Arg.String (fun x -> set_auto !tmp_arg x)], "" ; "--sets" , Arg.Tuple [Arg.Set_string tmp_arg; Arg.String (fun x -> prerr_endline "--sets is deprecated, use --set instead."; set_string !tmp_arg x)], "" diff --git a/src/util/defaults.ml b/src/util/defaults.ml index a59d937958..d0f0b826a5 100644 --- a/src/util/defaults.ml +++ b/src/util/defaults.ml @@ -59,6 +59,7 @@ let printAllCategories ch = (* {4 category [Std]} *) let _ = () ; reg Std "outfile" "" "File to print output to." + ; reg Std "removePath" "" "For the Sarif Github action. This removes the leading path of the Uri. This is needed, because the Github action runs in a subdirectory." ; reg Std "includes" "[]" "List of directories to include." ; reg Std "kernel_includes" "[]" "List of kernel directories to include." ; reg Std "custom_includes" "[]" "List of custom directories to include." @@ -285,6 +286,7 @@ let default_schema = {schema| { "file" : "" } , "outfile" : {} + , "removePath" : {} , "includes" : {} , "kernel_includes" : {} , "custom_includes" : {} From 7d5239447e55b585331ccbccd104c028b7828447 Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Mon, 11 Oct 2021 14:10:40 +0200 Subject: [PATCH 31/56] minor change to path of uri in Sarif --- src/framework/sarif.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/framework/sarif.ml b/src/framework/sarif.ml index 524b25daf4..05f2fafe83 100644 --- a/src/framework/sarif.ml +++ b/src/framework/sarif.ml @@ -391,7 +391,7 @@ let trimFile (path:string) = let lengthRemove = (String.length (get_string "removePath")) in if get_string "removePath" == "" then path else - String.sub path lengthRemove ((String.length path)-lengthRemove) + "./"^(String.sub path lengthRemove ((String.length path)-lengthRemove) ) let createArtifactLocationObject (uri:string) = { From 4162e279b0e259e162df2f3c63587f61080b692e Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Tue, 12 Oct 2021 00:58:07 +0200 Subject: [PATCH 32/56] added endline and endColumn --- src/framework/sarif.ml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/framework/sarif.ml b/src/framework/sarif.ml index 05f2fafe83..7bf234f46f 100644 --- a/src/framework/sarif.ml +++ b/src/framework/sarif.ml @@ -224,6 +224,8 @@ struct type t = { startLine:int; startColumn:int; + endColumn:int; + endLine:int; } [@@deriving to_yojson] @@ -416,6 +418,8 @@ let createPhysicalLocationObject (piece:Messages.Piece.t) = { Region.startLine=line; Region.startColumn=column; + Region.endLine=line+4; + Region.endColumn=column+4; } in { From aae6252020e605eba8bcbc96d9b45c1912c8ea3a Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Thu, 14 Oct 2021 21:34:55 +0200 Subject: [PATCH 33/56] added cil path --- scripts/goblintAnalysis.yml | 5 +- scripts/run/analyses.marshalled | Bin 0 -> 478 bytes scripts/run/cil.marshalled | Bin 0 -> 22262 bytes scripts/run/config.json | 1 + scripts/run/meta.json | 7 ++ scripts/run/solver.marshalled | Bin 0 -> 1965 bytes scripts/run/stats.marshalled | Bin 0 -> 228 bytes scripts/run/warnings.marshalled | Bin 0 -> 21 bytes scripts/test.sarif | 212 ++++++++++++++++++++++++++++++++ src/incremental/makefileUtil.ml | 22 +++- src/maingoblint.ml | 11 +- src/util/defaults.ml | 6 +- 12 files changed, 247 insertions(+), 17 deletions(-) create mode 100644 scripts/run/analyses.marshalled create mode 100644 scripts/run/cil.marshalled create mode 100644 scripts/run/config.json create mode 100644 scripts/run/meta.json create mode 100644 scripts/run/solver.marshalled create mode 100644 scripts/run/stats.marshalled create mode 100644 scripts/run/warnings.marshalled create mode 100644 scripts/test.sarif diff --git a/scripts/goblintAnalysis.yml b/scripts/goblintAnalysis.yml index 772eb335f9..e113dda6a9 100644 --- a/scripts/goblintAnalysis.yml +++ b/scripts/goblintAnalysis.yml @@ -37,12 +37,9 @@ jobs: uses: ocaml/setup-ocaml@v2 with: ocaml-compiler: ${{ matrix.ocaml-compiler }} - - name: PWD - run: pwd - name: Install dependencies - run: | - pwd + run: opam install . --deps-only --locked - name: Build run: | diff --git a/scripts/run/analyses.marshalled b/scripts/run/analyses.marshalled new file mode 100644 index 0000000000000000000000000000000000000000..a7142f9880a40371ccf288f54429bb9d40dfda94 GIT binary patch literal 478 zcmYjOTT+8S5X8Fx=0#bR6U0Y+MU5tEeB%a&WGk@X?qVhXUcvwV@)#b#Q#piK~4E&J_@QLQ53^Q6tJ#{4TTsrcK7i3T2sy zHWMqP%1Bw@wGoqu(>z)Lp_`jD2VUB=EJl6@3>vTiU$eCiN3)d9Hlb`SKsL>*LVD}{0&Y0N@Bjb+ literal 0 HcmV?d00001 diff --git a/scripts/run/cil.marshalled b/scripts/run/cil.marshalled new file mode 100644 index 0000000000000000000000000000000000000000..9588dfdf9445c5f41224f7d61940957012fe28aa GIT binary patch literal 22262 zcmai62b@&Z^`1BL&a^jUO*EERuwX|(MFe$_B38s63!B+x7FL$sb$2PEMzP1npkOyH zAZV;;jKP**SsTF;HCCd*5~D_A5=#{2|9$73H}|oN`Oh!Gd*CW9=~r&9Oz$_MwPDKSN=s))zX?s9{mL!n z=F?_W+WU1hv^TZ!%hvklrk2jS&dTJrx;+LB8Z^G4-|ho;ZER}q=-jn3y|dCXez%6M zh1o=6??nH)y80iMZfk0;v~OiRI`#u9WW29q+}Pe)U)NsgoYLM>R~|pUz0%Rqy};j) zV*Cw!KN8@tQ!R~C)_%d5>`_(oknb8C5gWqher zg*Md4-=tcq3tJl-gMr3Cfy$z_z1t6Jh^?xnpNEJooXE%^ZLMt$ty5Y$o144mjZkfO zn|BCC^8;x+S4-uvwWDES%yMVz@I+cmVdbaWC9R`q^{EoCsSTB?Mt zlh!h^jwVdZ--Yv<!&;>FA#44VfYYv z3b;i6Fwyi{+is;5PI6W_6|e)0MXSMv)HXRYnR0ujt}?x0V!35Pr4GSwcrCLK?=+x? z8+w|dV@rl0*X^%Ty)W=rQ`1n_a{wD*?XwLQvwdTGWqKRb6h+PwFRL@2jTtj8@xvKk z4lX@4z-uH`lqBfR@S9Uz_1J8qu=e@?$ z`F%&z1SG&Xp<5bwScEz~D&EzO!6RUBurYYZ7{m^?#&UfJkUXo!dsaNIvyDc4NigN( z)S?LEM29DD7?!|biL>8w;0`t1vR*3JP6ftV@euhUe|{Ob!wmN)htor`7Sih|5jZFp z;ob!9aKpWBIJYNUY~LF&=oY~cFcM=7_Rjx+4FC+PMXdtv;{6c_1N{pO##;NI#=s@d9mrrSYMLYhQY7@h!0;@j(60=Gco7{(s9ric z%k7=rlFU$IGA&7=JVhjvKp$o8M6a1T)6ziysR>OYv?Y!rDGfauaTw z#1Q%-K|x z-UG^H43^C?IRs2jG$scblh}r5b_N#DDU0L9d(k0}2J$3B9%;y!m$jgLt}C}sfC)~n zDvCOv2vArQOY&z1LK3h>eirW8B+4#x=wv-mVZAHKpBu{U*;*jt5s`#i5v&O?9`F=A z!OhKtH8fYs?Ep;ExlLW*uVSt%$7cl6?+`wu+MbwbYoplpB{y>vwd zitUclypF!y;$YyAs5jV5gT)q8Qx8P0b3JFyQacD{HIJ1iq##l%LD&#g*0OP;6wp?1~HbRl42 zJuArtCel@7wapF?B675pcK{UDu#&v(2lS+QW~iPINRru~>GoS-!`fAnzcK9pNN4uI zbVoSJ4+9+*v66hSw`8Qly33MFRPr;Dd`P`$nRs7nW4R<*D3~tKfLmC-O7bb=79|<1 zp5oJg$SLsxU||6($>$7)lTL%32Guz3F^78ehX|^>q_#!Hig)JsK*UpE1)?-Q&~xV zL+w*}ct?##Dh(cCohvEdcnq!`RORMr<WWeI&WevD*Ud!rE9;n;ScK1)vTQ zZa421u)}Q->LHZO0gbe+p%#?UU58fLVc^I@(~d;IGw6 z@^#g;0Xxabs{_y~?9|BybRn=7%qR|JWhAZ|SLrn(i42Y(2CmAZX ziPqEtv!t$4MHWf&MQz*)9kp?rq?jce$3On*giVkgyOGGbmt`X5aqB{>7 zEA8c`jtV@h(uQO%^@L9CaY^C91wS+`3M(&ho)OWlqT2;}fwK+R*MPA#>gd#aa!K8!3hX5*JWYZEdrN8sPzKzCT&^%; zfN_c08<#?y#PP}lA&>=_jYbIc5?2~Aq&Kw8`!h)`RVYH>7@X~yifxqC z*$#`s&P(t};5tQ>oht^+yT;?t^j%%&HxYG>p(dEbSURP54SVg;J#TbLWloFTHTWF_ z^W>w*Qw{7~Bc41#YQ?$63<9q+;PhU=m``CV_{|PDlfdf@c$NXNg`%yiDfQ$j%}lBN zk*e|K;*VCps*2C+I0K{5^Aa~05mkDzqywe~i*=R7wc>A}K%FS+JTGyhA)`VsW-?>~ zEn3Imi7&llzWD2?0ym4V;oM&&zAKCU`Q-O2CyX~oEy8Que8XEBC8!8HTv5Dh}1QCl={g-^Eq&65q#Y-$OV!5d} zw5DROYjw@t$2om9?%izoDDK6MCcPo2(Qj7S?}~qm8tQ!}Q~IID|CL%Wu8?@!v~WSU zmVVM$FFD~K61K=-AM}ES&L7tL{u>UaA@3H0{lhIw`vVr)& zqoveZf|oA5#BD}I?_IN-Gtm#WKd1m9)gU3xDXLl773 zNW~5jpI5gwd=RmB8?k3^Y-3{wOMcl{u_Hv>f(!05y~JX}Mi-hrC(BC`PIiDZ(t*U? zW4MtfGnS&oQX>HS*7mX-PT;);JoJYb1(_t3i~Qgi!gy7HEhI-7Yz^S%qLh@~tfmrjzd|awY#@BSN9^1W)d=8xjrg#x-xrQmoc0ZTKt1{=tZs3>(V~Iy%R*w6SMa@~*O2De_n4pwsyaSu8acZyAfVL^bZ@7o2On zPuQadd)Ht%ae6#N#LXCRuR7c(#64!Xj~ve2FpP#gsVEP+MJLC)6D+H#6T)K@&85eh_*)svbc9>IB zAzdK&NdxB%9NP{E#*I+m4K7Z46Ok2^suNBBn9!$;*swPg_cqjhutNKY3{@m;l-`0+ z-U^f0y!XVzqrF?wyC`^PN$*7GOz$f4XKnP8^wy3Y-b3^ftjNhOdKEEdM_go~n2+j) z^kCEtsyK)YLNf&1Ojm1J$g=$B%F_g z2_J6o*#4-ii=QUx?bH-UN_q!X{%Dc^5*osfAg|>{9B#aN##r7255N?V_C~nlhoiC8ZmKgOq6s{8>dLR3H*#@Bl$mX#CYQ$OUB#UE4r(o zRi|=ByhHgBsi*Po1%t=pU3A9t`jY>?S8tL*wg)i$bF_PpmYj zu8SNH@!m_kVZaA^*);^xx@uRb7a8U;0^c;?QU{D2Zb}Q@?7;g`_0728N+aa(!zn&P z;9EvKWx)S&7GNLB@lGx{c?q7aa1DwwC?CzAe)^88fNSL?T`%tz$OiietgXgp)fj-mkp zBCU@}(_cxN`H_v*u=tJpgvD*c7NPnpw|+N@fGh3n0U3HTbR(Q8nm%mC-+RACz<%+(nw_WHcJS zXSlUQL&PA;)@YdN!(&rFuxdu5;rj-Sq9H^^PN#33m+^B3?&9y&T02X|a|}@Xc!>{; z!FD$Bp8G^AESx_Xyg?c%ttH{#3>cM!v5O~!aEQD|MGlcPs}~!r;gV+K1fp;mTifv2 zQAQLxLNZxJ>S(P8|8CHz9>j%7G~LeA+A1C40oK`sjmBwbwo*oiNm`%2XU0hSYsV2U zyLgF@jAQh+OKkV>N?`!4->O`WmvlQlJ#zx0j^lDHxqNI~jy5aCmO*z9Z{u;FmpQVw z^)n|E_le<7G~8N}RBZXo7-xH}2mfKPwbX;KJvLTmfU0~djO;X>Oo`mNH2x%~X>@$o ze3T;VoXAe%J~Ldq;bL||EvU~JGT{!HDVgn^&@&1Cr-4s5aLiXwI6>OUs_w<{BP4SH zk)Ip#JVW+$Pkp0=?uob^x#wjB{>y-u^cJZ{Pi8&06i95n#J>%2g#p~=4L2^YvnU8^ zMS`v;?mvdR)^Ka2V&VHBVdbB>S|@p{WUf;;x=qrrXyXpa9HWi9By$|N8ADu7dWkQL zxYfA#NG%b-GB-Gd@F>npd})xo4bn3}w*Z5JFPg*>V!krW{f3Ec$gm3Zx(Vt{>9+=qZc34?YSN?6p4NCbP%=+D>F*Fj(xc04}n1c2jsUM%v(wh)fyrBSZGsEYLBVb;5p1h;NY146;TM z)6o(yr83`fS+YAxMqdKR?jjl8zuDa+tCeAPcgeiY<{d>}J&9wji6zetGzA?l#Bkx^@L2@&NZwH5GKSm7aL!d~d<+6?R_pTY&m_CELRHi;#O4iq zlwsF$A&01z-KKU3Wlth3FxUxe5sBaG5VDi1+a%dtoyZEY1;aM<#Y5w@Yh zZZ??P8#NziZJ52r;ZU@B-j56y)s${2!aaor0ScN$CS^tG{n$`ZMY%R9dS`T>EyYcPkB%-!m*t6eqy+&oJ5YSE>qvyy0!v8 zbG*Z|p7b^`d{j^NI0Lv4N9jVYkgQ(kWZ#zT@cUlpk z+&>K$n=orl9$XvggjY+J#|=VyjIFPicT4sb8avlt zvbSNZ4d0d6ZH?I3u(8YlzvKc^-)Yb7BiY|5klQD>7m?c;at}koIz5h2sEujv;I!SB zI2JNwGQ@B(HxA!V07h%`+`*F5E6v=YlIx?3bhzZGuyHt;?D`rp+Noj1S7>Y=TeLPJ zcx1G(#O+|XF@{_7Xr+TrQJamE9CIKWeFC978gYE@8EAcra~ZRy!6!&=XH~pOaxPfr zG+6FrT%us@~0}goBu3~3N z_CZyDw&c#$#+6)M{gA;da@)}R+rO!f>up(9@8Jm5x3 z+ucyto3z+piNG&w+RJ$9F!pjN#9pg2xlM96sM{-s^ZmM@I!eq0+w;vJ)=5_$NJ@T3hf}GW0Wi z82&m)Zs7m_7fYI28k(n!uXOYa8SXaG^Nt-wt@lxhONaR>&l@|e>z04&A1m2*a+$xg z4I;BH9g!RR{|jMR+|jSSGQqU$H+b-_om21|!=`d`NAEw3;(5;wqY6V*g;JMF-gB-q$Rs0PO zZC|VZ!oBg;=B4W5P3lfb*hfZ`mLBA9<0WNe=>Wi@p^ue_A5rRh_E0wZ8)~(EMwBG) zmzIw8_x6&z3@?oWa$a=}#`rDr(xd#6m)w8&fu$}VSwI(m{y(zI$2s=`-zx;$1J_iB zm_z)-z2s&iOC!2`oUNfk{(7b1T|RySftUL5&wl)8I4shITC~eQ6#w8qh0@Z|{>h&A zui+rp>EdgDUH;H6e}__abeDfjmp=wWyZnv1{B62?a0j}7$)5z9E%m%U*#wM_cKBH= z`NO-ak{>Ji`ceth9;60IzQTT-{O^O#eJJ^fX#bn-FC`CFp#DngJ;}Ey^+!_AOa4@L zJxyYndgygRwF^I%I zlD}TZ_A!!w8SRtUu9H0O zCKR><>76CdM_y#J4(atJzk)Qr$gIK_nbneiN2&ji`bzTevg=b4pG*D&5+9QISn{}@ z2lWc6*CdbA5Y#eK&q@9>5=%)uE_vS0g8VhfJ0$-Fi5p1VB>At=Uc~mVCC_U+e(=>5 z{A#Y`zps5Wo!^`;fv5d#q&g(_0Wz6 zZ5T@1hh6(hfZ`3E{YVXvK(l|)8AaSMyqqM7@R7HY=Ox8%!qa`>LBe})WM@uj! zl)ER%y(Ks@B!5D3GYO6{q)$2{0jj{oe3hk&Cyo-FNMa?4_azvI_9twACPA4neDKwH zelpUp2P(teksADXjj?3Qi3Ox;V($dl;9~2 zw{<2;2Kfp@5D8{i3j`6xIy~7P6!RDQsZK;4^#? z{7VWyUMv9}AXp^@-1&fdm(&MRz(oou&MkOb3R{ri0TC>f!q#ZN$o9)p*p?mi{NNEO z^aYU|3?eyHl6#{)lx_Sn6X_g=(eZ=1QeYiInvps4K%zWioVXtG|OeEEzNnjs>$0z~c|DYPz@JkR)iS_`I0kaOp@%KIVC^Glpf4;DDo~z{4tg0Ev-O;9-?ya*=#|=_pD5 z(eqa7;J)nNNeY@wZA4-dDRiq;E>IQ=^faJ&poWNyJ+%yN?x_s+)N|~3m&6BBc#)XQ z+oV=X;pK2v8Ln3b>-8!-?EurDMeg=p=%bYE2OxyQZ!roaw+b{E_!}?rWE^=m_g!9DI#S8RVFoFiYUcF9Zc#l zDKcj|iS0Tmve0DT=A^e2&M-|ArC}n?nl>S^xfDmSr$Ay|DISD24+Eq@#Y52{Ji5}J z6vv<=8gwK(=ufgrib$3~(Ix_$gcs)cg87QPCq>PcmXUZ)isPsgKNzrp-z}12nZz|D zu9qV7rTJ_xl;Q*(HkZ^jQbfLl0Ek$v^)~}{ipdKu79@3{=hfpC6we!sFK{W6x&T8j ztqq-pA5}*~FN=omZ9^}G#B(U)d?_NIlFQkiEk)*2ssQaSu)AhdQb(#@isxwGa8jeB zcz!r^dy+d!@gh!%9w_iY&8dW@6WI51^l-zW`G-60~_x;dhnAhqQ;g(H|^DW>WqxB(TvQ q<;3^}J;{eBJ%Kh88NaU-pVA&~JY<8#XO-g4L;6=_I)#syO#B}tq)kWw literal 0 HcmV?d00001 diff --git a/scripts/run/config.json b/scripts/run/config.json new file mode 100644 index 0000000000..cad618748c --- /dev/null +++ b/scripts/run/config.json @@ -0,0 +1 @@ +{"ana":{"path_sens":["OSEK","OSEK2","mutex","malloc_null","uninit","apron"],"context":{"widen":false},"apron":{"context":true},"base":{"context":{"interval":true,"int":true,"non-ptr":true}},"arrayoob":false,"wp":false,"specification":"","sv-comp":{"functions":false,"enabled":false},"mutex":{"disjoint_types":true},"opt":{"equal":true,"hashcons":true},"arinc":{"merge_globals":false,"export":true,"validate":true,"simplify":true,"assume_success":true},"pml":{"debug":true},"spec":{"file":""},"file":{"optimistic":false},"int":{"refinement":"never","congruence":false,"enums":false,"interval":false,"def_exc":true},"osek":{"def_header":true,"flags":[],"safe_isr":[],"safe_task":[],"safe_vars":[],"warnfiles":false,"names":[],"check":false,"intrpts":false,"tasksuffix":"","isrsuffix":"","taskprefix":"function_of_","isrprefix":"function_of_","defaults":true,"oil":""},"cont":{"class":"","localclass":false},"ctx_insens":["OSEK2","stack_loc","stack_trace_set"],"activated":["expRelation","base","threadid","threadflag","threadreturn","escape","mutex","mallocWrapper"]},"outfile":"/home/alex/Documents/git/analyzer/testResults/99-tutorials/02-first-extend.sarif","result":"sarif","warn_at":"early","warn":{"race":true,"success":true,"debug":true,"info":true,"warning":true,"error":true,"unknown":true,"analyzer":true,"deadcode":true,"cast":true,"integer":true,"behavior":true,"assert":true},"gobview":true,"dbg":{"verbose":true,"print_dead_code":true,"cfg":{"loop-clusters":false},"cilcfgdot":false,"test":{"domain":false},"regression":false,"warn_with_context":false,"limit":{"widen":0},"slice":{"n":10,"on":false},"print_wpoints":false,"solver-progress":false,"backtrace-signal":"sigusr2","solver-signal":"sigusr1","solver-stats-interval":10,"timeout":"0","cilout":"","dump":"","uncalled":true,"showtemps":false,"trace":{"context":false},"debug":false},"g2html":false,"exp":{"cfgdot":true,"gcc_path":"/usr/bin/gcc","partition-arrays":{"smart-join":false,"partition-by-const-on-return":false,"keep-expr":"first","enabled":false},"architecture":"64bit","witness":{"stack":true,"uncil":false,"minimize":false,"invariant":{"nodes":"all"},"id":"node","path":"witness.graphml"},"ptr-arith-safe":false,"uninit-ptr-safe":false,"fast_global_inits":true,"solver":{"slr4":{"restart_count":1},"td3":{"space_restore":true,"space_cache":true,"space":false,"side_widen":"sides","term":true}},"basic-blocks":false,"no-narrow":false,"extraspecials":[],"g2html_path":".","list-type":false,"precious_globs":[],"globs_are_top":false,"single-threaded":false,"volatiles_are_top":true,"malloc":{"wrappers":["kmalloc","__kmalloc","usb_alloc_urb","__builtin_alloca","kzalloc"],"fail":false},"forward":false,"unique":[],"region-offsets":false,"failing-locks":false,"earlyglobs":false,"mincfg":false,"apron":{"privatization":"mutex-meet"},"priv-distr-init":false,"priv-prec-dump":"","privatization":"protection-read","lower-constants":true},"trans":{"expeval":{"query_file_name":""},"activated":[]},"sem":{"int":{"signed_overflow":"assume_top"},"builtin_unreachable":{"dead_code":false},"unknown_function":{"invalidate":{"globals":true},"spawn":true}},"incremental":{"wpoint":false,"stable":true,"save":false,"load":false},"compare_runs":[],"load_run":"","save_run":"","phases":[],"interact":{"paused":false,"enabled":false,"out":"result"},"colors":"auto","nonstatic":false,"allfuns":false,"solverdiffs":false,"comparesolver":"","solver":"td3","dump_globs":false,"kernel":false,"cppflags":"","tempDir":"","keepcpp":false,"allglobs":false,"otherfun":[],"exitfun":[],"mainfun":["main"],"verify":true,"printstats":false,"justcfg":false,"justcil":false,"custom_libc":false,"custom_incl":"","custom_includes":[],"kernel_includes":[],"includes":[]} \ No newline at end of file diff --git a/scripts/run/meta.json b/scripts/run/meta.json new file mode 100644 index 0000000000..3271bc3a3c --- /dev/null +++ b/scripts/run/meta.json @@ -0,0 +1,7 @@ +{ + "command": + "../goblint --sarif -o /home/alex/Documents/git/analyzer/testResults/99-tutorials/02-first-extend.sarif /home/alex/Documents/git/analyzer/tests/regression/99-tutorials/02-first-extend.c", + "version": "heads/integrationSarif-0-g8c1794b4-dirty", + "timestamp": 1633641073.0, + "localtime": "2021-10-07 23:11:13" +} \ No newline at end of file diff --git a/scripts/run/solver.marshalled b/scripts/run/solver.marshalled new file mode 100644 index 0000000000000000000000000000000000000000..ace7fb80d6591c484f3ac5a3b6546d7cdbaec264 GIT binary patch literal 1965 zcmchYQEU`N7{_OJzq8jUh@pXKwWWz#LoG`oM%$v!_V%u&LKCPEc@VgiZMpWkhqrg$ z(Ff9pCM3SNl<-g=yMv?$>Leel6p&u?z`%7U%b7bm&f znaO;?W_Rq^$+L`AO)$paW9*@K>30C#&M;FL6AQEgIz{2&=i&%DVa8r!&&F-r zOlKw?nk}p~^9RzVZ6{LJ3B!wy=)%>jH){J+!=@Hbnt9Dg^<{@mD`RT|iHsJv;>m*} zW?D;FeaY-T)7HEV*X`$gXUq|tx6wwr5ID7^lCvQX56j)%X!W)SZ=5l0%9S<;d@`-I zwK~*Xzov>?M$X$ug%I9URB-8Ir79z^c(7}~ZRCFM0AiNdi zGQu+IJw?p)ct*Hgu$lAUA~a}3SS@oQ)Cf^P+$|7yDNNL55&KC*o8@{F8EBmj)kucNXr_WC^$Ra@#C zNAT#%(SkSS(z=D|ibVlqsIV8$PoqnufBf|4An9~a9&n`v`c<-m4WYyC#e)2zxE=_q z_kucnC)CnkzcyW3W=&Pd%SO!`Gw%rKg#9lv$(^n0@*38^vbKszQ_4+N(HO)ZtX#m^ z|Ez)Bnph|Z+M&&NCZMu&@3%dB!!QB|A&+Q4E+7Yzh`lgG$a+j|YB;khH+`FV3S=!E zxdVr&u6{)Lh-#5~rxCtJ_(3>b2?`EN%b8;=-p~vd&B7+)|0G^RAz~VxB@dlL^|bhNQZc6 z35?!XWqb7X9ou`n7lX@6Ygmbu9HG)RRmNwpgk@^FMe}z#puzFpLFyA9*4>_)VWd>P un*>~jucVGkK^@al$3?kWkGi~D-?Q=f4MwB8jk8f#Ec!9LyY7GJ5z61OdB7?F literal 0 HcmV?d00001 diff --git a/scripts/run/stats.marshalled b/scripts/run/stats.marshalled new file mode 100644 index 0000000000000000000000000000000000000000..e15e4fcec2b769355273b09b3190f44826f8a75a GIT binary patch literal 228 zcmZpfx@;c<1H%O%mIvYnAkJHGKsCfa#LX~1qU<|^Ad9^i!+N^Sb#kB;{2Sl z%)E3ShN&Ol8|(Sl1I4t1^<46E^->E<6LWYNK5Sj^{n!CJ2M3^xPI^v$QesYgW?p7V zF%JWy@%@ATe;`tN$@zI@sYN9UCHV@@o<2MYAKji!w70MaX;UpoEGkarY4ABHm42BK tDCEGwz~I6Fb`{SK14l4pMhrKEk#Jqg(Zzv@fg^#z1*jARz#N7m2LM+AMeqOs literal 0 HcmV?d00001 diff --git a/scripts/run/warnings.marshalled b/scripts/run/warnings.marshalled new file mode 100644 index 0000000000000000000000000000000000000000..66fc919b0b1cbee7c212bd929f4bfbdb094ab1ca GIT binary patch literal 21 TcmZpfx@;c<0|O%v!+`?;Fo^=c literal 0 HcmV?d00001 diff --git a/scripts/test.sarif b/scripts/test.sarif new file mode 100644 index 0000000000..e72aadb4cb --- /dev/null +++ b/scripts/test.sarif @@ -0,0 +1,212 @@ +{ + "$schema": "https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.5.json", + "version": "2.1.0", + "runs": [ + { + "tool": { + "driver": { + "name": "Goblint", + "fullName": "Goblint static analyser", + "informationUri": "https://goblint.in.tum.de/home", + "organization": "TUM - i2 and UTartu - SWS", + "version": "heads/integrationSarif-0-g8c1794b4-dirty", + "downloadUri": "https://github.com/goblint/analyzer", + "rules": [ + { + "id": "GO001", + "name": "", + "helpUri": "https://goblint.in.tum.de/home", + "help": { + "text": "The category analyser describes ...." + }, + "shortDescription": { + "text": "" + }, + "fullDescription": { + "text": "" + } + }, + { + "id": "GO002", + "name": "CWE119 ", + "helpUri": "https://cwe.mitre.org/data/definitions/119.html", + "help": { + "text": "CWE 119:Improper Restriction of Operations within the Bounds of a Memory Buffer" + }, + "shortDescription": { + "text": "CWE119 " + }, + "fullDescription": { + "text": "The software performs operations on a memory buffer, but it can read from or write to a memory location that is outside of the intended boundary of the buffer." + } + }, + { + "id": "GO003", + "name": "Integer Overflow or Wraparound", + "helpUri": "https://cwe.mitre.org/data/definitions/190.html", + "help": { + "text": "The software performs a calculation that can produce an integer overflow or wraparound, when the logic assumes that the resulting value will always be larger than the original value.This can introduce other weaknesses when the calculation is used for resource management or execution control. " + }, + "shortDescription": { + "text": "Integer Overflow or Wraparound" + }, + "fullDescription": { + "text": "An integer overflow or wraparound occurs when an integer value is incremented to a value that is too large to store in the associated representation. When this occurs, the value may wrap to become a very small or negative number. While this may be intended behavior in circumstances that rely on wrapping, it can have security consequences if the wrap is unexpected. This is especially the case if the integer overflow can be triggered using user-supplied inputs. This becomes security-critical when the result is used to control looping, make a security decision, or determine the offset or size in behaviors such as memory allocation, copying, concatenation, etc. " + } + }, + { + "id": "GO004", + "name": "The software does not handle or incorrectly handles when a particular element is not the expected type, e.g. it expects a digit (0-9) but is provided with a letter (A-Z). ", + "helpUri": "https://cwe.mitre.org/data/definitions/241.html", + "help": { + "text": "CWE 241:Improper Handling of Unexpected Data Type" + }, + "shortDescription": { + "text": "The software does not handle or incorrectly handles when a particular element is not the expected type, e.g. it expects a digit (0-9) but is provided with a letter (A-Z). " + }, + "fullDescription": { + "text": "" + } + }, + { + "id": "GO005", + "name": "The program contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently. ", + "helpUri": "https://cwe.mitre.org/data/definitions/362.html", + "help": { + "text": "CWE 362: Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')" + }, + "shortDescription": { + "text": "The program contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently. " + }, + "fullDescription": { + "text": "" + } + }, + { + "id": "GO006", + "name": "The product divides a value by zero. ", + "helpUri": "https://cwe.mitre.org/data/definitions/369.html", + "help": { + "text": "CWE 369: Divide By Zero" + }, + "shortDescription": { + "text": "The product divides a value by zero. " + }, + "fullDescription": { + "text": "This weakness typically occurs when an unexpected value is provided to the product, or if an error occurs that is not properly detected. It frequently occurs in calculations involving physical dimensions such as size, length, width, and height. " + } + }, + { + "id": "GO007", + "name": "Referencing memory after it has been freed can cause a program to crash, use unexpected values, or execute code. ", + "helpUri": "https://cwe.mitre.org/data/definitions/416.html", + "help": { + "text": "CWE 416:Use After Free" + }, + "shortDescription": { + "text": "Referencing memory after it has been freed can cause a program to crash, use unexpected values, or execute code. " + }, + "fullDescription": { + "text": "The use of previously-freed memory can have any number of adverse consequences, ranging from the corruption of valid data to the execution of arbitrary code, depending on the instantiation and timing of the flaw. The simplest way data corruption may occur involves the system's reuse of the freed memory. Use-after-free errors have two common and sometimes overlapping causes: Error conditions and other exceptional circumstances. Confusion over which part of the program is responsible for freeing the memory.In this scenario, the memory in question is allocated to another pointer validly at some point after it has been freed. The original pointer to the freed memory is used again and points to somewhere within the new allocation. As the data is changed, it corrupts the validly used memory; this induces undefined behavior in the process.If the newly allocated data chances to hold a class, in C++ for example, various function pointers may be scattered within the heap data. If one of these function pointers is overwritten with an address to valid shellcode, execution of arbitrary code can be achieved. " + } + }, + { + "id": "GO008", + "name": "A NULL pointer dereference occurs when the application dereferences a pointer that it expects to be valid, but is NULL, typically causing a crash or exit. ", + "helpUri": "https://cwe.mitre.org/data/definitions/476.html", + "help": { + "text": "CWE 476:NULL Pointer Dereference" + }, + "shortDescription": { + "text": "A NULL pointer dereference occurs when the application dereferences a pointer that it expects to be valid, but is NULL, typically causing a crash or exit. " + }, + "fullDescription": { + "text": "NULL pointer dereference issues can occur through a number of flaws, including race conditions, and simple programming omissions. " + } + }, + { + "id": "GO009", + "name": "The software contains dead code, which can never be executed. ", + "helpUri": "https://cwe.mitre.org/data/definitions/561.html", + "help": { + "text": "CWE 561:Dead Code" + }, + "shortDescription": { + "text": "The software contains dead code, which can never be executed. " + }, + "fullDescription": { + "text": "Dead code is source code that can never be executed in a running program. The surrounding code makes it impossible for a section of code to ever be executed. " + } + }, + { + "id": "GO0010", + "name": "The software contains an expression that will always evaluate to false. ", + "helpUri": "https://cwe.mitre.org/data/definitions/570.html", + "help": { + "text": "CWE 570:Expression is Always False" + }, + "shortDescription": { + "text": "The software contains an expression that will always evaluate to false. " + }, + "fullDescription": { + "text": "" + } + }, + { + "id": "GO0011", + "name": "The software contains an expression that will always evaluate to true. ", + "helpUri": "https://cwe.mitre.org/data/definitions/571.html", + "help": { + "text": "CWE 571:Expression is Always True" + }, + "shortDescription": { + "text": "The software contains an expression that will always evaluate to true. " + }, + "fullDescription": { + "text": "" + } + }, + { + "id": "GO012", + "name": "The software writes data past the end, or before the beginning, of the intended buffer. ", + "helpUri": "https://cwe.mitre.org/data/definitions/787.html", + "help": { + "text": "CWE 787: Out-of-bounds Write" + }, + "shortDescription": { + "text": "The software writes data past the end, or before the beginning, of the intended buffer. " + }, + "fullDescription": { + "text": "Typically, this can result in corruption of data, a crash, or code execution. The software may modify an index or perform pointer arithmetic that references a memory location that is outside of the boundaries of the buffer. A subsequent write operation then produces undefined or unexpected results. " + } + }, + { + "id": "GO013", + "name": "The software reads or writes to a buffer using an index or pointer that references a memory location after the end of the buffer. ", + "helpUri": "https://cwe.mitre.org/data/definitions/788.html", + "help": { + "text": "CWE 788:Access of Memory Location After End of Buffer" + }, + "shortDescription": { + "text": "The software reads or writes to a buffer using an index or pointer that references a memory location after the end of the buffer. " + }, + "fullDescription": { + "text": "This typically occurs when a pointer or its index is decremented to a position before the buffer;when pointer arithmetic results in a position before the buffer; or when a negative index is used, which generates a position before the buffer. " + } + } + ] + } + }, + "invocations": [ + { + "commandLine": "../goblint --sarif -o test.sarif ../tests/regression/02-base/02-simple_assignments.c", + "executionSuccessful": true + } + ], + "defaultSourceLanguage": "C", + "results": [ + + ] + } + ] +} diff --git a/src/incremental/makefileUtil.ml b/src/incremental/makefileUtil.ml index 4c123e00c3..d0b48c5ffc 100644 --- a/src/incremental/makefileUtil.ml +++ b/src/incremental/makefileUtil.ml @@ -6,10 +6,12 @@ let buff_size = 1024 let comb_suffix = "_comb.c" let exec_command ?path (command: string) = + print_string ("command = "^command); let current_dir = Sys.getcwd () in (match path with | Some path -> - if Sys.file_exists path && Sys.is_directory path then Sys.chdir path + print_string ("path = "^path); + if Sys.file_exists path && Sys.is_directory path then Sys.chdir path else failwith ("Directory " ^ path ^ " does not exist!") | None -> ()); if GobConfig.get_bool "dbg.verbose" then print_endline ("executing command `" ^ command ^ "` in " ^ Sys.getcwd ()); @@ -18,7 +20,7 @@ let exec_command ?path (command: string) = try while true do let line = input_char std_out in - Buffer.add_char output line + Buffer.add_char output line done; assert false; with End_of_file -> @@ -34,6 +36,9 @@ let string_of_process_status = function (* BFS for a file with a given suffix in a directory or any subdirectoy *) let find_file_by_suffix (dir: string) (file_name_suffix: string) = + + (*print_string ("find_file_by_suffix dir "^dir^"\n"); + print_string ("find_file_by_suffix file_name_suffix "^file_name_suffix^"\n");*) let list_files d = Array.to_list @@ Sys.readdir d in let dirs = Queue.create () in let rec search (dir: string) (files: string list) = match files with @@ -47,11 +52,12 @@ let find_file_by_suffix (dir: string) (file_name_suffix: string) = in search dir (list_files dir) -let run_cilly (path: string) = +let run_cilly (path: string) = + if Sys.file_exists path && Sys.is_directory path then ( (* We need to `make clean` if `make` was run manually, otherwise it would say there is nothing to do and cilly would not be run and no combined C file would be created. *) let _ = exec_command ~path "make clean" in - (try + (try while true do let comb = find_file_by_suffix path comb_suffix in if GobConfig.get_bool "dbg.verbose" then print_endline ("deleting " ^ comb); @@ -60,10 +66,14 @@ let run_cilly (path: string) = with Failure e -> ()); (* Deleted all *_comb.c files in the directory *) (* Combine source files with make using cilly as compiler *) let gcc_path = GobConfig.get_string "exp.gcc_path" in + let command = ("make CC=\"cilly --gcc=" ^ gcc_path ^ " --merge --keepmerged\" " ^ + "LD=\"cilly --gcc=" ^ gcc_path ^ " --merge --keepmerged\"") in + print_string ("command = "^ command^"\n"); let (exit_code, output) = exec_command ~path ("make CC=\"cilly --gcc=" ^ gcc_path ^ " --merge --keepmerged\" " ^ "LD=\"cilly --gcc=" ^ gcc_path ^ " --merge --keepmerged\"") in - print_string output; + (* fail if make failed *) - if exit_code <> WEXITED 0 then + if exit_code <> WEXITED 0 then failwith ("Failed combining files. Make " ^ (string_of_process_status exit_code) ^ ".") + ) diff --git a/src/maingoblint.ml b/src/maingoblint.ml index 3055d357fc..09e4cd4b6f 100644 --- a/src/maingoblint.ml +++ b/src/maingoblint.ml @@ -83,10 +83,8 @@ let option_spec_list = let configure_sarif () = if (get_string "outfile" = "") then set_string "outfile" "test.sarif"; - if (get_string "removePath" = "") then - set_string "removePath" ""; - if get_string "exp.g2html_path" = "" then - set_string "exp.g2html_path" exe_dir; + if get_string "makeFilePath" = "" then + set_string "makeFilePath" ""; set_bool "dbg.print_dead_code" true; set_bool "exp.cfgdot" true; set_bool "g2html" false; @@ -98,6 +96,7 @@ let option_spec_list = ; "-v" , Arg.Unit (fun () -> set_bool "dbg.verbose" true; set_bool "printstats" true), "" ; "-I" , Arg.String (set_string "includes[+]"), "" ; "-R" , Arg.String (set_string "removePath"), "" + ; "-C" , Arg.String (set_string "makeFilePath"), "" ; "-IK" , Arg.String (set_string "kernel_includes[+]"), "" ; "--set" , Arg.Tuple [Arg.Set_string tmp_arg; Arg.String (fun x -> set_auto !tmp_arg x)], "" ; "--sets" , Arg.Tuple [Arg.Set_string tmp_arg; Arg.String (fun x -> prerr_endline "--sets is deprecated, use --set instead."; set_string !tmp_arg x)], "" @@ -214,13 +213,14 @@ let preprocess_files () = (* reverse the files again *) cFileNames := List.rev !cFileNames; - + (* If the first file given is a Makefile, we use it to combine files *) if List.length !cFileNames >= 1 then ( let firstFile = List.first !cFileNames in if Filename.basename firstFile = "Makefile" then ( let makefile = firstFile in let path = Filename.dirname makefile in + printf "Path of makefile: %s\n\n%!" path; (* make sure the Makefile exists or try to generate it *) if not (Sys.file_exists makefile) then ( print_endline ("Given " ^ makefile ^ " does not exist!"); @@ -233,6 +233,7 @@ let preprocess_files () = ) else failwith ("Could neither find given " ^ makefile ^ " nor " ^ configure ^ " - abort!") ); let _ = MakefileUtil.run_cilly path in + let file = MakefileUtil.(find_file_by_suffix path comb_suffix) in cFileNames := file :: (List.drop 1 !cFileNames); ); diff --git a/src/util/defaults.ml b/src/util/defaults.ml index d0f0b826a5..d02676cf58 100644 --- a/src/util/defaults.ml +++ b/src/util/defaults.ml @@ -60,6 +60,7 @@ let printAllCategories ch = let _ = () ; reg Std "outfile" "" "File to print output to." ; reg Std "removePath" "" "For the Sarif Github action. This removes the leading path of the Uri. This is needed, because the Github action runs in a subdirectory." + ; reg Std "makeFilePath" "" "Path to the makeFile. Needed for the Github action" ; reg Std "includes" "[]" "List of directories to include." ; reg Std "kernel_includes" "[]" "List of kernel directories to include." ; reg Std "custom_includes" "[]" "List of custom directories to include." @@ -286,7 +287,8 @@ let default_schema = {schema| { "file" : "" } , "outfile" : {} - , "removePath" : {} + , "removePath" : {} + , "makeFilePath" : {} , "includes" : {} , "kernel_includes" : {} , "custom_includes" : {} @@ -295,7 +297,7 @@ let default_schema = {schema| , "justcil" : {} , "justcfg" : {} , "printstats" : {} - , "verify" : {} + , "verify" : {} , "mainfun" : {} , "exitfun" : {} , "otherfun" : {} From 12532032f02eeebc2ab22ec76383059b09fcc5a5 Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Fri, 15 Oct 2021 01:39:48 +0200 Subject: [PATCH 34/56] added firstElements function --- src/util/goblintutil.ml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/util/goblintutil.ml b/src/util/goblintutil.ml index 8f909aa95e..93cf188613 100644 --- a/src/util/goblintutil.ml +++ b/src/util/goblintutil.ml @@ -424,3 +424,8 @@ let assoc_eq (x: 'a) (ys: ('a * 'b) list) (eq: 'a -> 'a -> bool): ('b option) = Option.map Batteries.Tuple2.second (List.find_opt (fun (x',_) -> eq x x') ys) let dummy_obj = Obj.repr () + +(*returns the first n elements of a list. *) +let rec firstElems n li = match li with + | [] -> []; + | x::xs -> if n=1 then [x] else firstElems (n-1) xs; \ No newline at end of file From d09d8db9ab66600c01fd85a7700b106926d43dde Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Fri, 15 Oct 2021 01:46:47 +0200 Subject: [PATCH 35/56] added maximum to locations of result object --- src/framework/sarif.ml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/framework/sarif.ml b/src/framework/sarif.ml index 7bf234f46f..a389cfd8f7 100644 --- a/src/framework/sarif.ml +++ b/src/framework/sarif.ml @@ -1,7 +1,7 @@ (** The Sarif format is a standardised output format for static analysis tools. https://docs.oasis-open.org/sarif/sarif/v2.1.0/sarif-v2.1.0.html *) open GobConfig module Category = MessageCategory - +module GU = Goblintutil type categoryInformation = { @@ -340,6 +340,7 @@ struct end + let createMessageObject (text:String.t) = { SairfMessageObject.text=text; @@ -388,6 +389,7 @@ let getCategoryInformationID (tags:Messages.Tags.t) = | x::xs -> match x with |Category cat-> MessageCategory.categoryName cat | CWE c-> "" (*this case should not be reachable *) + (* for the github action. Removes leading directory.*) let trimFile (path:string) = let lengthRemove = (String.length (get_string "removePath")) @@ -432,7 +434,7 @@ let createPhysicalLocationObject (piece:Messages.Piece.t) = let createLocationsObject (multiPiece:Messages.MultiPiece.t) = match multiPiece with | Single piece ->List.map createPhysicalLocationObject (List.filter hasLocation [piece]); - | Group {group_text = n; pieces = e} ->List.map createPhysicalLocationObject (List.filter hasLocation e) + | Group {group_text = n; pieces = e} ->List.map createPhysicalLocationObject (GU.firstElems 10 (List.filter hasLocation e)) @@ -476,7 +478,7 @@ let runObject msgList= Run.artifacts= List.map createArtifactLocationObject (collectAllFileLocations msgList); Run.tool=toolObject; Run.defaultSourceLanguage="C"; - Run.results=List.map createResult msgList; + Run.results=List.map createResult (GU.firstElems 5000 msgList); } module SarifLog = struct From 9779187b01f69f8ac6c1e4d30e8fe80ab331397a Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Fri, 15 Oct 2021 03:15:48 +0200 Subject: [PATCH 36/56] bugfix --- src/util/goblintutil.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/goblintutil.ml b/src/util/goblintutil.ml index 93cf188613..4b70db7a93 100644 --- a/src/util/goblintutil.ml +++ b/src/util/goblintutil.ml @@ -428,4 +428,4 @@ let dummy_obj = Obj.repr () (*returns the first n elements of a list. *) let rec firstElems n li = match li with | [] -> []; - | x::xs -> if n=1 then [x] else firstElems (n-1) xs; \ No newline at end of file + | x::xs -> if n=1 then [x] else x::firstElems (n-1) xs; \ No newline at end of file From 665ba0b01e78b229a8e3ed2997d46536afe6b85f Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Fri, 15 Oct 2021 05:17:53 +0200 Subject: [PATCH 37/56] modified gitHubaction path --- scripts/goblintAnalysis.yml | 72 ++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 38 deletions(-) diff --git a/scripts/goblintAnalysis.yml b/scripts/goblintAnalysis.yml index e113dda6a9..de0e6e9647 100644 --- a/scripts/goblintAnalysis.yml +++ b/scripts/goblintAnalysis.yml @@ -9,7 +9,7 @@ jobs: env: # ./analysisTarget/main.c needs to be replaced with ./analysisTarget/PATH_TO_MAIN #the prefix ./analysisTarget/ is removed in Goblint, so the location shows correctly in Github - MAIN_NAME: './analysisTarget/main.c' + MAIN_NAME: './testCRepo/main.c ./testCRepo/dumb.c' strategy: fail-fast: false matrix: @@ -21,41 +21,37 @@ jobs: runs-on: ${{ matrix.os }} permissions: - security-events: write + security-events: write steps: - - name: Checkout Goblint repository - uses: actions/checkout@v2 - with: - repository: AlexanderEichler/analyzer - #this path needs to be changed to the main branch - ref: integrationSarif - - name: Set up OCaml ${{ matrix.ocaml-compiler }} - env: - # otherwise setup-ocaml pins non-locked dependencies - # https://github.com/ocaml/setup-ocaml/issues/166 - OPAMLOCKED: locked - uses: ocaml/setup-ocaml@v2 - with: - ocaml-compiler: ${{ matrix.ocaml-compiler }} - - - name: Install dependencies - run: - opam install . --deps-only --locked - - name: Build - run: | - pwd - ./make.sh nat - - name: Checkout code - uses: actions/checkout@v2 - with: - path: analysisTarget - - name: Generate the Sarif output - run: | - pwd - ls - ./goblint --sarif -o GitHubSarif.sarif ${{env.MAIN_NAME}} - - name: Upload the generated Sarif File - uses: github/codeql-action/upload-sarif@v1 - with: - # Path to SARIF file relative to the root of the repository - sarif_file: GitHubSarif.sarif + - name: Checkout Goblint repository + uses: actions/checkout@v2 + with: + repository: goblint/analyzer + #this path needs to be changed to the main branch + ref: integrationSarif + - name: Set up OCaml ${{ matrix.ocaml-compiler }} + env: + # otherwise setup-ocaml pins non-locked dependencies + # https://github.com/ocaml/setup-ocaml/issues/166 + OPAMLOCKED: locked + uses: ocaml/setup-ocaml@v2 + with: + ocaml-compiler: ${{ matrix.ocaml-compiler }} + - name: Install dependencies + run: opam install . --deps-only --locked + - name: Build + run: ./make.sh nat + - name: Checkout code + uses: actions/checkout@v2 + with: + path: testCRepo + - name: Generate the Sarif output + #cilly --gcc=/usr/bin/gcc-6 --merge main.c dumb.c -o merged --keepmerged + # ./goblint --sarif -o GitHubSarif.sarif ${{env.MAIN_NAME}} -R ./testCRepo/ + run: | + ./goblint --sarif -o GitHubSarif.sarif ${{env.MAIN_NAME}} + - name: Upload the generated Sarif File + uses: github/codeql-action/upload-sarif@v1 + with: + # Path to SARIF file relative to the root of the repository + sarif_file: GitHubSarif.sarif From bbc4470cce09425ffb89efe3ccd2066bccc83645 Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Fri, 15 Oct 2021 05:30:18 +0200 Subject: [PATCH 38/56] added more documentation --- scripts/goblintAnalysis.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/scripts/goblintAnalysis.yml b/scripts/goblintAnalysis.yml index de0e6e9647..444a474575 100644 --- a/scripts/goblintAnalysis.yml +++ b/scripts/goblintAnalysis.yml @@ -7,9 +7,11 @@ on: jobs: generate-Sarif: env: - # ./analysisTarget/main.c needs to be replaced with ./analysisTarget/PATH_TO_MAIN + # ./analysisTarget/main.c needs to be replaced with ./analysisTarget/PATH_TO_FILE + #for each file that is supposed to be analyzed. + #This should be simplified to instead use the MakeFile of the repository. #the prefix ./analysisTarget/ is removed in Goblint, so the location shows correctly in Github - MAIN_NAME: './testCRepo/main.c ./testCRepo/dumb.c' + MAIN_NAME: './analysisTarget/main.c strategy: fail-fast: false matrix: @@ -44,7 +46,7 @@ jobs: - name: Checkout code uses: actions/checkout@v2 with: - path: testCRepo + path: analysisTarget - name: Generate the Sarif output #cilly --gcc=/usr/bin/gcc-6 --merge main.c dumb.c -o merged --keepmerged # ./goblint --sarif -o GitHubSarif.sarif ${{env.MAIN_NAME}} -R ./testCRepo/ From c3d9c45e72f5d1f145ce7ee78c5842710c937ec1 Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Fri, 15 Oct 2021 09:39:11 +0200 Subject: [PATCH 39/56] deleted unneeded script --- scripts/createSarifTestOutput.sh | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100755 scripts/createSarifTestOutput.sh diff --git a/scripts/createSarifTestOutput.sh b/scripts/createSarifTestOutput.sh deleted file mode 100755 index a6ec7fcb71..0000000000 --- a/scripts/createSarifTestOutput.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash -clear -echo "Generating output of test runs of tests/regression/*" -mkdir "/home/alex/Documents/git/analyzer/testResults" -dstpath=/home/alex/Documents/git/analyzer/testResults/ -for folder in "/home/alex/Documents/git/analyzer/tests/regression"/*; do - foldername=$(basename "$folder") - echo "$foldername" - mkdir "/home/alex/Documents/git/analyzer/testResults"/$foldername - for entry in "/home/alex/Documents/git/analyzer/tests/regression"/$foldername/*; do - - basename=$(basename "$entry") - dst="${dstpath}"$foldername"/"${basename::-2}".sarif" - ../goblint --sarif -o "$dst" "$entry" - done -done From 0cad65f8333b5aa1934f64e91edd791789c2c090 Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Fri, 15 Oct 2021 09:42:32 +0200 Subject: [PATCH 40/56] improved documentation --- scripts/goblintAnalysis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/goblintAnalysis.yml b/scripts/goblintAnalysis.yml index 444a474575..f95daed243 100644 --- a/scripts/goblintAnalysis.yml +++ b/scripts/goblintAnalysis.yml @@ -9,9 +9,8 @@ jobs: env: # ./analysisTarget/main.c needs to be replaced with ./analysisTarget/PATH_TO_FILE #for each file that is supposed to be analyzed. - #This should be simplified to instead use the MakeFile of the repository. #the prefix ./analysisTarget/ is removed in Goblint, so the location shows correctly in Github - MAIN_NAME: './analysisTarget/main.c + MAIN_NAME: './analysisTarget/main.c' strategy: fail-fast: false matrix: From 038c6b7e4241d26e195c86041940c3e7d6552f39 Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Fri, 15 Oct 2021 09:44:22 +0200 Subject: [PATCH 41/56] deleted test output --- scripts/test.sarif | 212 --------------------------------------------- 1 file changed, 212 deletions(-) delete mode 100644 scripts/test.sarif diff --git a/scripts/test.sarif b/scripts/test.sarif deleted file mode 100644 index e72aadb4cb..0000000000 --- a/scripts/test.sarif +++ /dev/null @@ -1,212 +0,0 @@ -{ - "$schema": "https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.5.json", - "version": "2.1.0", - "runs": [ - { - "tool": { - "driver": { - "name": "Goblint", - "fullName": "Goblint static analyser", - "informationUri": "https://goblint.in.tum.de/home", - "organization": "TUM - i2 and UTartu - SWS", - "version": "heads/integrationSarif-0-g8c1794b4-dirty", - "downloadUri": "https://github.com/goblint/analyzer", - "rules": [ - { - "id": "GO001", - "name": "", - "helpUri": "https://goblint.in.tum.de/home", - "help": { - "text": "The category analyser describes ...." - }, - "shortDescription": { - "text": "" - }, - "fullDescription": { - "text": "" - } - }, - { - "id": "GO002", - "name": "CWE119 ", - "helpUri": "https://cwe.mitre.org/data/definitions/119.html", - "help": { - "text": "CWE 119:Improper Restriction of Operations within the Bounds of a Memory Buffer" - }, - "shortDescription": { - "text": "CWE119 " - }, - "fullDescription": { - "text": "The software performs operations on a memory buffer, but it can read from or write to a memory location that is outside of the intended boundary of the buffer." - } - }, - { - "id": "GO003", - "name": "Integer Overflow or Wraparound", - "helpUri": "https://cwe.mitre.org/data/definitions/190.html", - "help": { - "text": "The software performs a calculation that can produce an integer overflow or wraparound, when the logic assumes that the resulting value will always be larger than the original value.This can introduce other weaknesses when the calculation is used for resource management or execution control. " - }, - "shortDescription": { - "text": "Integer Overflow or Wraparound" - }, - "fullDescription": { - "text": "An integer overflow or wraparound occurs when an integer value is incremented to a value that is too large to store in the associated representation. When this occurs, the value may wrap to become a very small or negative number. While this may be intended behavior in circumstances that rely on wrapping, it can have security consequences if the wrap is unexpected. This is especially the case if the integer overflow can be triggered using user-supplied inputs. This becomes security-critical when the result is used to control looping, make a security decision, or determine the offset or size in behaviors such as memory allocation, copying, concatenation, etc. " - } - }, - { - "id": "GO004", - "name": "The software does not handle or incorrectly handles when a particular element is not the expected type, e.g. it expects a digit (0-9) but is provided with a letter (A-Z). ", - "helpUri": "https://cwe.mitre.org/data/definitions/241.html", - "help": { - "text": "CWE 241:Improper Handling of Unexpected Data Type" - }, - "shortDescription": { - "text": "The software does not handle or incorrectly handles when a particular element is not the expected type, e.g. it expects a digit (0-9) but is provided with a letter (A-Z). " - }, - "fullDescription": { - "text": "" - } - }, - { - "id": "GO005", - "name": "The program contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently. ", - "helpUri": "https://cwe.mitre.org/data/definitions/362.html", - "help": { - "text": "CWE 362: Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')" - }, - "shortDescription": { - "text": "The program contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently. " - }, - "fullDescription": { - "text": "" - } - }, - { - "id": "GO006", - "name": "The product divides a value by zero. ", - "helpUri": "https://cwe.mitre.org/data/definitions/369.html", - "help": { - "text": "CWE 369: Divide By Zero" - }, - "shortDescription": { - "text": "The product divides a value by zero. " - }, - "fullDescription": { - "text": "This weakness typically occurs when an unexpected value is provided to the product, or if an error occurs that is not properly detected. It frequently occurs in calculations involving physical dimensions such as size, length, width, and height. " - } - }, - { - "id": "GO007", - "name": "Referencing memory after it has been freed can cause a program to crash, use unexpected values, or execute code. ", - "helpUri": "https://cwe.mitre.org/data/definitions/416.html", - "help": { - "text": "CWE 416:Use After Free" - }, - "shortDescription": { - "text": "Referencing memory after it has been freed can cause a program to crash, use unexpected values, or execute code. " - }, - "fullDescription": { - "text": "The use of previously-freed memory can have any number of adverse consequences, ranging from the corruption of valid data to the execution of arbitrary code, depending on the instantiation and timing of the flaw. The simplest way data corruption may occur involves the system's reuse of the freed memory. Use-after-free errors have two common and sometimes overlapping causes: Error conditions and other exceptional circumstances. Confusion over which part of the program is responsible for freeing the memory.In this scenario, the memory in question is allocated to another pointer validly at some point after it has been freed. The original pointer to the freed memory is used again and points to somewhere within the new allocation. As the data is changed, it corrupts the validly used memory; this induces undefined behavior in the process.If the newly allocated data chances to hold a class, in C++ for example, various function pointers may be scattered within the heap data. If one of these function pointers is overwritten with an address to valid shellcode, execution of arbitrary code can be achieved. " - } - }, - { - "id": "GO008", - "name": "A NULL pointer dereference occurs when the application dereferences a pointer that it expects to be valid, but is NULL, typically causing a crash or exit. ", - "helpUri": "https://cwe.mitre.org/data/definitions/476.html", - "help": { - "text": "CWE 476:NULL Pointer Dereference" - }, - "shortDescription": { - "text": "A NULL pointer dereference occurs when the application dereferences a pointer that it expects to be valid, but is NULL, typically causing a crash or exit. " - }, - "fullDescription": { - "text": "NULL pointer dereference issues can occur through a number of flaws, including race conditions, and simple programming omissions. " - } - }, - { - "id": "GO009", - "name": "The software contains dead code, which can never be executed. ", - "helpUri": "https://cwe.mitre.org/data/definitions/561.html", - "help": { - "text": "CWE 561:Dead Code" - }, - "shortDescription": { - "text": "The software contains dead code, which can never be executed. " - }, - "fullDescription": { - "text": "Dead code is source code that can never be executed in a running program. The surrounding code makes it impossible for a section of code to ever be executed. " - } - }, - { - "id": "GO0010", - "name": "The software contains an expression that will always evaluate to false. ", - "helpUri": "https://cwe.mitre.org/data/definitions/570.html", - "help": { - "text": "CWE 570:Expression is Always False" - }, - "shortDescription": { - "text": "The software contains an expression that will always evaluate to false. " - }, - "fullDescription": { - "text": "" - } - }, - { - "id": "GO0011", - "name": "The software contains an expression that will always evaluate to true. ", - "helpUri": "https://cwe.mitre.org/data/definitions/571.html", - "help": { - "text": "CWE 571:Expression is Always True" - }, - "shortDescription": { - "text": "The software contains an expression that will always evaluate to true. " - }, - "fullDescription": { - "text": "" - } - }, - { - "id": "GO012", - "name": "The software writes data past the end, or before the beginning, of the intended buffer. ", - "helpUri": "https://cwe.mitre.org/data/definitions/787.html", - "help": { - "text": "CWE 787: Out-of-bounds Write" - }, - "shortDescription": { - "text": "The software writes data past the end, or before the beginning, of the intended buffer. " - }, - "fullDescription": { - "text": "Typically, this can result in corruption of data, a crash, or code execution. The software may modify an index or perform pointer arithmetic that references a memory location that is outside of the boundaries of the buffer. A subsequent write operation then produces undefined or unexpected results. " - } - }, - { - "id": "GO013", - "name": "The software reads or writes to a buffer using an index or pointer that references a memory location after the end of the buffer. ", - "helpUri": "https://cwe.mitre.org/data/definitions/788.html", - "help": { - "text": "CWE 788:Access of Memory Location After End of Buffer" - }, - "shortDescription": { - "text": "The software reads or writes to a buffer using an index or pointer that references a memory location after the end of the buffer. " - }, - "fullDescription": { - "text": "This typically occurs when a pointer or its index is decremented to a position before the buffer;when pointer arithmetic results in a position before the buffer; or when a negative index is used, which generates a position before the buffer. " - } - } - ] - } - }, - "invocations": [ - { - "commandLine": "../goblint --sarif -o test.sarif ../tests/regression/02-base/02-simple_assignments.c", - "executionSuccessful": true - } - ], - "defaultSourceLanguage": "C", - "results": [ - - ] - } - ] -} From db7e04434b248a62296a169c936a2c63073f851d Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Fri, 15 Oct 2021 09:46:15 +0200 Subject: [PATCH 42/56] removed debug messages --- src/incremental/makefileUtil.ml | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/incremental/makefileUtil.ml b/src/incremental/makefileUtil.ml index d0b48c5ffc..c52e0ef923 100644 --- a/src/incremental/makefileUtil.ml +++ b/src/incremental/makefileUtil.ml @@ -6,11 +6,9 @@ let buff_size = 1024 let comb_suffix = "_comb.c" let exec_command ?path (command: string) = - print_string ("command = "^command); let current_dir = Sys.getcwd () in (match path with | Some path -> - print_string ("path = "^path); if Sys.file_exists path && Sys.is_directory path then Sys.chdir path else failwith ("Directory " ^ path ^ " does not exist!") | None -> ()); @@ -35,10 +33,7 @@ let string_of_process_status = function | WSTOPPED n -> "was stopped by signal " ^ string_of_int n (* BFS for a file with a given suffix in a directory or any subdirectoy *) -let find_file_by_suffix (dir: string) (file_name_suffix: string) = - - (*print_string ("find_file_by_suffix dir "^dir^"\n"); - print_string ("find_file_by_suffix file_name_suffix "^file_name_suffix^"\n");*) +let find_file_by_suffix (dir: string) (file_name_suffix: string) = let list_files d = Array.to_list @@ Sys.readdir d in let dirs = Queue.create () in let rec search (dir: string) (files: string list) = match files with @@ -65,10 +60,7 @@ let run_cilly (path: string) = done with Failure e -> ()); (* Deleted all *_comb.c files in the directory *) (* Combine source files with make using cilly as compiler *) - let gcc_path = GobConfig.get_string "exp.gcc_path" in - let command = ("make CC=\"cilly --gcc=" ^ gcc_path ^ " --merge --keepmerged\" " ^ - "LD=\"cilly --gcc=" ^ gcc_path ^ " --merge --keepmerged\"") in - print_string ("command = "^ command^"\n"); + let gcc_path = GobConfig.get_string "exp.gcc_path" in let (exit_code, output) = exec_command ~path ("make CC=\"cilly --gcc=" ^ gcc_path ^ " --merge --keepmerged\" " ^ "LD=\"cilly --gcc=" ^ gcc_path ^ " --merge --keepmerged\"") in From eefe41f41553c2c178729063c0a60ff8f4e4cf78 Mon Sep 17 00:00:00 2001 From: AlexanderEichler Date: Fri, 15 Oct 2021 09:51:07 +0200 Subject: [PATCH 43/56] removed dead code and debug messages --- src/framework/sarif.ml | 1 + src/maingoblint.ml | 8 -------- src/util/defaults.ml | 2 -- 3 files changed, 1 insertion(+), 10 deletions(-) diff --git a/src/framework/sarif.ml b/src/framework/sarif.ml index a389cfd8f7..cf37f4f008 100644 --- a/src/framework/sarif.ml +++ b/src/framework/sarif.ml @@ -219,6 +219,7 @@ struct end +(*endColumn and endLine are not produced by Goblint yet, however the Github action uses these properties. *) module Region = struct type t = { diff --git a/src/maingoblint.ml b/src/maingoblint.ml index 09e4cd4b6f..43569fee0a 100644 --- a/src/maingoblint.ml +++ b/src/maingoblint.ml @@ -83,12 +83,8 @@ let option_spec_list = let configure_sarif () = if (get_string "outfile" = "") then set_string "outfile" "test.sarif"; - if get_string "makeFilePath" = "" then - set_string "makeFilePath" ""; set_bool "dbg.print_dead_code" true; set_bool "exp.cfgdot" true; - set_bool "g2html" false; - set_bool "dbg.verbose" true; set_string "result" "sarif" in let tmp_arg = ref "" in @@ -96,7 +92,6 @@ let option_spec_list = ; "-v" , Arg.Unit (fun () -> set_bool "dbg.verbose" true; set_bool "printstats" true), "" ; "-I" , Arg.String (set_string "includes[+]"), "" ; "-R" , Arg.String (set_string "removePath"), "" - ; "-C" , Arg.String (set_string "makeFilePath"), "" ; "-IK" , Arg.String (set_string "kernel_includes[+]"), "" ; "--set" , Arg.Tuple [Arg.Set_string tmp_arg; Arg.String (fun x -> set_auto !tmp_arg x)], "" ; "--sets" , Arg.Tuple [Arg.Set_string tmp_arg; Arg.String (fun x -> prerr_endline "--sets is deprecated, use --set instead."; set_string !tmp_arg x)], "" @@ -220,7 +215,6 @@ let preprocess_files () = if Filename.basename firstFile = "Makefile" then ( let makefile = firstFile in let path = Filename.dirname makefile in - printf "Path of makefile: %s\n\n%!" path; (* make sure the Makefile exists or try to generate it *) if not (Sys.file_exists makefile) then ( print_endline ("Given " ^ makefile ^ " does not exist!"); @@ -233,7 +227,6 @@ let preprocess_files () = ) else failwith ("Could neither find given " ^ makefile ^ " nor " ^ configure ^ " - abort!") ); let _ = MakefileUtil.run_cilly path in - let file = MakefileUtil.(find_file_by_suffix path comb_suffix) in cFileNames := file :: (List.drop 1 !cFileNames); ); @@ -269,7 +262,6 @@ let merge_preprocessed cpp_file_names = if get_bool "dbg.verbose" then print_endline "Parsing files."; let files_AST = List.rev_map Cilfacade.getAST cpp_file_names in remove_temp_dir (); - let cilout = if get_string "dbg.cilout" = "" then Legacy.stderr else Legacy.open_out (get_string "dbg.cilout") in diff --git a/src/util/defaults.ml b/src/util/defaults.ml index d02676cf58..f8f21f9102 100644 --- a/src/util/defaults.ml +++ b/src/util/defaults.ml @@ -60,7 +60,6 @@ let printAllCategories ch = let _ = () ; reg Std "outfile" "" "File to print output to." ; reg Std "removePath" "" "For the Sarif Github action. This removes the leading path of the Uri. This is needed, because the Github action runs in a subdirectory." - ; reg Std "makeFilePath" "" "Path to the makeFile. Needed for the Github action" ; reg Std "includes" "[]" "List of directories to include." ; reg Std "kernel_includes" "[]" "List of kernel directories to include." ; reg Std "custom_includes" "[]" "List of custom directories to include." @@ -288,7 +287,6 @@ let default_schema = {schema| } , "outfile" : {} , "removePath" : {} - , "makeFilePath" : {} , "includes" : {} , "kernel_includes" : {} , "custom_includes" : {} From 24bfd57374984e1721f92da7736d1e93b7e524e8 Mon Sep 17 00:00:00 2001 From: Simmo Saan Date: Wed, 3 Nov 2021 13:27:23 +0200 Subject: [PATCH 44/56] Trim trailing whitespace in Sarif --- src/framework/sarif.ml | 136 ++++++++++++++++++++--------------------- 1 file changed, 68 insertions(+), 68 deletions(-) diff --git a/src/framework/sarif.ml b/src/framework/sarif.ml index cf37f4f008..8668db1497 100644 --- a/src/framework/sarif.ml +++ b/src/framework/sarif.ml @@ -11,7 +11,7 @@ type categoryInformation = { shortDescription:string; helpUri:string; longDescription:string; -} +} let unknownRule = { name="Unknown"; ruleId="GO000"; @@ -69,7 +69,7 @@ let rules = [ shortDescription="Result of arithmetic operation might be outside of the valid range. "; helpUri="https://en.wikipedia.org/wiki/Integer_overflow"; longDescription=""; - }; + }; { name="DivByZero"; ruleId="GO0007"; @@ -126,7 +126,7 @@ let rules = [ shortDescription="TODO "; helpUri="https://goblint.in.tum.de/home"; longDescription=""; - }; + }; { name="Unknown Aob"; ruleId="GO0014"; @@ -187,15 +187,15 @@ let rules = [ name="788"; ruleId="GO0021"; helpText="Access of Memory Location After End of Buffer"; - shortDescription="The software reads or writes to a buffer using an index or pointer that references a memory location after the end of the buffer. "; + shortDescription="The software reads or writes to a buffer using an index or pointer that references a memory location after the end of the buffer. "; helpUri="https://cwe.mitre.org/data/definitions/788.html"; longDescription=""; } ] (*Returns the information about a Rule. If the rule is not found, a default rule will be returned. *) -let getRuleInformation (searchName:string) = - match List.find_opt (fun rule -> rule.name=searchName) rules with +let getRuleInformation (searchName:string) = + match List.find_opt (fun rule -> rule.name=searchName) rules with | None ->unknownRule ; | Some rule -> rule @@ -215,10 +215,10 @@ struct commandLine:string; executionSuccessful:bool; - } [@@deriving to_yojson] + } [@@deriving to_yojson] -end +end (*endColumn and endLine are not produced by Goblint yet, however the Github action uses these properties. *) module Region = struct @@ -227,36 +227,36 @@ struct startColumn:int; endColumn:int; endLine:int; - } [@@deriving to_yojson] + } [@@deriving to_yojson] -end +end module ArtifactLocation = struct type t = { uri:string; - } [@@deriving to_yojson] + } [@@deriving to_yojson] -end +end module PhysicalLocation = struct type t = { artifactLocation:ArtifactLocation.t; region:Region.t; - } [@@deriving to_yojson] -end + } [@@deriving to_yojson] +end -(*This type represents the Sarif locationProperty. +(*This type represents the Sarif locationProperty. It is needed twice, since Sarif requires differen keys names, depending on where it is used.*) module LocationObject = struct type t = { location:ArtifactLocation.t; - } [@@deriving to_yojson] -end + } [@@deriving to_yojson] +end module Locations = @@ -265,18 +265,18 @@ struct physicalLocation:PhysicalLocation.t; - } [@@deriving to_yojson] + } [@@deriving to_yojson] -end +end module SairfMessageObject = struct type t = { text:string; - } [@@deriving to_yojson] + } [@@deriving to_yojson] -end +end module ReportingDescriptor = struct type t = { @@ -287,10 +287,10 @@ struct shortDescription:SairfMessageObject.t; fullDescription:SairfMessageObject.t; - } [@@deriving to_yojson] + } [@@deriving to_yojson] -end +end module Driver = struct @@ -301,18 +301,18 @@ struct organization:string; version:string; rules:ReportingDescriptor.t list - } [@@deriving to_yojson] + } [@@deriving to_yojson] -end +end module Tool = struct type t = { - driver:Driver.t; - } [@@deriving to_yojson] + driver:Driver.t; + } [@@deriving to_yojson] -end +end module ResultObject = @@ -322,10 +322,10 @@ struct level:string; message:SairfMessageObject.t; locations:Locations.t list; - } [@@deriving to_yojson] + } [@@deriving to_yojson] -end +end module Run = struct @@ -335,32 +335,32 @@ struct invocations:InvocationObject.t list; artifacts:LocationObject.t list; results:ResultObject.t list - }[@@deriving to_yojson] + }[@@deriving to_yojson] -end +end -let createMessageObject (text:String.t) = +let createMessageObject (text:String.t) = { SairfMessageObject.text=text; } (*A reportingDescriptor offers a lot of information about a Goblint rule *) -let createReportingDescriptor categoryInformation = +let createReportingDescriptor categoryInformation = { - ReportingDescriptor.ruleId=categoryInformation.ruleId; - ReportingDescriptor.ruleName=categoryInformation.name; + ReportingDescriptor.ruleId=categoryInformation.ruleId; + ReportingDescriptor.ruleName=categoryInformation.name; ReportingDescriptor.helpUri=categoryInformation.helpUri; ReportingDescriptor.help=(createMessageObject categoryInformation.helpText); ReportingDescriptor.shortDescription=(createMessageObject categoryInformation.shortDescription); ReportingDescriptor.fullDescription=(createMessageObject categoryInformation.longDescription); - } + } -let transformToReportingDescriptor (id:String.t)= +let transformToReportingDescriptor (id:String.t)= createReportingDescriptor (getRuleInformation id) -let (driverObject:Driver.t) = +let (driverObject:Driver.t) = { Driver.name="Goblint"; Driver.fullName= "Goblint static analyser"; @@ -369,32 +369,32 @@ let (driverObject:Driver.t) = Driver.version=Version.goblint; Driver.rules=List.map transformToReportingDescriptor (List.map (fun rule -> rule.name) rules) } -let (toolObject:Tool.t) = +let (toolObject:Tool.t) = { - Tool.driver=driverObject; + Tool.driver=driverObject; } (*returns the Rule corresponding to a message entry *) -let getCategoryInformationID (tags:Messages.Tags.t) = - let getCWE (tag:Messages.Tag.t) = match tag with +let getCategoryInformationID (tags:Messages.Tags.t) = + let getCWE (tag:Messages.Tag.t) = match tag with | CWE cwe-> Some cwe; | Category cat -> None; - in - (* if a CWE is present only the CWE is used, since using multiple ones for the same result doesn' make sense. + in + (* if a CWE is present only the CWE is used, since using multiple ones for the same result doesn' make sense. If only Categorys are present, all of them are displayed.*) - match List.find_map getCWE tags with - | Some cwe -> string_of_int cwe; + match List.find_map getCWE tags with + | Some cwe -> string_of_int cwe; | None -> match tags with | [] -> "" - | x::xs -> match x with + | x::xs -> match x with |Category cat-> MessageCategory.categoryName cat | CWE c-> "" (*this case should not be reachable *) (* for the github action. Removes leading directory.*) let trimFile (path:string) = let lengthRemove = (String.length (get_string "removePath")) - in + in if get_string "removePath" == "" then path else "./"^(String.sub path lengthRemove ((String.length path)-lengthRemove) ) @@ -412,11 +412,11 @@ let hasLocation (piece:Messages.Piece.t) = match piece.loc with |Some loc -> true |None -> false (*should only be called after hasLocation*) -let deOptionalizeLocation (piece:Messages.Piece.t)= match piece.loc with +let deOptionalizeLocation (piece:Messages.Piece.t)= match piece.loc with | Some loc ->loc | None -> assert false -let createPhysicalLocationObject (piece:Messages.Piece.t) = +let createPhysicalLocationObject (piece:Messages.Piece.t) = let createRegionObject (line,column)= { Region.startLine=line; @@ -433,14 +433,14 @@ let createPhysicalLocationObject (piece:Messages.Piece.t) = } -let createLocationsObject (multiPiece:Messages.MultiPiece.t) = match multiPiece with +let createLocationsObject (multiPiece:Messages.MultiPiece.t) = match multiPiece with | Single piece ->List.map createPhysicalLocationObject (List.filter hasLocation [piece]); | Group {group_text = n; pieces = e} ->List.map createPhysicalLocationObject (GU.firstElems 10 (List.filter hasLocation e)) -let createResult (message:Messages.Message.t) = - let getMessage (multiPiece:Messages.MultiPiece.t)= match multiPiece with +let createResult (message:Messages.Message.t) = + let getMessage (multiPiece:Messages.MultiPiece.t)= match multiPiece with | Single piece ->piece.text; | Group {group_text = n; pieces = e} ->n in @@ -449,28 +449,28 @@ let createResult (message:Messages.Message.t) = ResultObject.level=severityToLevel message.severity; ResultObject.message=createMessageObject (getMessage message.multipiece); ResultObject.locations=createLocationsObject message.multipiece; - } + } -let getFileLocation (multipiece:Messages.MultiPiece.t)= +let getFileLocation (multipiece:Messages.MultiPiece.t)= let getFile (loc:Cil.location) = loc.file in - let toLocation = match multipiece with + let toLocation = match multipiece with | Single piece ->[deOptionalizeLocation piece]; | Group {group_text = n; pieces = e} -> List.map deOptionalizeLocation (List.filter hasLocation e); - in - List.map getFile toLocation + in + List.map getFile toLocation let collectAllFileLocations (msgList:Messages.Message.t list)= let getUris= List.flatten (List.map (fun (msg:Messages.Message.t)-> getFileLocation msg.multipiece) msgList) - in + in let uniques x xs = if List.mem x xs then xs else x::xs; in List.fold_right uniques getUris [] -let runObject msgList= +let runObject msgList= { Run.invocations=[{ InvocationObject.commandLine=String.concat ", " (BatArray.to_list BatSys.argv) ; @@ -478,9 +478,9 @@ let runObject msgList= }]; Run.artifacts= List.map createArtifactLocationObject (collectAllFileLocations msgList); Run.tool=toolObject; - Run.defaultSourceLanguage="C"; + Run.defaultSourceLanguage="C"; Run.results=List.map createResult (GU.firstElems 5000 msgList); - } + } module SarifLog = struct type t = { @@ -488,9 +488,9 @@ struct version:string; schema :string [@key "$schema"]; runs:Run.t list ; - } [@@deriving to_yojson] + } [@@deriving to_yojson] -end +end module Sarif = @@ -498,15 +498,15 @@ struct type t = | SarifLog (*[@name "sarifLog"]*) - [@@deriving yojson] + [@@deriving yojson] let sarifObject msgList={SarifLog.version="2.1.0"; SarifLog.schema="https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.5.json"; SarifLog.runs=[runObject msgList] }; -end +end -let to_yojson msgList= [%to_yojson: SarifLog.t] (Sarif.sarifObject msgList) +let to_yojson msgList= [%to_yojson: SarifLog.t] (Sarif.sarifObject msgList) From bef4b47ad3200799fa47cf367c6745b10bf17ea1 Mon Sep 17 00:00:00 2001 From: Simmo Saan Date: Wed, 3 Nov 2021 13:28:39 +0200 Subject: [PATCH 45/56] Use BatList in Sarif --- src/framework/sarif.ml | 7 ++++--- src/util/goblintutil.ml | 5 ----- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/framework/sarif.ml b/src/framework/sarif.ml index 8668db1497..a2cbbb371c 100644 --- a/src/framework/sarif.ml +++ b/src/framework/sarif.ml @@ -1,4 +1,5 @@ (** The Sarif format is a standardised output format for static analysis tools. https://docs.oasis-open.org/sarif/sarif/v2.1.0/sarif-v2.1.0.html *) +open Prelude open GobConfig module Category = MessageCategory module GU = Goblintutil @@ -383,7 +384,7 @@ let getCategoryInformationID (tags:Messages.Tags.t) = in (* if a CWE is present only the CWE is used, since using multiple ones for the same result doesn' make sense. If only Categorys are present, all of them are displayed.*) - match List.find_map getCWE tags with + match List.find_map_opt getCWE tags with | Some cwe -> string_of_int cwe; | None -> match tags with | [] -> "" @@ -435,7 +436,7 @@ let createPhysicalLocationObject (piece:Messages.Piece.t) = let createLocationsObject (multiPiece:Messages.MultiPiece.t) = match multiPiece with | Single piece ->List.map createPhysicalLocationObject (List.filter hasLocation [piece]); - | Group {group_text = n; pieces = e} ->List.map createPhysicalLocationObject (GU.firstElems 10 (List.filter hasLocation e)) + | Group {group_text = n; pieces = e} ->List.map createPhysicalLocationObject (List.take 10 (List.filter hasLocation e)) @@ -479,7 +480,7 @@ let runObject msgList= Run.artifacts= List.map createArtifactLocationObject (collectAllFileLocations msgList); Run.tool=toolObject; Run.defaultSourceLanguage="C"; - Run.results=List.map createResult (GU.firstElems 5000 msgList); + Run.results=List.map createResult (List.take 5000 msgList); } module SarifLog = struct diff --git a/src/util/goblintutil.ml b/src/util/goblintutil.ml index 4b70db7a93..8f909aa95e 100644 --- a/src/util/goblintutil.ml +++ b/src/util/goblintutil.ml @@ -424,8 +424,3 @@ let assoc_eq (x: 'a) (ys: ('a * 'b) list) (eq: 'a -> 'a -> bool): ('b option) = Option.map Batteries.Tuple2.second (List.find_opt (fun (x',_) -> eq x x') ys) let dummy_obj = Obj.repr () - -(*returns the first n elements of a list. *) -let rec firstElems n li = match li with - | [] -> []; - | x::xs -> if n=1 then [x] else x::firstElems (n-1) xs; \ No newline at end of file From c1bbb7c1d89448e19c7f3eb93bc659154a862f96 Mon Sep 17 00:00:00 2001 From: Simmo Saan Date: Wed, 3 Nov 2021 13:36:27 +0200 Subject: [PATCH 46/56] Update --sarif options --- src/maingoblint.ml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/maingoblint.ml b/src/maingoblint.ml index 43569fee0a..1fd65186a2 100644 --- a/src/maingoblint.ml +++ b/src/maingoblint.ml @@ -82,9 +82,8 @@ let option_spec_list = in let configure_sarif () = if (get_string "outfile" = "") then - set_string "outfile" "test.sarif"; + set_string "outfile" "goblint.sarif"; set_bool "dbg.print_dead_code" true; - set_bool "exp.cfgdot" true; set_string "result" "sarif" in let tmp_arg = ref "" in @@ -208,7 +207,7 @@ let preprocess_files () = (* reverse the files again *) cFileNames := List.rev !cFileNames; - + (* If the first file given is a Makefile, we use it to combine files *) if List.length !cFileNames >= 1 then ( let firstFile = List.first !cFileNames in From 2cdf708c4d713ce50beb7101948f4c3490907a38 Mon Sep 17 00:00:00 2001 From: Simmo Saan Date: Wed, 3 Nov 2021 13:37:04 +0200 Subject: [PATCH 47/56] Add *.sarif to .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index b78a710c37..92da6005fd 100644 --- a/.gitignore +++ b/.gitignore @@ -71,3 +71,5 @@ incremental_data/ # test-incremental.sh *.log + +*.sarif From cb093d6fc5248d3f65ed23d8ede9aa1855012957 Mon Sep 17 00:00:00 2001 From: Simmo Saan Date: Wed, 3 Nov 2021 13:40:56 +0200 Subject: [PATCH 48/56] Remove slow Sarif GitHub workflow example --- scripts/goblintAnalysis.yml | 58 ------------------------------------- 1 file changed, 58 deletions(-) delete mode 100644 scripts/goblintAnalysis.yml diff --git a/scripts/goblintAnalysis.yml b/scripts/goblintAnalysis.yml deleted file mode 100644 index f95daed243..0000000000 --- a/scripts/goblintAnalysis.yml +++ /dev/null @@ -1,58 +0,0 @@ -name: goblintAnalysis - -on: - push: - pull_request: - -jobs: - generate-Sarif: - env: - # ./analysisTarget/main.c needs to be replaced with ./analysisTarget/PATH_TO_FILE - #for each file that is supposed to be analyzed. - #the prefix ./analysisTarget/ is removed in Goblint, so the location shows correctly in Github - MAIN_NAME: './analysisTarget/main.c' - strategy: - fail-fast: false - matrix: - os: - - ubuntu-latest - ocaml-compiler: - - 4.12.0 # matches opam lock file - # don't add any other because they won't be used - - runs-on: ${{ matrix.os }} - permissions: - security-events: write - steps: - - name: Checkout Goblint repository - uses: actions/checkout@v2 - with: - repository: goblint/analyzer - #this path needs to be changed to the main branch - ref: integrationSarif - - name: Set up OCaml ${{ matrix.ocaml-compiler }} - env: - # otherwise setup-ocaml pins non-locked dependencies - # https://github.com/ocaml/setup-ocaml/issues/166 - OPAMLOCKED: locked - uses: ocaml/setup-ocaml@v2 - with: - ocaml-compiler: ${{ matrix.ocaml-compiler }} - - name: Install dependencies - run: opam install . --deps-only --locked - - name: Build - run: ./make.sh nat - - name: Checkout code - uses: actions/checkout@v2 - with: - path: analysisTarget - - name: Generate the Sarif output - #cilly --gcc=/usr/bin/gcc-6 --merge main.c dumb.c -o merged --keepmerged - # ./goblint --sarif -o GitHubSarif.sarif ${{env.MAIN_NAME}} -R ./testCRepo/ - run: | - ./goblint --sarif -o GitHubSarif.sarif ${{env.MAIN_NAME}} - - name: Upload the generated Sarif File - uses: github/codeql-action/upload-sarif@v1 - with: - # Path to SARIF file relative to the root of the repository - sarif_file: GitHubSarif.sarif From 901dc4b34c31e800f934e4662226462bc997e44c Mon Sep 17 00:00:00 2001 From: Simmo Saan Date: Wed, 3 Nov 2021 13:43:08 +0200 Subject: [PATCH 49/56] Move Sarif from framework to util --- src/{framework => util}/sarif.ml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{framework => util}/sarif.ml (100%) diff --git a/src/framework/sarif.ml b/src/util/sarif.ml similarity index 100% rename from src/framework/sarif.ml rename to src/util/sarif.ml From dfbcb7dbe26cb254c275a05e395c59a32ae3378a Mon Sep 17 00:00:00 2001 From: Simmo Saan Date: Wed, 3 Nov 2021 13:44:53 +0200 Subject: [PATCH 50/56] Move Sarif rules to SarifRules module --- src/util/sarif.ml | 197 +---------------------------------------- src/util/sarifRules.ml | 195 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 196 insertions(+), 196 deletions(-) create mode 100644 src/util/sarifRules.ml diff --git a/src/util/sarif.ml b/src/util/sarif.ml index a2cbbb371c..65db81a583 100644 --- a/src/util/sarif.ml +++ b/src/util/sarif.ml @@ -4,202 +4,7 @@ open GobConfig module Category = MessageCategory module GU = Goblintutil - -type categoryInformation = { - name:string; - ruleId:string; - helpText:string; - shortDescription:string; - helpUri:string; - longDescription:string; -} -let unknownRule = { - name="Unknown"; - ruleId="GO000"; - helpText=""; - shortDescription=""; - helpUri="https://goblint.in.tum.de/home"; - longDescription=""; -} - -let rules = [ - { - name="Assert"; - ruleId="GO0001"; - helpText="Assert Error"; - shortDescription="This is an internal Goblint Category"; - helpUri="https://goblint.in.tum.de/home"; - longDescription=""; - }; - { - name="Analyzer"; - ruleId="GO0002"; - helpText="Analyzer Error"; - shortDescription="This is an internal Goblint Category"; - helpUri="https://goblint.in.tum.de/home"; - longDescription=""; - }; - { - name="Cast"; - ruleId="GO0003"; - helpText="Cast Error"; - shortDescription="This is an internal Goblint Cast Error, most likely not indicating a problem in the analyzed program."; - helpUri="https://goblint.in.tum.de/home"; - longDescription=""; - }; - { - name="Deadcode"; - ruleId="GO0004"; - helpText="Deadcode"; - shortDescription="This code is never used in the program."; - helpUri="https://goblint.in.tum.de/home"; - longDescription=""; - }; - { - name="Race"; - ruleId="GO0005"; - helpText="A race condition"; - shortDescription="The program contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently. "; - helpUri="https://goblint.in.tum.de/home"; - longDescription=""; - }; - { - name="Overflow"; - ruleId="GO0006"; - helpText="Integer Overflow"; - shortDescription="Result of arithmetic operation might be outside of the valid range. "; - helpUri="https://en.wikipedia.org/wiki/Integer_overflow"; - longDescription=""; - }; - { - name="DivByZero"; - ruleId="GO0007"; - helpText="Division by zero"; - shortDescription="Division by zero can result in undefined behaviour."; - helpUri="https://goblint.in.tum.de/home"; - longDescription=""; - }; - { - name="Implementation"; - ruleId="GO0008"; - (*TODO is this correct? *) - helpText="Implementation of function might not be present on all versions of the target platform."; - shortDescription=" Implementation of function might not be present on all versions of the target platform."; - helpUri="https://goblint.in.tum.de/home"; - longDescription=""; - }; - { - name="Machine"; - ruleId="GO0009"; - helpText="TODO"; - shortDescription="TODO "; - helpUri="https://goblint.in.tum.de/home"; - longDescription=""; - }; - { - name="NullPointerDereference"; - ruleId="GO0010"; - helpText="Nullpointer dereference"; - shortDescription="A NULL pointer dereference occurs when the application dereferences a pointer that it expects to be valid, but is NULL, typically causing a crash or exit. "; - helpUri="https://cwe.mitre.org/data/definitions/476.html"; - longDescription=""; - }; - { - name="UseAfterFree"; - ruleId="GO0011"; - helpText="TODO"; - shortDescription="TODO "; - helpUri="https://goblint.in.tum.de/home"; - longDescription=""; - }; - { - name="PastEnd"; - ruleId="GO0012"; - helpText="TODO"; - shortDescription="TODO "; - helpUri="https://goblint.in.tum.de/home"; - longDescription=""; - }; - { - name="BeforeStart"; - ruleId="GO0013"; - helpText="TODO"; - shortDescription="TODO "; - helpUri="https://goblint.in.tum.de/home"; - longDescription=""; - }; - { - name="Unknown Aob"; - ruleId="GO0014"; - helpText="Array out of Bounds Error"; - shortDescription="Array out of Bounds Error "; - helpUri="https://goblint.in.tum.de/home"; - longDescription=""; - }; - { - name="362"; - ruleId="GO015"; - helpText="Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')"; - shortDescription="The program contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently. "; - helpUri="https://cwe.mitre.org/data/definitions/362.html"; - longDescription=""; - }; - { - name="416"; - ruleId="GO0016"; - helpText="Use After Free"; - shortDescription="Referencing memory after it has been freed can cause a program to crash, use unexpected values, or execute code. "; - helpUri="https://cwe.mitre.org/data/definitions/416.html"; - longDescription=""; - }; - { - name="476"; - ruleId="GO0017"; - helpText="NULL Pointer Dereference"; - shortDescription="A NULL pointer dereference occurs when the application dereferences a pointer that it expects to be valid, but is NULL, typically causing a crash or exit. "; - helpUri="https://cwe.mitre.org/data/definitions/476.html"; - longDescription=""; - }; - { - name="570"; - ruleId="GO0018"; - helpText="Expression is Always False"; - shortDescription="The software contains an expression that will always evaluate to false."; - helpUri="https://cwe.mitre.org/data/definitions/570.html"; - longDescription=""; - }; - { - name="571"; - ruleId="GO0019"; - helpText="Expression is Always True"; - shortDescription="The software contains an expression that will always evaluate to true."; - helpUri="https://cwe.mitre.org/data/definitions/571.html"; - longDescription=""; - }; - { - name="787"; - ruleId="GO0020"; - helpText="Out-of-bounds Write"; - shortDescription="The software writes data past the end, or before the beginning, of the intended buffer. "; - helpUri="https://cwe.mitre.org/data/definitions/787.html"; - longDescription=""; - }; - { - name="788"; - ruleId="GO0021"; - helpText="Access of Memory Location After End of Buffer"; - shortDescription="The software reads or writes to a buffer using an index or pointer that references a memory location after the end of the buffer. "; - helpUri="https://cwe.mitre.org/data/definitions/788.html"; - longDescription=""; - } -] - -(*Returns the information about a Rule. If the rule is not found, a default rule will be returned. *) -let getRuleInformation (searchName:string) = - match List.find_opt (fun rule -> rule.name=searchName) rules with - | None ->unknownRule ; - | Some rule -> rule - +open SarifRules (*matches the Goblint severity to the Sarif property level.*) diff --git a/src/util/sarifRules.ml b/src/util/sarifRules.ml new file mode 100644 index 0000000000..dff04893c3 --- /dev/null +++ b/src/util/sarifRules.ml @@ -0,0 +1,195 @@ + +type categoryInformation = { + name:string; + ruleId:string; + helpText:string; + shortDescription:string; + helpUri:string; + longDescription:string; +} +let unknownRule = { + name="Unknown"; + ruleId="GO000"; + helpText=""; + shortDescription=""; + helpUri="https://goblint.in.tum.de/home"; + longDescription=""; +} + +let rules = [ + { + name="Assert"; + ruleId="GO0001"; + helpText="Assert Error"; + shortDescription="This is an internal Goblint Category"; + helpUri="https://goblint.in.tum.de/home"; + longDescription=""; + }; + { + name="Analyzer"; + ruleId="GO0002"; + helpText="Analyzer Error"; + shortDescription="This is an internal Goblint Category"; + helpUri="https://goblint.in.tum.de/home"; + longDescription=""; + }; + { + name="Cast"; + ruleId="GO0003"; + helpText="Cast Error"; + shortDescription="This is an internal Goblint Cast Error, most likely not indicating a problem in the analyzed program."; + helpUri="https://goblint.in.tum.de/home"; + longDescription=""; + }; + { + name="Deadcode"; + ruleId="GO0004"; + helpText="Deadcode"; + shortDescription="This code is never used in the program."; + helpUri="https://goblint.in.tum.de/home"; + longDescription=""; + }; + { + name="Race"; + ruleId="GO0005"; + helpText="A race condition"; + shortDescription="The program contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently. "; + helpUri="https://goblint.in.tum.de/home"; + longDescription=""; + }; + { + name="Overflow"; + ruleId="GO0006"; + helpText="Integer Overflow"; + shortDescription="Result of arithmetic operation might be outside of the valid range. "; + helpUri="https://en.wikipedia.org/wiki/Integer_overflow"; + longDescription=""; + }; + { + name="DivByZero"; + ruleId="GO0007"; + helpText="Division by zero"; + shortDescription="Division by zero can result in undefined behaviour."; + helpUri="https://goblint.in.tum.de/home"; + longDescription=""; + }; + { + name="Implementation"; + ruleId="GO0008"; + (*TODO is this correct? *) + helpText="Implementation of function might not be present on all versions of the target platform."; + shortDescription=" Implementation of function might not be present on all versions of the target platform."; + helpUri="https://goblint.in.tum.de/home"; + longDescription=""; + }; + { + name="Machine"; + ruleId="GO0009"; + helpText="TODO"; + shortDescription="TODO "; + helpUri="https://goblint.in.tum.de/home"; + longDescription=""; + }; + { + name="NullPointerDereference"; + ruleId="GO0010"; + helpText="Nullpointer dereference"; + shortDescription="A NULL pointer dereference occurs when the application dereferences a pointer that it expects to be valid, but is NULL, typically causing a crash or exit. "; + helpUri="https://cwe.mitre.org/data/definitions/476.html"; + longDescription=""; + }; + { + name="UseAfterFree"; + ruleId="GO0011"; + helpText="TODO"; + shortDescription="TODO "; + helpUri="https://goblint.in.tum.de/home"; + longDescription=""; + }; + { + name="PastEnd"; + ruleId="GO0012"; + helpText="TODO"; + shortDescription="TODO "; + helpUri="https://goblint.in.tum.de/home"; + longDescription=""; + }; + { + name="BeforeStart"; + ruleId="GO0013"; + helpText="TODO"; + shortDescription="TODO "; + helpUri="https://goblint.in.tum.de/home"; + longDescription=""; + }; + { + name="Unknown Aob"; + ruleId="GO0014"; + helpText="Array out of Bounds Error"; + shortDescription="Array out of Bounds Error "; + helpUri="https://goblint.in.tum.de/home"; + longDescription=""; + }; + { + name="362"; + ruleId="GO015"; + helpText="Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')"; + shortDescription="The program contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently. "; + helpUri="https://cwe.mitre.org/data/definitions/362.html"; + longDescription=""; + }; + { + name="416"; + ruleId="GO0016"; + helpText="Use After Free"; + shortDescription="Referencing memory after it has been freed can cause a program to crash, use unexpected values, or execute code. "; + helpUri="https://cwe.mitre.org/data/definitions/416.html"; + longDescription=""; + }; + { + name="476"; + ruleId="GO0017"; + helpText="NULL Pointer Dereference"; + shortDescription="A NULL pointer dereference occurs when the application dereferences a pointer that it expects to be valid, but is NULL, typically causing a crash or exit. "; + helpUri="https://cwe.mitre.org/data/definitions/476.html"; + longDescription=""; + }; + { + name="570"; + ruleId="GO0018"; + helpText="Expression is Always False"; + shortDescription="The software contains an expression that will always evaluate to false."; + helpUri="https://cwe.mitre.org/data/definitions/570.html"; + longDescription=""; + }; + { + name="571"; + ruleId="GO0019"; + helpText="Expression is Always True"; + shortDescription="The software contains an expression that will always evaluate to true."; + helpUri="https://cwe.mitre.org/data/definitions/571.html"; + longDescription=""; + }; + { + name="787"; + ruleId="GO0020"; + helpText="Out-of-bounds Write"; + shortDescription="The software writes data past the end, or before the beginning, of the intended buffer. "; + helpUri="https://cwe.mitre.org/data/definitions/787.html"; + longDescription=""; + }; + { + name="788"; + ruleId="GO0021"; + helpText="Access of Memory Location After End of Buffer"; + shortDescription="The software reads or writes to a buffer using an index or pointer that references a memory location after the end of the buffer. "; + helpUri="https://cwe.mitre.org/data/definitions/788.html"; + longDescription=""; + } +] + +(*Returns the information about a Rule. If the rule is not found, a default rule will be returned. *) +let getRuleInformation (searchName:string) = + match List.find_opt (fun rule -> rule.name=searchName) rules with + | None ->unknownRule ; + | Some rule -> rule From 7d9040e420f389e4a00750185652fc0d66adb00d Mon Sep 17 00:00:00 2001 From: Simmo Saan Date: Wed, 3 Nov 2021 13:51:47 +0200 Subject: [PATCH 51/56] Move Sarif types to SarifType module --- src/framework/analyses.ml | 7 +- src/util/sarif.ml | 168 ++------------------------------------ src/util/sarifType.ml | 142 ++++++++++++++++++++++++++++++++ 3 files changed, 152 insertions(+), 165 deletions(-) create mode 100644 src/util/sarifType.ml diff --git a/src/framework/analyses.ml b/src/framework/analyses.ml index b9acb9c8d4..ebb9fcb3ba 100644 --- a/src/framework/analyses.ml +++ b/src/framework/analyses.ml @@ -8,7 +8,6 @@ module GU = Goblintutil module M = Messages module S = Sarif -module SarifLog = Sarif.SarifLog (** Analysis starts from lists of functions: start functions, exit functions, and * other functions. *) @@ -215,7 +214,7 @@ struct BatFile.with_temporary_out ~mode:[`create;`text;`delete_on_exit] write_file else let f = BatIO.output_channel out in - write_file f (get_string "outfile") + write_file f (get_string "outfile") | "json" -> let open BatPrintf in let module SH = BatHashtbl.Make (Basetype.RawStrings) in @@ -262,10 +261,10 @@ struct Printf.printf "Done in %fs!\n" t1 *) | "sarif" -> let open BatPrintf in - let debugMessage= + let debugMessage= printf "Writing sarif to temp. file: %s\n%!" (get_string "outfile"); in - debugMessage; + debugMessage; Yojson.Safe.pretty_to_channel ~std:true out (Sarif.to_yojson (List.rev !Messages.Table.messages_list)); | "json-messages" -> Yojson.Safe.pretty_to_channel ~std:true out (Messages.Table.to_yojson ()) diff --git a/src/util/sarif.ml b/src/util/sarif.ml index 65db81a583..46b324dd24 100644 --- a/src/util/sarif.ml +++ b/src/util/sarif.ml @@ -4,8 +4,11 @@ open GobConfig module Category = MessageCategory module GU = Goblintutil +open SarifType open SarifRules +module Region = SarifType.Region (* TODO: why is this needed if SarifType is opened? *) + (*matches the Goblint severity to the Sarif property level.*) let severityToLevel (severity:Messages.Severity.t)= match severity with @@ -15,138 +18,6 @@ let severityToLevel (severity:Messages.Severity.t)= match severity with | Debug -> "none" | Success -> "none" -module InvocationObject = -struct - type t = { - commandLine:string; - executionSuccessful:bool; - - } [@@deriving to_yojson] - - -end -(*endColumn and endLine are not produced by Goblint yet, however the Github action uses these properties. *) -module Region = -struct - type t = { - startLine:int; - startColumn:int; - endColumn:int; - endLine:int; - } [@@deriving to_yojson] - - -end -module ArtifactLocation = -struct - type t = { - uri:string; - - } [@@deriving to_yojson] - - -end -module PhysicalLocation = -struct - type t = { - artifactLocation:ArtifactLocation.t; - region:Region.t; - - } [@@deriving to_yojson] -end - -(*This type represents the Sarif locationProperty. - It is needed twice, since Sarif requires differen keys names, depending on where it is used.*) -module LocationObject = -struct type t = { - location:ArtifactLocation.t; - - } [@@deriving to_yojson] -end - - -module Locations = -struct - type t = { - - physicalLocation:PhysicalLocation.t; - - } [@@deriving to_yojson] - -end -module SairfMessageObject = -struct - type t = { - text:string; - - } [@@deriving to_yojson] - - -end -module ReportingDescriptor = -struct - type t = { - ruleId:string; [@key "id"] - ruleName:string; [@key "name"] - helpUri:string; - help:SairfMessageObject.t; - shortDescription:SairfMessageObject.t; - fullDescription:SairfMessageObject.t; - - } [@@deriving to_yojson] - - -end - -module Driver = -struct - type t = { - name:string; - fullName:string; - informationUri:string; - organization:string; - version:string; - rules:ReportingDescriptor.t list - } [@@deriving to_yojson] - - -end -module Tool = -struct - type t = { - driver:Driver.t; - } [@@deriving to_yojson] - - -end - - -module ResultObject = -struct - type t = { - ruleId:string; - level:string; - message:SairfMessageObject.t; - locations:Locations.t list; - } [@@deriving to_yojson] - - -end - -module Run = -struct - type t = { - tool:Tool.t; - defaultSourceLanguage:string; - invocations:InvocationObject.t list; - artifacts:LocationObject.t list; - results:ResultObject.t list - }[@@deriving to_yojson] - - -end - - let createMessageObject (text:String.t) = { @@ -287,34 +158,9 @@ let runObject msgList= Run.defaultSourceLanguage="C"; Run.results=List.map createResult (List.take 5000 msgList); } -module SarifLog = -struct - type t = { - (* Sarif prefers numerical Versions, this could be a future addition to Goblint. *) - version:string; - schema :string [@key "$schema"]; - runs:Run.t list ; - } [@@deriving to_yojson] - -end - - -module Sarif = -struct - - type t = - | SarifLog (*[@name "sarifLog"]*) - [@@deriving yojson] - let sarifObject msgList={SarifLog.version="2.1.0"; - SarifLog.schema="https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.5.json"; - SarifLog.runs=[runObject msgList] }; - -end - - -let to_yojson msgList= [%to_yojson: SarifLog.t] (Sarif.sarifObject msgList) - - - +let sarifObject msgList={SarifLog.version="2.1.0"; + SarifLog.schema="https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.5.json"; + SarifLog.runs=[runObject msgList] } +let to_yojson msgList= [%to_yojson: SarifLog.t] (sarifObject msgList) diff --git a/src/util/sarifType.ml b/src/util/sarifType.ml new file mode 100644 index 0000000000..1e69ec8905 --- /dev/null +++ b/src/util/sarifType.ml @@ -0,0 +1,142 @@ + +module InvocationObject = +struct + type t = { + commandLine:string; + executionSuccessful:bool; + + } [@@deriving to_yojson] + + +end +(*endColumn and endLine are not produced by Goblint yet, however the Github action uses these properties. *) +module Region = +struct + type t = { + startLine:int; + startColumn:int; + endColumn:int; + endLine:int; + } [@@deriving to_yojson] + + +end +module ArtifactLocation = +struct + type t = { + uri:string; + + } [@@deriving to_yojson] + + +end +module PhysicalLocation = +struct + type t = { + artifactLocation:ArtifactLocation.t; + region:Region.t; + + } [@@deriving to_yojson] +end + +(*This type represents the Sarif locationProperty. + It is needed twice, since Sarif requires differen keys names, depending on where it is used.*) +module LocationObject = +struct type t = { + location:ArtifactLocation.t; + + } [@@deriving to_yojson] +end + + +module Locations = +struct + type t = { + + physicalLocation:PhysicalLocation.t; + + } [@@deriving to_yojson] + +end +module SairfMessageObject = +struct + type t = { + text:string; + + } [@@deriving to_yojson] + + +end +module ReportingDescriptor = +struct + type t = { + ruleId:string; [@key "id"] + ruleName:string; [@key "name"] + helpUri:string; + help:SairfMessageObject.t; + shortDescription:SairfMessageObject.t; + fullDescription:SairfMessageObject.t; + + } [@@deriving to_yojson] + + +end + +module Driver = +struct + type t = { + name:string; + fullName:string; + informationUri:string; + organization:string; + version:string; + rules:ReportingDescriptor.t list + } [@@deriving to_yojson] + + +end +module Tool = +struct + type t = { + driver:Driver.t; + } [@@deriving to_yojson] + + +end + + +module ResultObject = +struct + type t = { + ruleId:string; + level:string; + message:SairfMessageObject.t; + locations:Locations.t list; + } [@@deriving to_yojson] + + +end + +module Run = +struct + type t = { + tool:Tool.t; + defaultSourceLanguage:string; + invocations:InvocationObject.t list; + artifacts:LocationObject.t list; + results:ResultObject.t list + }[@@deriving to_yojson] + + +end + +module SarifLog = +struct + type t = { + (* Sarif prefers numerical Versions, this could be a future addition to Goblint. *) + version:string; + schema :string [@key "$schema"]; + runs:Run.t list ; + } [@@deriving to_yojson] + +end From 370ce693be5ff02f22e87be93ef3121563ed14c4 Mon Sep 17 00:00:00 2001 From: Simmo Saan Date: Wed, 3 Nov 2021 14:32:04 +0200 Subject: [PATCH 52/56] Rename Sarif types to match standard --- src/util/sarif.ml | 36 +++++----- src/util/sarifType.ml | 157 ++++++++++++++++++------------------------ 2 files changed, 85 insertions(+), 108 deletions(-) diff --git a/src/util/sarif.ml b/src/util/sarif.ml index 46b324dd24..6782112d78 100644 --- a/src/util/sarif.ml +++ b/src/util/sarif.ml @@ -21,7 +21,7 @@ let severityToLevel (severity:Messages.Severity.t)= match severity with let createMessageObject (text:String.t) = { - SairfMessageObject.text=text; + Message.text=text; } (*A reportingDescriptor offers a lot of information about a Goblint rule *) let createReportingDescriptor categoryInformation = @@ -37,14 +37,14 @@ let createReportingDescriptor categoryInformation = let transformToReportingDescriptor (id:String.t)= createReportingDescriptor (getRuleInformation id) -let (driverObject:Driver.t) = +let (driverObject:ToolComponent.t) = { - Driver.name="Goblint"; - Driver.fullName= "Goblint static analyser"; - Driver.informationUri="https://goblint.in.tum.de/home"; - Driver.organization="TUM - i2 and UTartu - SWS"; - Driver.version=Version.goblint; - Driver.rules=List.map transformToReportingDescriptor (List.map (fun rule -> rule.name) rules) + ToolComponent.name="Goblint"; + ToolComponent.fullName= "Goblint static analyser"; + ToolComponent.informationUri="https://goblint.in.tum.de/home"; + ToolComponent.organization="TUM - i2 and UTartu - SWS"; + ToolComponent.version=Version.goblint; + ToolComponent.rules=List.map transformToReportingDescriptor (List.map (fun rule -> rule.name) rules) } let (toolObject:Tool.t) = { @@ -75,9 +75,9 @@ let trimFile (path:string) = if get_string "removePath" == "" then path else "./"^(String.sub path lengthRemove ((String.length path)-lengthRemove) ) -let createArtifactLocationObject (uri:string) = +let createArtifact (uri:string) = { - LocationObject.location={ + Artifact.location={ ArtifactLocation.uri=trimFile uri; } } @@ -103,7 +103,7 @@ let createPhysicalLocationObject (piece:Messages.Piece.t) = } in { - Locations.physicalLocation={ + Location.physicalLocation={ PhysicalLocation.artifactLocation= createArtifactObject (trimFile (deOptionalizeLocation piece).file); PhysicalLocation.region=createRegionObject ((deOptionalizeLocation piece).line,(deOptionalizeLocation piece).column); } @@ -122,10 +122,10 @@ let createResult (message:Messages.Message.t) = | Group {group_text = n; pieces = e} ->n in { - ResultObject.ruleId=(getRuleInformation (getCategoryInformationID message.tags)).ruleId; - ResultObject.level=severityToLevel message.severity; - ResultObject.message=createMessageObject (getMessage message.multipiece); - ResultObject.locations=createLocationsObject message.multipiece; + Result.ruleId=(getRuleInformation (getCategoryInformationID message.tags)).ruleId; + Result.level=severityToLevel message.severity; + Result.message=createMessageObject (getMessage message.multipiece); + Result.locations=createLocationsObject message.multipiece; } let getFileLocation (multipiece:Messages.MultiPiece.t)= @@ -150,10 +150,10 @@ let collectAllFileLocations (msgList:Messages.Message.t list)= let runObject msgList= { Run.invocations=[{ - InvocationObject.commandLine=String.concat ", " (BatArray.to_list BatSys.argv) ; - InvocationObject.executionSuccessful=true; + Invocation.commandLine=String.concat ", " (BatArray.to_list BatSys.argv) ; + Invocation.executionSuccessful=true; }]; - Run.artifacts= List.map createArtifactLocationObject (collectAllFileLocations msgList); + Run.artifacts= List.map createArtifact (collectAllFileLocations msgList); Run.tool=toolObject; Run.defaultSourceLanguage="C"; Run.results=List.map createResult (List.take 5000 msgList); diff --git a/src/util/sarifType.ml b/src/util/sarifType.ml index 1e69ec8905..effb7caaa1 100644 --- a/src/util/sarifType.ml +++ b/src/util/sarifType.ml @@ -1,142 +1,119 @@ -module InvocationObject = +module Invocation = struct type t = { - commandLine:string; - executionSuccessful:bool; - - } [@@deriving to_yojson] - - + commandLine: string; + executionSuccessful: bool; + } [@@deriving to_yojson] end + (*endColumn and endLine are not produced by Goblint yet, however the Github action uses these properties. *) module Region = struct type t = { - startLine:int; - startColumn:int; - endColumn:int; - endLine:int; - } [@@deriving to_yojson] - - + startLine: int; + startColumn: int; + endColumn: int; + endLine: int; + } [@@deriving to_yojson] end + module ArtifactLocation = struct type t = { - uri:string; - - } [@@deriving to_yojson] - - + uri: string; + } [@@deriving to_yojson] end + module PhysicalLocation = struct type t = { - artifactLocation:ArtifactLocation.t; - region:Region.t; - - } [@@deriving to_yojson] + artifactLocation: ArtifactLocation.t; + region: Region.t; + } [@@deriving to_yojson] end -(*This type represents the Sarif locationProperty. - It is needed twice, since Sarif requires differen keys names, depending on where it is used.*) -module LocationObject = -struct type t = { - location:ArtifactLocation.t; - - } [@@deriving to_yojson] +module Artifact = +struct + type t = { + location: ArtifactLocation.t; + } [@@deriving to_yojson] end - -module Locations = +module Location = struct type t = { - - physicalLocation:PhysicalLocation.t; - - } [@@deriving to_yojson] - + physicalLocation: PhysicalLocation.t; + } [@@deriving to_yojson] end -module SairfMessageObject = + +module Message = struct type t = { - text:string; - - } [@@deriving to_yojson] - - + text: string; + } [@@deriving to_yojson] end + module ReportingDescriptor = struct type t = { - ruleId:string; [@key "id"] - ruleName:string; [@key "name"] - helpUri:string; - help:SairfMessageObject.t; - shortDescription:SairfMessageObject.t; - fullDescription:SairfMessageObject.t; - - } [@@deriving to_yojson] - - + ruleId: string; [@key "id"] + ruleName: string; [@key "name"] + helpUri: string; + help: Message.t; + shortDescription: Message.t; + fullDescription: Message.t; + } [@@deriving to_yojson] end -module Driver = +module ToolComponent = struct type t = { - name:string; - fullName:string; - informationUri:string; - organization:string; - version:string; - rules:ReportingDescriptor.t list - } [@@deriving to_yojson] - - + name: string; + fullName: string; + informationUri: string; + organization: string; + version: string; + rules: ReportingDescriptor.t list; + } [@@deriving to_yojson] end + module Tool = struct type t = { - driver:Driver.t; - } [@@deriving to_yojson] - - + driver: ToolComponent.t; + } [@@deriving to_yojson] end - -module ResultObject = +module Result = struct type t = { - ruleId:string; - level:string; - message:SairfMessageObject.t; - locations:Locations.t list; - } [@@deriving to_yojson] - - + ruleId: string; + level: string; + message: Message.t; + locations: Location.t list; + } [@@deriving to_yojson] end +let result_to_yojson = Result.to_yojson (* workaround for ppx_deriving problem on Result *) + module Run = struct type t = { - tool:Tool.t; - defaultSourceLanguage:string; - invocations:InvocationObject.t list; - artifacts:LocationObject.t list; - results:ResultObject.t list - }[@@deriving to_yojson] - - + tool: Tool.t; + defaultSourceLanguage: string; + invocations: Invocation.t list; + artifacts: Artifact.t list; + results: (Result.t [@to_yojson result_to_yojson]) list; (* workaround for ppx_deriving problem on Result *) + } [@@deriving to_yojson] end +(* sarif prefix explicit in standard *) module SarifLog = struct type t = { - (* Sarif prefers numerical Versions, this could be a future addition to Goblint. *) - version:string; - schema :string [@key "$schema"]; - runs:Run.t list ; - } [@@deriving to_yojson] - + version: string; + schema: string [@key "$schema"]; + runs: Run.t list; + } [@@deriving to_yojson] end From d356c393d09c2753b96f3d429c157b62f7a724aa Mon Sep 17 00:00:00 2001 From: Simmo Saan Date: Wed, 3 Nov 2021 14:34:57 +0200 Subject: [PATCH 53/56] Remove removePath hack for Sarif --- src/maingoblint.ml | 1 - src/util/defaults.ml | 2 -- src/util/sarif.ml | 13 ++----------- 3 files changed, 2 insertions(+), 14 deletions(-) diff --git a/src/maingoblint.ml b/src/maingoblint.ml index 1fd65186a2..308e533cea 100644 --- a/src/maingoblint.ml +++ b/src/maingoblint.ml @@ -90,7 +90,6 @@ let option_spec_list = [ "-o" , Arg.String (set_string "outfile"), "" ; "-v" , Arg.Unit (fun () -> set_bool "dbg.verbose" true; set_bool "printstats" true), "" ; "-I" , Arg.String (set_string "includes[+]"), "" - ; "-R" , Arg.String (set_string "removePath"), "" ; "-IK" , Arg.String (set_string "kernel_includes[+]"), "" ; "--set" , Arg.Tuple [Arg.Set_string tmp_arg; Arg.String (fun x -> set_auto !tmp_arg x)], "" ; "--sets" , Arg.Tuple [Arg.Set_string tmp_arg; Arg.String (fun x -> prerr_endline "--sets is deprecated, use --set instead."; set_string !tmp_arg x)], "" diff --git a/src/util/defaults.ml b/src/util/defaults.ml index f8f21f9102..dedbafb474 100644 --- a/src/util/defaults.ml +++ b/src/util/defaults.ml @@ -59,7 +59,6 @@ let printAllCategories ch = (* {4 category [Std]} *) let _ = () ; reg Std "outfile" "" "File to print output to." - ; reg Std "removePath" "" "For the Sarif Github action. This removes the leading path of the Uri. This is needed, because the Github action runs in a subdirectory." ; reg Std "includes" "[]" "List of directories to include." ; reg Std "kernel_includes" "[]" "List of kernel directories to include." ; reg Std "custom_includes" "[]" "List of custom directories to include." @@ -286,7 +285,6 @@ let default_schema = {schema| { "file" : "" } , "outfile" : {} - , "removePath" : {} , "includes" : {} , "kernel_includes" : {} , "custom_includes" : {} diff --git a/src/util/sarif.ml b/src/util/sarif.ml index 6782112d78..832802a5fc 100644 --- a/src/util/sarif.ml +++ b/src/util/sarif.ml @@ -1,8 +1,5 @@ (** The Sarif format is a standardised output format for static analysis tools. https://docs.oasis-open.org/sarif/sarif/v2.1.0/sarif-v2.1.0.html *) open Prelude -open GobConfig -module Category = MessageCategory -module GU = Goblintutil open SarifType open SarifRules @@ -68,17 +65,11 @@ let getCategoryInformationID (tags:Messages.Tags.t) = |Category cat-> MessageCategory.categoryName cat | CWE c-> "" (*this case should not be reachable *) -(* for the github action. Removes leading directory.*) -let trimFile (path:string) = - let lengthRemove = (String.length (get_string "removePath")) - in - if get_string "removePath" == "" then path else - "./"^(String.sub path lengthRemove ((String.length path)-lengthRemove) ) let createArtifact (uri:string) = { Artifact.location={ - ArtifactLocation.uri=trimFile uri; + ArtifactLocation.uri=uri; } } let createArtifactObject (uri:string) = @@ -104,7 +95,7 @@ let createPhysicalLocationObject (piece:Messages.Piece.t) = in { Location.physicalLocation={ - PhysicalLocation.artifactLocation= createArtifactObject (trimFile (deOptionalizeLocation piece).file); + PhysicalLocation.artifactLocation= createArtifactObject (deOptionalizeLocation piece).file; PhysicalLocation.region=createRegionObject ((deOptionalizeLocation piece).line,(deOptionalizeLocation piece).column); } } From 7f9aa316bdc6cb315c75f66908ee300f355b6958 Mon Sep 17 00:00:00 2001 From: Simmo Saan Date: Wed, 3 Nov 2021 16:08:32 +0200 Subject: [PATCH 54/56] Remove scripts/run --- scripts/run/analyses.marshalled | Bin 478 -> 0 bytes scripts/run/cil.marshalled | Bin 22262 -> 0 bytes scripts/run/config.json | 1 - scripts/run/meta.json | 7 ------- scripts/run/solver.marshalled | Bin 1965 -> 0 bytes scripts/run/stats.marshalled | Bin 228 -> 0 bytes scripts/run/warnings.marshalled | Bin 21 -> 0 bytes 7 files changed, 8 deletions(-) delete mode 100644 scripts/run/analyses.marshalled delete mode 100644 scripts/run/cil.marshalled delete mode 100644 scripts/run/config.json delete mode 100644 scripts/run/meta.json delete mode 100644 scripts/run/solver.marshalled delete mode 100644 scripts/run/stats.marshalled delete mode 100644 scripts/run/warnings.marshalled diff --git a/scripts/run/analyses.marshalled b/scripts/run/analyses.marshalled deleted file mode 100644 index a7142f9880a40371ccf288f54429bb9d40dfda94..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 478 zcmYjOTT+8S5X8Fx=0#bR6U0Y+MU5tEeB%a&WGk@X?qVhXUcvwV@)#b#Q#piK~4E&J_@QLQ53^Q6tJ#{4TTsrcK7i3T2sy zHWMqP%1Bw@wGoqu(>z)Lp_`jD2VUB=EJl6@3>vTiU$eCiN3)d9Hlb`SKsL>*LVD}{0&Y0N@Bjb+ diff --git a/scripts/run/cil.marshalled b/scripts/run/cil.marshalled deleted file mode 100644 index 9588dfdf9445c5f41224f7d61940957012fe28aa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22262 zcmai62b@&Z^`1BL&a^jUO*EERuwX|(MFe$_B38s63!B+x7FL$sb$2PEMzP1npkOyH zAZV;;jKP**SsTF;HCCd*5~D_A5=#{2|9$73H}|oN`Oh!Gd*CW9=~r&9Oz$_MwPDKSN=s))zX?s9{mL!n z=F?_W+WU1hv^TZ!%hvklrk2jS&dTJrx;+LB8Z^G4-|ho;ZER}q=-jn3y|dCXez%6M zh1o=6??nH)y80iMZfk0;v~OiRI`#u9WW29q+}Pe)U)NsgoYLM>R~|pUz0%Rqy};j) zV*Cw!KN8@tQ!R~C)_%d5>`_(oknb8C5gWqher zg*Md4-=tcq3tJl-gMr3Cfy$z_z1t6Jh^?xnpNEJooXE%^ZLMt$ty5Y$o144mjZkfO zn|BCC^8;x+S4-uvwWDES%yMVz@I+cmVdbaWC9R`q^{EoCsSTB?Mt zlh!h^jwVdZ--Yv<!&;>FA#44VfYYv z3b;i6Fwyi{+is;5PI6W_6|e)0MXSMv)HXRYnR0ujt}?x0V!35Pr4GSwcrCLK?=+x? z8+w|dV@rl0*X^%Ty)W=rQ`1n_a{wD*?XwLQvwdTGWqKRb6h+PwFRL@2jTtj8@xvKk z4lX@4z-uH`lqBfR@S9Uz_1J8qu=e@?$ z`F%&z1SG&Xp<5bwScEz~D&EzO!6RUBurYYZ7{m^?#&UfJkUXo!dsaNIvyDc4NigN( z)S?LEM29DD7?!|biL>8w;0`t1vR*3JP6ftV@euhUe|{Ob!wmN)htor`7Sih|5jZFp z;ob!9aKpWBIJYNUY~LF&=oY~cFcM=7_Rjx+4FC+PMXdtv;{6c_1N{pO##;NI#=s@d9mrrSYMLYhQY7@h!0;@j(60=Gco7{(s9ric z%k7=rlFU$IGA&7=JVhjvKp$o8M6a1T)6ziysR>OYv?Y!rDGfauaTw z#1Q%-K|x z-UG^H43^C?IRs2jG$scblh}r5b_N#DDU0L9d(k0}2J$3B9%;y!m$jgLt}C}sfC)~n zDvCOv2vArQOY&z1LK3h>eirW8B+4#x=wv-mVZAHKpBu{U*;*jt5s`#i5v&O?9`F=A z!OhKtH8fYs?Ep;ExlLW*uVSt%$7cl6?+`wu+MbwbYoplpB{y>vwd zitUclypF!y;$YyAs5jV5gT)q8Qx8P0b3JFyQacD{HIJ1iq##l%LD&#g*0OP;6wp?1~HbRl42 zJuArtCel@7wapF?B675pcK{UDu#&v(2lS+QW~iPINRru~>GoS-!`fAnzcK9pNN4uI zbVoSJ4+9+*v66hSw`8Qly33MFRPr;Dd`P`$nRs7nW4R<*D3~tKfLmC-O7bb=79|<1 zp5oJg$SLsxU||6($>$7)lTL%32Guz3F^78ehX|^>q_#!Hig)JsK*UpE1)?-Q&~xV zL+w*}ct?##Dh(cCohvEdcnq!`RORMr<WWeI&WevD*Ud!rE9;n;ScK1)vTQ zZa421u)}Q->LHZO0gbe+p%#?UU58fLVc^I@(~d;IGw6 z@^#g;0Xxabs{_y~?9|BybRn=7%qR|JWhAZ|SLrn(i42Y(2CmAZX ziPqEtv!t$4MHWf&MQz*)9kp?rq?jce$3On*giVkgyOGGbmt`X5aqB{>7 zEA8c`jtV@h(uQO%^@L9CaY^C91wS+`3M(&ho)OWlqT2;}fwK+R*MPA#>gd#aa!K8!3hX5*JWYZEdrN8sPzKzCT&^%; zfN_c08<#?y#PP}lA&>=_jYbIc5?2~Aq&Kw8`!h)`RVYH>7@X~yifxqC z*$#`s&P(t};5tQ>oht^+yT;?t^j%%&HxYG>p(dEbSURP54SVg;J#TbLWloFTHTWF_ z^W>w*Qw{7~Bc41#YQ?$63<9q+;PhU=m``CV_{|PDlfdf@c$NXNg`%yiDfQ$j%}lBN zk*e|K;*VCps*2C+I0K{5^Aa~05mkDzqywe~i*=R7wc>A}K%FS+JTGyhA)`VsW-?>~ zEn3Imi7&llzWD2?0ym4V;oM&&zAKCU`Q-O2CyX~oEy8Que8XEBC8!8HTv5Dh}1QCl={g-^Eq&65q#Y-$OV!5d} zw5DROYjw@t$2om9?%izoDDK6MCcPo2(Qj7S?}~qm8tQ!}Q~IID|CL%Wu8?@!v~WSU zmVVM$FFD~K61K=-AM}ES&L7tL{u>UaA@3H0{lhIw`vVr)& zqoveZf|oA5#BD}I?_IN-Gtm#WKd1m9)gU3xDXLl773 zNW~5jpI5gwd=RmB8?k3^Y-3{wOMcl{u_Hv>f(!05y~JX}Mi-hrC(BC`PIiDZ(t*U? zW4MtfGnS&oQX>HS*7mX-PT;);JoJYb1(_t3i~Qgi!gy7HEhI-7Yz^S%qLh@~tfmrjzd|awY#@BSN9^1W)d=8xjrg#x-xrQmoc0ZTKt1{=tZs3>(V~Iy%R*w6SMa@~*O2De_n4pwsyaSu8acZyAfVL^bZ@7o2On zPuQadd)Ht%ae6#N#LXCRuR7c(#64!Xj~ve2FpP#gsVEP+MJLC)6D+H#6T)K@&85eh_*)svbc9>IB zAzdK&NdxB%9NP{E#*I+m4K7Z46Ok2^suNBBn9!$;*swPg_cqjhutNKY3{@m;l-`0+ z-U^f0y!XVzqrF?wyC`^PN$*7GOz$f4XKnP8^wy3Y-b3^ftjNhOdKEEdM_go~n2+j) z^kCEtsyK)YLNf&1Ojm1J$g=$B%F_g z2_J6o*#4-ii=QUx?bH-UN_q!X{%Dc^5*osfAg|>{9B#aN##r7255N?V_C~nlhoiC8ZmKgOq6s{8>dLR3H*#@Bl$mX#CYQ$OUB#UE4r(o zRi|=ByhHgBsi*Po1%t=pU3A9t`jY>?S8tL*wg)i$bF_PpmYj zu8SNH@!m_kVZaA^*);^xx@uRb7a8U;0^c;?QU{D2Zb}Q@?7;g`_0728N+aa(!zn&P z;9EvKWx)S&7GNLB@lGx{c?q7aa1DwwC?CzAe)^88fNSL?T`%tz$OiietgXgp)fj-mkp zBCU@}(_cxN`H_v*u=tJpgvD*c7NPnpw|+N@fGh3n0U3HTbR(Q8nm%mC-+RACz<%+(nw_WHcJS zXSlUQL&PA;)@YdN!(&rFuxdu5;rj-Sq9H^^PN#33m+^B3?&9y&T02X|a|}@Xc!>{; z!FD$Bp8G^AESx_Xyg?c%ttH{#3>cM!v5O~!aEQD|MGlcPs}~!r;gV+K1fp;mTifv2 zQAQLxLNZxJ>S(P8|8CHz9>j%7G~LeA+A1C40oK`sjmBwbwo*oiNm`%2XU0hSYsV2U zyLgF@jAQh+OKkV>N?`!4->O`WmvlQlJ#zx0j^lDHxqNI~jy5aCmO*z9Z{u;FmpQVw z^)n|E_le<7G~8N}RBZXo7-xH}2mfKPwbX;KJvLTmfU0~djO;X>Oo`mNH2x%~X>@$o ze3T;VoXAe%J~Ldq;bL||EvU~JGT{!HDVgn^&@&1Cr-4s5aLiXwI6>OUs_w<{BP4SH zk)Ip#JVW+$Pkp0=?uob^x#wjB{>y-u^cJZ{Pi8&06i95n#J>%2g#p~=4L2^YvnU8^ zMS`v;?mvdR)^Ka2V&VHBVdbB>S|@p{WUf;;x=qrrXyXpa9HWi9By$|N8ADu7dWkQL zxYfA#NG%b-GB-Gd@F>npd})xo4bn3}w*Z5JFPg*>V!krW{f3Ec$gm3Zx(Vt{>9+=qZc34?YSN?6p4NCbP%=+D>F*Fj(xc04}n1c2jsUM%v(wh)fyrBSZGsEYLBVb;5p1h;NY146;TM z)6o(yr83`fS+YAxMqdKR?jjl8zuDa+tCeAPcgeiY<{d>}J&9wji6zetGzA?l#Bkx^@L2@&NZwH5GKSm7aL!d~d<+6?R_pTY&m_CELRHi;#O4iq zlwsF$A&01z-KKU3Wlth3FxUxe5sBaG5VDi1+a%dtoyZEY1;aM<#Y5w@Yh zZZ??P8#NziZJ52r;ZU@B-j56y)s${2!aaor0ScN$CS^tG{n$`ZMY%R9dS`T>EyYcPkB%-!m*t6eqy+&oJ5YSE>qvyy0!v8 zbG*Z|p7b^`d{j^NI0Lv4N9jVYkgQ(kWZ#zT@cUlpk z+&>K$n=orl9$XvggjY+J#|=VyjIFPicT4sb8avlt zvbSNZ4d0d6ZH?I3u(8YlzvKc^-)Yb7BiY|5klQD>7m?c;at}koIz5h2sEujv;I!SB zI2JNwGQ@B(HxA!V07h%`+`*F5E6v=YlIx?3bhzZGuyHt;?D`rp+Noj1S7>Y=TeLPJ zcx1G(#O+|XF@{_7Xr+TrQJamE9CIKWeFC978gYE@8EAcra~ZRy!6!&=XH~pOaxPfr zG+6FrT%us@~0}goBu3~3N z_CZyDw&c#$#+6)M{gA;da@)}R+rO!f>up(9@8Jm5x3 z+ucyto3z+piNG&w+RJ$9F!pjN#9pg2xlM96sM{-s^ZmM@I!eq0+w;vJ)=5_$NJ@T3hf}GW0Wi z82&m)Zs7m_7fYI28k(n!uXOYa8SXaG^Nt-wt@lxhONaR>&l@|e>z04&A1m2*a+$xg z4I;BH9g!RR{|jMR+|jSSGQqU$H+b-_om21|!=`d`NAEw3;(5;wqY6V*g;JMF-gB-q$Rs0PO zZC|VZ!oBg;=B4W5P3lfb*hfZ`mLBA9<0WNe=>Wi@p^ue_A5rRh_E0wZ8)~(EMwBG) zmzIw8_x6&z3@?oWa$a=}#`rDr(xd#6m)w8&fu$}VSwI(m{y(zI$2s=`-zx;$1J_iB zm_z)-z2s&iOC!2`oUNfk{(7b1T|RySftUL5&wl)8I4shITC~eQ6#w8qh0@Z|{>h&A zui+rp>EdgDUH;H6e}__abeDfjmp=wWyZnv1{B62?a0j}7$)5z9E%m%U*#wM_cKBH= z`NO-ak{>Ji`ceth9;60IzQTT-{O^O#eJJ^fX#bn-FC`CFp#DngJ;}Ey^+!_AOa4@L zJxyYndgygRwF^I%I zlD}TZ_A!!w8SRtUu9H0O zCKR><>76CdM_y#J4(atJzk)Qr$gIK_nbneiN2&ji`bzTevg=b4pG*D&5+9QISn{}@ z2lWc6*CdbA5Y#eK&q@9>5=%)uE_vS0g8VhfJ0$-Fi5p1VB>At=Uc~mVCC_U+e(=>5 z{A#Y`zps5Wo!^`;fv5d#q&g(_0Wz6 zZ5T@1hh6(hfZ`3E{YVXvK(l|)8AaSMyqqM7@R7HY=Ox8%!qa`>LBe})WM@uj! zl)ER%y(Ks@B!5D3GYO6{q)$2{0jj{oe3hk&Cyo-FNMa?4_azvI_9twACPA4neDKwH zelpUp2P(teksADXjj?3Qi3Ox;V($dl;9~2 zw{<2;2Kfp@5D8{i3j`6xIy~7P6!RDQsZK;4^#? z{7VWyUMv9}AXp^@-1&fdm(&MRz(oou&MkOb3R{ri0TC>f!q#ZN$o9)p*p?mi{NNEO z^aYU|3?eyHl6#{)lx_Sn6X_g=(eZ=1QeYiInvps4K%zWioVXtG|OeEEzNnjs>$0z~c|DYPz@JkR)iS_`I0kaOp@%KIVC^Glpf4;DDo~z{4tg0Ev-O;9-?ya*=#|=_pD5 z(eqa7;J)nNNeY@wZA4-dDRiq;E>IQ=^faJ&poWNyJ+%yN?x_s+)N|~3m&6BBc#)XQ z+oV=X;pK2v8Ln3b>-8!-?EurDMeg=p=%bYE2OxyQZ!roaw+b{E_!}?rWE^=m_g!9DI#S8RVFoFiYUcF9Zc#l zDKcj|iS0Tmve0DT=A^e2&M-|ArC}n?nl>S^xfDmSr$Ay|DISD24+Eq@#Y52{Ji5}J z6vv<=8gwK(=ufgrib$3~(Ix_$gcs)cg87QPCq>PcmXUZ)isPsgKNzrp-z}12nZz|D zu9qV7rTJ_xl;Q*(HkZ^jQbfLl0Ek$v^)~}{ipdKu79@3{=hfpC6we!sFK{W6x&T8j ztqq-pA5}*~FN=omZ9^}G#B(U)d?_NIlFQkiEk)*2ssQaSu)AhdQb(#@isxwGa8jeB zcz!r^dy+d!@gh!%9w_iY&8dW@6WI51^l-zW`G-60~_x;dhnAhqQ;g(H|^DW>WqxB(TvQ q<;3^}J;{eBJ%Kh88NaU-pVA&~JY<8#XO-g4L;6=_I)#syO#B}tq)kWw diff --git a/scripts/run/config.json b/scripts/run/config.json deleted file mode 100644 index cad618748c..0000000000 --- a/scripts/run/config.json +++ /dev/null @@ -1 +0,0 @@ -{"ana":{"path_sens":["OSEK","OSEK2","mutex","malloc_null","uninit","apron"],"context":{"widen":false},"apron":{"context":true},"base":{"context":{"interval":true,"int":true,"non-ptr":true}},"arrayoob":false,"wp":false,"specification":"","sv-comp":{"functions":false,"enabled":false},"mutex":{"disjoint_types":true},"opt":{"equal":true,"hashcons":true},"arinc":{"merge_globals":false,"export":true,"validate":true,"simplify":true,"assume_success":true},"pml":{"debug":true},"spec":{"file":""},"file":{"optimistic":false},"int":{"refinement":"never","congruence":false,"enums":false,"interval":false,"def_exc":true},"osek":{"def_header":true,"flags":[],"safe_isr":[],"safe_task":[],"safe_vars":[],"warnfiles":false,"names":[],"check":false,"intrpts":false,"tasksuffix":"","isrsuffix":"","taskprefix":"function_of_","isrprefix":"function_of_","defaults":true,"oil":""},"cont":{"class":"","localclass":false},"ctx_insens":["OSEK2","stack_loc","stack_trace_set"],"activated":["expRelation","base","threadid","threadflag","threadreturn","escape","mutex","mallocWrapper"]},"outfile":"/home/alex/Documents/git/analyzer/testResults/99-tutorials/02-first-extend.sarif","result":"sarif","warn_at":"early","warn":{"race":true,"success":true,"debug":true,"info":true,"warning":true,"error":true,"unknown":true,"analyzer":true,"deadcode":true,"cast":true,"integer":true,"behavior":true,"assert":true},"gobview":true,"dbg":{"verbose":true,"print_dead_code":true,"cfg":{"loop-clusters":false},"cilcfgdot":false,"test":{"domain":false},"regression":false,"warn_with_context":false,"limit":{"widen":0},"slice":{"n":10,"on":false},"print_wpoints":false,"solver-progress":false,"backtrace-signal":"sigusr2","solver-signal":"sigusr1","solver-stats-interval":10,"timeout":"0","cilout":"","dump":"","uncalled":true,"showtemps":false,"trace":{"context":false},"debug":false},"g2html":false,"exp":{"cfgdot":true,"gcc_path":"/usr/bin/gcc","partition-arrays":{"smart-join":false,"partition-by-const-on-return":false,"keep-expr":"first","enabled":false},"architecture":"64bit","witness":{"stack":true,"uncil":false,"minimize":false,"invariant":{"nodes":"all"},"id":"node","path":"witness.graphml"},"ptr-arith-safe":false,"uninit-ptr-safe":false,"fast_global_inits":true,"solver":{"slr4":{"restart_count":1},"td3":{"space_restore":true,"space_cache":true,"space":false,"side_widen":"sides","term":true}},"basic-blocks":false,"no-narrow":false,"extraspecials":[],"g2html_path":".","list-type":false,"precious_globs":[],"globs_are_top":false,"single-threaded":false,"volatiles_are_top":true,"malloc":{"wrappers":["kmalloc","__kmalloc","usb_alloc_urb","__builtin_alloca","kzalloc"],"fail":false},"forward":false,"unique":[],"region-offsets":false,"failing-locks":false,"earlyglobs":false,"mincfg":false,"apron":{"privatization":"mutex-meet"},"priv-distr-init":false,"priv-prec-dump":"","privatization":"protection-read","lower-constants":true},"trans":{"expeval":{"query_file_name":""},"activated":[]},"sem":{"int":{"signed_overflow":"assume_top"},"builtin_unreachable":{"dead_code":false},"unknown_function":{"invalidate":{"globals":true},"spawn":true}},"incremental":{"wpoint":false,"stable":true,"save":false,"load":false},"compare_runs":[],"load_run":"","save_run":"","phases":[],"interact":{"paused":false,"enabled":false,"out":"result"},"colors":"auto","nonstatic":false,"allfuns":false,"solverdiffs":false,"comparesolver":"","solver":"td3","dump_globs":false,"kernel":false,"cppflags":"","tempDir":"","keepcpp":false,"allglobs":false,"otherfun":[],"exitfun":[],"mainfun":["main"],"verify":true,"printstats":false,"justcfg":false,"justcil":false,"custom_libc":false,"custom_incl":"","custom_includes":[],"kernel_includes":[],"includes":[]} \ No newline at end of file diff --git a/scripts/run/meta.json b/scripts/run/meta.json deleted file mode 100644 index 3271bc3a3c..0000000000 --- a/scripts/run/meta.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "command": - "../goblint --sarif -o /home/alex/Documents/git/analyzer/testResults/99-tutorials/02-first-extend.sarif /home/alex/Documents/git/analyzer/tests/regression/99-tutorials/02-first-extend.c", - "version": "heads/integrationSarif-0-g8c1794b4-dirty", - "timestamp": 1633641073.0, - "localtime": "2021-10-07 23:11:13" -} \ No newline at end of file diff --git a/scripts/run/solver.marshalled b/scripts/run/solver.marshalled deleted file mode 100644 index ace7fb80d6591c484f3ac5a3b6546d7cdbaec264..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1965 zcmchYQEU`N7{_OJzq8jUh@pXKwWWz#LoG`oM%$v!_V%u&LKCPEc@VgiZMpWkhqrg$ z(Ff9pCM3SNl<-g=yMv?$>Leel6p&u?z`%7U%b7bm&f znaO;?W_Rq^$+L`AO)$paW9*@K>30C#&M;FL6AQEgIz{2&=i&%DVa8r!&&F-r zOlKw?nk}p~^9RzVZ6{LJ3B!wy=)%>jH){J+!=@Hbnt9Dg^<{@mD`RT|iHsJv;>m*} zW?D;FeaY-T)7HEV*X`$gXUq|tx6wwr5ID7^lCvQX56j)%X!W)SZ=5l0%9S<;d@`-I zwK~*Xzov>?M$X$ug%I9URB-8Ir79z^c(7}~ZRCFM0AiNdi zGQu+IJw?p)ct*Hgu$lAUA~a}3SS@oQ)Cf^P+$|7yDNNL55&KC*o8@{F8EBmj)kucNXr_WC^$Ra@#C zNAT#%(SkSS(z=D|ibVlqsIV8$PoqnufBf|4An9~a9&n`v`c<-m4WYyC#e)2zxE=_q z_kucnC)CnkzcyW3W=&Pd%SO!`Gw%rKg#9lv$(^n0@*38^vbKszQ_4+N(HO)ZtX#m^ z|Ez)Bnph|Z+M&&NCZMu&@3%dB!!QB|A&+Q4E+7Yzh`lgG$a+j|YB;khH+`FV3S=!E zxdVr&u6{)Lh-#5~rxCtJ_(3>b2?`EN%b8;=-p~vd&B7+)|0G^RAz~VxB@dlL^|bhNQZc6 z35?!XWqb7X9ou`n7lX@6Ygmbu9HG)RRmNwpgk@^FMe}z#puzFpLFyA9*4>_)VWd>P un*>~jucVGkK^@al$3?kWkGi~D-?Q=f4MwB8jk8f#Ec!9LyY7GJ5z61OdB7?F diff --git a/scripts/run/stats.marshalled b/scripts/run/stats.marshalled deleted file mode 100644 index e15e4fcec2b769355273b09b3190f44826f8a75a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 228 zcmZpfx@;c<1H%O%mIvYnAkJHGKsCfa#LX~1qU<|^Ad9^i!+N^Sb#kB;{2Sl z%)E3ShN&Ol8|(Sl1I4t1^<46E^->E<6LWYNK5Sj^{n!CJ2M3^xPI^v$QesYgW?p7V zF%JWy@%@ATe;`tN$@zI@sYN9UCHV@@o<2MYAKji!w70MaX;UpoEGkarY4ABHm42BK tDCEGwz~I6Fb`{SK14l4pMhrKEk#Jqg(Zzv@fg^#z1*jARz#N7m2LM+AMeqOs diff --git a/scripts/run/warnings.marshalled b/scripts/run/warnings.marshalled deleted file mode 100644 index 66fc919b0b1cbee7c212bd929f4bfbdb094ab1ca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21 TcmZpfx@;c<0|O%v!+`?;Fo^=c From 9a8d3707815b5f48a2890256dd9a33dd342dc0e5 Mon Sep 17 00:00:00 2001 From: Simmo Saan Date: Wed, 3 Nov 2021 16:11:18 +0200 Subject: [PATCH 55/56] Clean up Sarif in Analyses --- src/framework/analyses.ml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/framework/analyses.ml b/src/framework/analyses.ml index 7d9175a98d..22caa840c3 100644 --- a/src/framework/analyses.ml +++ b/src/framework/analyses.ml @@ -7,8 +7,6 @@ open GobConfig module GU = Goblintutil module M = Messages -module S = Sarif - (** Analysis starts from lists of functions: start functions, exit functions, and * other functions. *) @@ -272,10 +270,7 @@ struct Printf.printf "Done in %fs!\n" t1 *) | "sarif" -> let open BatPrintf in - let debugMessage= - printf "Writing sarif to temp. file: %s\n%!" (get_string "outfile"); - in - debugMessage; + printf "Writing Sarif to file: %s\n%!" (get_string "outfile"); Yojson.Safe.pretty_to_channel ~std:true out (Sarif.to_yojson (List.rev !Messages.Table.messages_list)); | "json-messages" -> Yojson.Safe.pretty_to_channel ~std:true out (Messages.Table.to_yojson ()) From 2c52bfdecb4bd533c6ae43743b6b33fb94332f79 Mon Sep 17 00:00:00 2001 From: Simmo Saan Date: Wed, 3 Nov 2021 16:12:19 +0200 Subject: [PATCH 56/56] Revert Sarif whitespace changes to unrelated files --- src/incremental/makefileUtil.ml | 18 ++++++++---------- src/maingoblint.ml | 1 + 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/incremental/makefileUtil.ml b/src/incremental/makefileUtil.ml index c52e0ef923..4c123e00c3 100644 --- a/src/incremental/makefileUtil.ml +++ b/src/incremental/makefileUtil.ml @@ -9,7 +9,7 @@ let exec_command ?path (command: string) = let current_dir = Sys.getcwd () in (match path with | Some path -> - if Sys.file_exists path && Sys.is_directory path then Sys.chdir path + if Sys.file_exists path && Sys.is_directory path then Sys.chdir path else failwith ("Directory " ^ path ^ " does not exist!") | None -> ()); if GobConfig.get_bool "dbg.verbose" then print_endline ("executing command `" ^ command ^ "` in " ^ Sys.getcwd ()); @@ -18,7 +18,7 @@ let exec_command ?path (command: string) = try while true do let line = input_char std_out in - Buffer.add_char output line + Buffer.add_char output line done; assert false; with End_of_file -> @@ -33,7 +33,7 @@ let string_of_process_status = function | WSTOPPED n -> "was stopped by signal " ^ string_of_int n (* BFS for a file with a given suffix in a directory or any subdirectoy *) -let find_file_by_suffix (dir: string) (file_name_suffix: string) = +let find_file_by_suffix (dir: string) (file_name_suffix: string) = let list_files d = Array.to_list @@ Sys.readdir d in let dirs = Queue.create () in let rec search (dir: string) (files: string list) = match files with @@ -47,12 +47,11 @@ let find_file_by_suffix (dir: string) (file_name_suffix: string) = in search dir (list_files dir) -let run_cilly (path: string) = - +let run_cilly (path: string) = if Sys.file_exists path && Sys.is_directory path then ( (* We need to `make clean` if `make` was run manually, otherwise it would say there is nothing to do and cilly would not be run and no combined C file would be created. *) let _ = exec_command ~path "make clean" in - (try + (try while true do let comb = find_file_by_suffix path comb_suffix in if GobConfig.get_bool "dbg.verbose" then print_endline ("deleting " ^ comb); @@ -60,12 +59,11 @@ let run_cilly (path: string) = done with Failure e -> ()); (* Deleted all *_comb.c files in the directory *) (* Combine source files with make using cilly as compiler *) - let gcc_path = GobConfig.get_string "exp.gcc_path" in + let gcc_path = GobConfig.get_string "exp.gcc_path" in let (exit_code, output) = exec_command ~path ("make CC=\"cilly --gcc=" ^ gcc_path ^ " --merge --keepmerged\" " ^ "LD=\"cilly --gcc=" ^ gcc_path ^ " --merge --keepmerged\"") in - + print_string output; (* fail if make failed *) - if exit_code <> WEXITED 0 then + if exit_code <> WEXITED 0 then failwith ("Failed combining files. Make " ^ (string_of_process_status exit_code) ^ ".") - ) diff --git a/src/maingoblint.ml b/src/maingoblint.ml index 80f9ffbacc..b298837a41 100644 --- a/src/maingoblint.ml +++ b/src/maingoblint.ml @@ -291,6 +291,7 @@ let merge_preprocessed cpp_file_names = if get_bool "dbg.verbose" then print_endline "Parsing files."; let files_AST = List.rev_map Cilfacade.getAST cpp_file_names in remove_temp_dir (); + let cilout = if get_string "dbg.cilout" = "" then Legacy.stderr else Legacy.open_out (get_string "dbg.cilout") in