diff --git a/CHANGELOG.md b/CHANGELOG.md index be4779ad77..8d46ea2a0e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 8.7.1 + +### Fixed + +* Service: Removed deprecated Azure retention policy setting that was causing scaleset deployment errors [#3452](https://github.com/microsoft/onefuzz/pull/3452) + ## 8.7.0 ### Added diff --git a/CURRENT_VERSION b/CURRENT_VERSION index c0bcaebe8f..efeecbe2c5 100644 --- a/CURRENT_VERSION +++ b/CURRENT_VERSION @@ -1 +1 @@ -8.7.0 \ No newline at end of file +8.7.1 \ No newline at end of file diff --git a/README.md b/README.md index 010148dd3a..486dae6c15 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,20 @@ # OneFuzz +# IMPORTANT NOTICE + +**_Since September 2020 when OneFuzz was first open sourced, we’ve been on a journey to create a best-in-class orchestrator for running fuzzers, driving security and quality into our products._** + + +**_Initially launched by a small group in MSR, OneFuzz has now become a significant internal platform within Microsoft. As such, we are regretfully archiving the project to focus our attention on becoming a more deeply integrated service within the company. Unfortunately, we aren’t a large enough team to live in both the open-source world and the internal Microsoft world with its own unique set of requirements._** + +**_Our current plan is to archive the project in the next few months. That means we’ll still be making updates for a little while. Of course, even after it’s archived, you’ll still be able to fork it and make the changes you need. Once we’ve decided on a specific date for archiving, we’ll update this readme._** + +**_Thanks for taking the journey with us._** + +**_The OneFuzz team._** + +--- + [![Onefuzz build status](https://github.com/microsoft/onefuzz/workflows/Build/badge.svg?branch=main)](https://github.com/microsoft/onefuzz/actions/workflows/ci.yml?query=branch%3Amain) ## A self-hosted Fuzzing-As-A-Service platform diff --git a/contrib/onefuzz-job-azure-devops-pipeline/ado-work-items.json b/contrib/onefuzz-job-azure-devops-pipeline/ado-work-items.json index eb89fc019d..034d97cf15 100644 --- a/contrib/onefuzz-job-azure-devops-pipeline/ado-work-items.json +++ b/contrib/onefuzz-job-azure-devops-pipeline/ado-work-items.json @@ -13,6 +13,10 @@ "System.AreaPath": "OneFuzz-Ado-Integration", "System.Title": "{{report.task_id}}" }, + "ado_duplicate_fields": { + "System.Reason": "My custom value that means a work item is a duplicate", + "Custom.Work.Item.Field": "My custom value that means a work item is a duplicate" + }, "on_duplicate": { "increment": [], "comment": "DUP {{report.input_sha256}}
Repro Command:
 {{ repro_cmd }} 
", diff --git a/docs/notifications/ado.md b/docs/notifications/ado.md index 131986afba..09dd5b9072 100644 --- a/docs/notifications/ado.md +++ b/docs/notifications/ado.md @@ -51,6 +51,13 @@ clickable, make it a link. "System.Title": "{{ report.crash_site }} - {{ report.executable }}", "Microsoft.VSTS.TCM.ReproSteps": "This is my call stack: " }, + "ado_duplicate_fields": { + "System.Reason": "My custom value that means a work item is a duplicate", + "Custom.Work.Item.Field": "My custom value that means a work item is a duplicate" + // note: the fields and values below are checked by default and don't need to be specified + // "System.Reason": "Duplicate" + // "Microsoft.VSTS.Common.ResolvedReason": "Duplicate" + }, "comment": "This is my comment. {{ report.input_sha256 }} {{ input_url }}
{{ repro_cmd }}
", "unique_fields": ["System.Title", "System.AreaPath"], "on_duplicate": { diff --git a/src/ApiService/ApiService/OneFuzzTypes/Model.cs b/src/ApiService/ApiService/OneFuzzTypes/Model.cs index b839f52ddc..424669899a 100644 --- a/src/ApiService/ApiService/OneFuzzTypes/Model.cs +++ b/src/ApiService/ApiService/OneFuzzTypes/Model.cs @@ -689,6 +689,7 @@ public record AdoTemplate( List UniqueFields, Dictionary AdoFields, ADODuplicateTemplate OnDuplicate, + Dictionary? AdoDuplicateFields = null, string? Comment = null ) : NotificationTemplate { public async Task Validate() { @@ -704,8 +705,9 @@ public record RenderedAdoTemplate( List UniqueFields, Dictionary AdoFields, ADODuplicateTemplate OnDuplicate, + Dictionary? AdoDuplicateFields = null, string? Comment = null - ) : AdoTemplate(BaseUrl, AuthToken, Project, Type, UniqueFields, AdoFields, OnDuplicate, Comment); + ) : AdoTemplate(BaseUrl, AuthToken, Project, Type, UniqueFields, AdoFields, OnDuplicate, AdoDuplicateFields, Comment); public record TeamsTemplate(SecretData Url) : NotificationTemplate { public Task Validate() { diff --git a/src/ApiService/ApiService/onefuzzlib/notifications/Ado.cs b/src/ApiService/ApiService/onefuzzlib/notifications/Ado.cs index e05bb9bc24..3780bc1b2b 100644 --- a/src/ApiService/ApiService/onefuzzlib/notifications/Ado.cs +++ b/src/ApiService/ApiService/onefuzzlib/notifications/Ado.cs @@ -291,6 +291,7 @@ public static RenderedAdoTemplate RenderAdoTemplate(ILogger logTracer, Renderer original.UniqueFields, adoFields, onDuplicate, + original.AdoDuplicateFields, original.Comment != null ? Render(renderer, original.Comment, instanceUrl, logTracer) : null ); } @@ -535,7 +536,7 @@ public async Async.Task Process(IList<(string, string)> notificationInfo) { _logTracer.AddTags(new List<(string, string)> { ("MatchingWorkItemIds", $"{workItem.Id}") }); _logTracer.LogInformation("Found matching work item"); } - if (IsADODuplicateWorkItem(workItem)) { + if (IsADODuplicateWorkItem(workItem, _config.AdoDuplicateFields)) { continue; } @@ -575,13 +576,17 @@ public async Async.Task Process(IList<(string, string)> notificationInfo) { } } - private static bool IsADODuplicateWorkItem(WorkItem wi) { + private static bool IsADODuplicateWorkItem(WorkItem wi, Dictionary? duplicateFields) { // A work item could have System.State == Resolve && System.Reason == Duplicate // OR it could have System.State == Closed && System.Reason == Duplicate // I haven't found any other combinations where System.Reason could be duplicate but just to be safe // we're explicitly _not_ checking the state of the work item to determine if it's duplicate return wi.Fields.ContainsKey("System.Reason") && string.Equals(wi.Fields["System.Reason"].ToString(), "Duplicate", StringComparison.OrdinalIgnoreCase) || wi.Fields.ContainsKey("Microsoft.VSTS.Common.ResolvedReason") && string.Equals(wi.Fields["Microsoft.VSTS.Common.ResolvedReason"].ToString(), "Duplicate", StringComparison.OrdinalIgnoreCase) + || duplicateFields?.Any(fieldPair => { + var (field, value) = fieldPair; + return wi.Fields.ContainsKey(field) && string.Equals(wi.Fields[field].ToString(), value, StringComparison.OrdinalIgnoreCase); + }) == true // Alternatively, the work item can also specify a 'relation' to another work item. // This is typically used to create parent/child relationships between work items but can also // Be used to mark duplicates so we should check this as well. diff --git a/src/ApiService/IntegrationTests/JinjaToScribanMigrationTests.cs b/src/ApiService/IntegrationTests/JinjaToScribanMigrationTests.cs index 0ae3b11cb5..4033a05369 100644 --- a/src/ApiService/IntegrationTests/JinjaToScribanMigrationTests.cs +++ b/src/ApiService/IntegrationTests/JinjaToScribanMigrationTests.cs @@ -111,6 +111,7 @@ public async Async.Task OptionalFieldsAreSupported() { }, "{{ if org }} blah {{ end }}" ), + null, "{{ if org }} blah {{ end }}" ); @@ -137,6 +138,7 @@ public async Async.Task All_ADO_Fields_Are_Migrated() { }, "{% if org %} comment {% endif %}" ), + null, "{% if org %} comment {% endif %}" ); diff --git a/src/ApiService/Tests/OrmModelsTest.cs b/src/ApiService/Tests/OrmModelsTest.cs index 1aa7d2d163..956d0c30c5 100644 --- a/src/ApiService/Tests/OrmModelsTest.cs +++ b/src/ApiService/Tests/OrmModelsTest.cs @@ -232,6 +232,7 @@ from authToken in Arb.Generate>() from str in Arb.Generate() from fields in Arb.Generate>() from adoFields in Arb.Generate>() + from adoDuplicateFields in Arb.Generate>() from dupeTemplate in Arb.Generate() select new AdoTemplate( baseUrl, @@ -241,6 +242,7 @@ from dupeTemplate in Arb.Generate() fields, adoFields, dupeTemplate, + adoDuplicateFields, str.Get)); public static Arbitrary ArbTeamsTemplate() diff --git a/src/ApiService/Tests/TemplateTests.cs b/src/ApiService/Tests/TemplateTests.cs index 97d8641eb8..0d44732975 100644 --- a/src/ApiService/Tests/TemplateTests.cs +++ b/src/ApiService/Tests/TemplateTests.cs @@ -32,6 +32,11 @@ public class TemplateTests { // * Change "{% ... %}" in python to "{{ ... }}" private static readonly string _testString3 = "The fuzzing target ({{ job.project }} {{ job.name }} {{ job.build }}) reported a crash.
{{ if report.asan_log }} AddressSanitizer reported the following details:
 {{ report.asan_log }} 
{{ else }} Faulting call stack:
    {{ for item in report.call_stack }}
  • {{ item }}
  • {{ end }}

{{ end }} You can reproduce the issue remotely in OneFuzz by running the following command:
 {{ repro_cmd }} 
"; + // Ensure that extension data gets picked up. + private static readonly string _testString4 = "Artifacts:
    {{ for item in report.extension_data.artifacts }}
  • {{ item.name }}({{ item.desc}})
  • {{ end }}
\nInitially found in: \n"; + + private static readonly string _testString4Artifacts = """[{"desc": "Super duper sekrit artifacts","name": "Abc","url": "https://onefuzz.microsoft.com/api/download?container=abc123&filename=le_crash.zip"}]"""; + private static readonly string _jinjaIfStatement = "{% if report.asan_log %} AddressSanitizer reported the following details:
 {{ report.asan_log }} 
{% else %} Faulting call stack:
    {% endif %}"; [Fact] @@ -69,6 +74,23 @@ public void CanFormatTemplateWithForLoop() { output.Should().ContainAll(report.CallStack); } + [Fact] + public void CanFormatTemplateWithExtensionData() { + var template = Template.Parse(_testString4); + template.Should().NotBeNull(); + + var report = GetReport(); + + // Add extension data field to the report. + report.ExtensionData?.Add("artifacts", JsonSerializer.Deserialize(_testString4Artifacts)!); + + var output = template.Render(new { + Report = report + }); + + output.Should().Contain("Super duper sekrit artifacts"); + } + [Fact] public void CanFormatWithMultipleComplexObjects() { var template = Template.Parse(_testString2); diff --git a/src/agent/Cargo.lock b/src/agent/Cargo.lock index 254684be97..b74d4055a7 100644 --- a/src/agent/Cargo.lock +++ b/src/agent/Cargo.lock @@ -883,9 +883,9 @@ dependencies = [ [[package]] name = "elsa" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e0aca8dce8856e420195bd13b6a64de3334235ccc9214e824b86b12bf26283" +checksum = "714f766f3556b44e7e4776ad133fcc3445a489517c25c704ace411bb14790194" dependencies = [ "stable_deref_trait", ] @@ -3468,9 +3468,9 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.7.1" +version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc02fddf48964c42031a0b3fe0428320ecf3a73c401040fc0096f97794310651" +checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" dependencies = [ "cfg-if 1.0.0", "fastrand 2.0.0", @@ -3555,9 +3555,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.30.0" +version = "1.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3ce25f50619af8b0aec2eb23deebe84249e19e2ddd393a6e16e3300a6dadfd" +checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" dependencies = [ "backtrace", "bytes", diff --git a/src/agent/coverage/Cargo.toml b/src/agent/coverage/Cargo.toml index 29e67523d9..cca6dc2e4b 100644 --- a/src/agent/coverage/Cargo.toml +++ b/src/agent/coverage/Cargo.toml @@ -38,5 +38,5 @@ pretty_assertions = "1.4.0" insta = { version = "1.31.0", features = ["glob"] } coverage = { path = "../coverage" } cc = "1.0" -tempfile = "3.7.0" +tempfile = "3.8.0" dunce = "1.0" diff --git a/src/agent/debuggable-module/Cargo.toml b/src/agent/debuggable-module/Cargo.toml index 1cd11dfd30..ee464961f7 100644 --- a/src/agent/debuggable-module/Cargo.toml +++ b/src/agent/debuggable-module/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT" [dependencies] anyhow = "1.0" -elsa = "1.8.1" +elsa = "1.9.0" gimli = "0.27.2" goblin = "0.6" iced-x86 = "1.20" diff --git a/src/agent/onefuzz-agent/Cargo.toml b/src/agent/onefuzz-agent/Cargo.toml index 5ce8669766..90f44147c1 100644 --- a/src/agent/onefuzz-agent/Cargo.toml +++ b/src/agent/onefuzz-agent/Cargo.toml @@ -22,7 +22,7 @@ reqwest = { version = "0.11", features = [ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" storage-queue = { path = "../storage-queue" } -tokio = { version = "1.29", features = ["full"] } +tokio = { version = "1.32", features = ["full"] } url = { version = "2.4", features = ["serde"] } uuid = { version = "1.4", features = ["serde", "v4"] } clap = { version = "4", features = ["derive", "cargo"] } diff --git a/src/agent/onefuzz-task/Cargo.toml b/src/agent/onefuzz-task/Cargo.toml index 4e0bd381b0..4b7b4da730 100644 --- a/src/agent/onefuzz-task/Cargo.toml +++ b/src/agent/onefuzz-task/Cargo.toml @@ -46,9 +46,9 @@ strum = "0.25" strum_macros = "0.25" stacktrace-parser = { path = "../stacktrace-parser" } storage-queue = { path = "../storage-queue" } -tempfile = "3.7.0" +tempfile = "3.8.0" thiserror = "1.0" -tokio = { version = "1.29", features = ["full"] } +tokio = { version = "1.32", features = ["full"] } tokio-util = { version = "0.7", features = ["full"] } tokio-stream = "0.1" tui = { package = "ratatui", version = "0.22.0", default-features = false, features = [ diff --git a/src/agent/onefuzz-telemetry/Cargo.toml b/src/agent/onefuzz-telemetry/Cargo.toml index 23574a013f..8f91478b1f 100644 --- a/src/agent/onefuzz-telemetry/Cargo.toml +++ b/src/agent/onefuzz-telemetry/Cargo.toml @@ -15,5 +15,5 @@ chrono = { version = "0.4", default-features = false, features = [ lazy_static = "1.4" log = "0.4" serde = { version = "1.0", features = ["derive"] } -tokio = { version = "1.29", features = ["full"] } +tokio = { version = "1.32", features = ["full"] } uuid = { version = "1.4", features = ["serde", "v4"] } diff --git a/src/agent/onefuzz/Cargo.toml b/src/agent/onefuzz/Cargo.toml index 1f3c27985c..b5b7837d8e 100644 --- a/src/agent/onefuzz/Cargo.toml +++ b/src/agent/onefuzz/Cargo.toml @@ -31,7 +31,7 @@ serde = "1.0" serde_json = "1.0" rand = "0.8" serde_derive = "1.0" -tokio = { version = "1.29", features = ["full"] } +tokio = { version = "1.32", features = ["full"] } tokio-stream = { version = "0.1", features = ["fs", "time", "tokio-util"] } tokio-util = { version = "0.7", features = ["full"] } uuid = { version = "1.4", features = ["serde", "v4"] } @@ -40,7 +40,7 @@ url-escape = "0.1.0" storage-queue = { path = "../storage-queue" } strum = "0.25" strum_macros = "0.25" -tempfile = "3.7.0" +tempfile = "3.8.0" process_control = "4.0" reqwest-retry = { path = "../reqwest-retry" } onefuzz-telemetry = { path = "../onefuzz-telemetry" } diff --git a/src/agent/reqwest-retry/Cargo.toml b/src/agent/reqwest-retry/Cargo.toml index d7d12ff4e8..5ddfbbe419 100644 --- a/src/agent/reqwest-retry/Cargo.toml +++ b/src/agent/reqwest-retry/Cargo.toml @@ -19,5 +19,5 @@ reqwest = { version = "0.11", features = [ thiserror = "1.0" [dev-dependencies] -tokio = { version = "1.29", features = ["macros"] } +tokio = { version = "1.32", features = ["macros"] } wiremock = "0.5" diff --git a/src/agent/storage-queue/Cargo.toml b/src/agent/storage-queue/Cargo.toml index d5c1c09d08..381a761c74 100644 --- a/src/agent/storage-queue/Cargo.toml +++ b/src/agent/storage-queue/Cargo.toml @@ -26,6 +26,6 @@ serde = { version = "1.0", features = ["derive"] } serde_derive = "1.0" serde_json = "1.0" bincode = "1.3" -tokio = { version = "1.29", features = ["full"] } +tokio = { version = "1.32", features = ["full"] } queue-file = "1.4" uuid = { version = "1.4", features = ["serde", "v4"] } diff --git a/src/agent/win-util/Cargo.toml b/src/agent/win-util/Cargo.toml index 1edaa3fc58..2c4f1065bf 100644 --- a/src/agent/win-util/Cargo.toml +++ b/src/agent/win-util/Cargo.toml @@ -33,4 +33,4 @@ features = [ ] [dev-dependencies] -tempfile = "3.7.0" +tempfile = "3.8.0" diff --git a/src/proxy-manager/Cargo.lock b/src/proxy-manager/Cargo.lock index ca4813995e..4eae33643a 100644 --- a/src/proxy-manager/Cargo.lock +++ b/src/proxy-manager/Cargo.lock @@ -1474,9 +1474,9 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.7.1" +version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc02fddf48964c42031a0b3fe0428320ecf3a73c401040fc0096f97794310651" +checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" dependencies = [ "cfg-if", "fastrand", @@ -1531,9 +1531,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.30.0" +version = "1.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3ce25f50619af8b0aec2eb23deebe84249e19e2ddd393a6e16e3300a6dadfd" +checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" dependencies = [ "backtrace", "bytes", diff --git a/src/proxy-manager/Cargo.toml b/src/proxy-manager/Cargo.toml index c783e8d3aa..b2258e994b 100644 --- a/src/proxy-manager/Cargo.toml +++ b/src/proxy-manager/Cargo.toml @@ -20,7 +20,7 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" storage-queue = { path = "../agent/storage-queue" } thiserror = "1.0" -tokio = { version = "1.29", features = [ +tokio = { version = "1.32", features = [ "macros", "rt-multi-thread", "fs", @@ -31,4 +31,4 @@ reqwest-retry = { path = "../agent/reqwest-retry" } onefuzz-telemetry = { path = "../agent/onefuzz-telemetry" } uuid = { version = "1.4", features = ["serde"] } log = "0.4" -tempfile = "3.7.0" +tempfile = "3.8.0" diff --git a/src/pytypes/onefuzztypes/models.py b/src/pytypes/onefuzztypes/models.py index a5f8139e97..c888621600 100644 --- a/src/pytypes/onefuzztypes/models.py +++ b/src/pytypes/onefuzztypes/models.py @@ -273,6 +273,7 @@ class ADOTemplate(BaseModel): unique_fields: List[str] comment: Optional[str] ado_fields: Dict[str, str] + ado_duplicate_fields: Optional[Dict[str, str]] on_duplicate: ADODuplicateTemplate # validator needed to convert auth_token to SecretData