[code sync] Merge code from sonic-net/sonic-buildimage:master to master - #3071
Merged
Merged
Conversation
mssonicbld
commented
Sep 9, 2026
Collaborator
… (#29398) #### Why I did it src/dhcpmon ``` * ecebfe4 - (HEAD -> master, origin/master, origin/HEAD) [dhcpmon] Validate downstream DHCPv4 reply fan-out (Azure#107) (21 hours ago) [Xichen96] ``` #### How I did it #### How to verify it #### Description for the changelog
… automatically (#29399) #### Why I did it src/sonic-platform-common ``` * 34d7720 - (HEAD -> master, origin/master, origin/HEAD) [eeprom] Use swsscommon instead of redis-py in eeprom_tlvinfo. (Azure#748) (11 hours ago) [Jianyue Wu] ``` #### How I did it #### How to verify it #### Description for the changelog
[marvell] Formalize create_only_config_db_buffers
…est HEAD (#29213) Update the following submodules to the latest head: - aspeed/sonic-platform-modules-arista - broadcom/sonic-platform-modules-arista Signed-off-by: Justin Wong <jvwong@arista.com>
…9255) [Mellanox] Increase TC3 DWRR weight to 26 for SN6600_LD SPC6 SKUs
Add inode real time usage in monit script
Why I did it SNMP_USER values and SNMP_COMMUNITY keys were rendered directly into whitespace-delimited snmpd.conf directives. Values containing LF, CR, CRLF, spaces, tabs, vertical tabs, or form feeds could create additional directives or alter directive arguments when ConfigDB/YANG validation was bypassed through a direct Redis write. Work item tracking Microsoft ADO (number only): 39463594 How I did it Added leaf-specific YANG patterns rejecting carriage returns, line feeds, and tabs in SNMP user names, authentication passwords, encryption passwords, and community names. Kept the validation changes local to the affected leaves; no shared typedef was broadened or changed. Removed Net-SNMP whitespace separators (space, tab, vertical tab, form feed, CR, and LF) from every rendered SNMP_USER value at the snmpd.conf.j2 sink. Applied the same sink protection to community keys used by rocommunity, rocommunity6, rwcommunity, and rwcommunity6. Protected both RO and RW paths and retained valid clean rendering behavior. Added YANG negative cases for LF, CR, CRLF, and tabs in all affected free-form fields. Added real sonic-cfggen coverage for same-line argument injection and newline configuration injection.
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
Collaborator
Author
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
… MCTP (#29044) Switch-BMC images on the NVIDIA AST2700 platform need a supported path to update the BMC firmware from the running SONiC image. Operators expect to use the existing fwutil workflow (fwutil install … fw / fwutil update … fw) rather than a separate out-of-band tool. This PR adds platform integration so fwutil can drive BMC firmware updates over PLDM for Firmware Update (DSP0267) on MCTP, targeting the Aspeed IRoT link (mctpirot0). --------- Signed-off-by: Brian Carr <brcarr@nvidia.com>
What: Adds installer/efi_sbatlevel.py and updates installer/default_platform.conf to compare installed vs incoming shim SBAT levels before replacing the UEFI Secure Boot component set (shim, grub, MokManager). Why: Prevent shim SBAT downgrades; prerequisite for safe SONiC-to-SONiC downgrade on Secure Boot systems (relates to #28739). How: On install, compares SBAT timestamps; preserves the complete installed bundle on downgrade or comparison failure, and repairs an unreadable installed shim with the incoming bundle. Errors out if it can't preserve an incomplete installed set. Testing: CI green (CLEAN/MERGEABLE), APPROVED. Manual test script included in PR; additional Secure Boot test cases in progress in sonic-mgmt. Signed-off-by: Ely Barnea <elybarnea@microsoft.com>
What: Replaces the platform-specific Watchdog class in platform/aspeed/sonic-platform-modules-nokia/h6-128 with the common BMCWatchdog from sonic-platform-common; deletes the old watchdog.py and wires chassis.py to BMCWatchdog via the hw-watchdog-mgrd UPIC socket. Why: The aspeed BMC watchdog moved to a daemon (hw-watchdog-mgrd) exposing a UPIC socket, and a common BMCWatchdog class was added to avoid client-side duplication. Nokia's h6-128 was never updated and retained the original bug. How: Import BMCWatchdog and initialize it with SOCKET_PATH /run/hw-watchdog-mgrd/hw-watchdog-mgrd.sock, removing the legacy ioctl/sysfs watchdog implementation. Testing: CI green (CLEAN/MERGEABLE), APPROVED. Signed-off-by: Chandrasekaran Swaminathan <chander@nexthop.ai>
…omatically (#29414) #### Why I did it platform/alpinevs ``` * ed558c8 - (HEAD -> master, origin/master, origin/HEAD) [AVS-lite] Alpine start order and config files fixed (Azure#47) (11 hours ago) [Sree Iyer] ``` #### How I did it #### How to verify it #### Description for the changelog
…automatically (#29417) #### Why I did it src/sonic-mgmt-framework ``` * c08cc7b - (HEAD -> master, origin/master, origin/HEAD) [CLI] Require explicit CA for remote Python REST connections (Azure#166) (8 hours ago) [Ashutosh Agrawal] ``` #### How I did it #### How to verify it #### Description for the changelog
… automatically (#29418) #### Why I did it src/sonic-platform-common ``` * 7ff32c1 - (HEAD -> master, origin/master, origin/HEAD) Add SFF-8024 Rev 4.14 LRO (RTLR) AppSel host electrical interface codes (Azure#749) (5 hours ago) [Bobby McGonigle] ``` #### How I did it #### How to verify it #### Description for the changelog
…omatically (#29421) #### Why I did it src/sonic-swss-common ``` * 42f5152 - (HEAD -> master, origin/master, origin/HEAD) [common]: Add shared VRF name validation (Azure#1242) (8 hours ago) [Ashutosh Agrawal] ``` #### How I did it #### How to verify it #### Description for the changelog
- Why I did it
Support CLI command: 'show interfaces label-port status' for sn6810_ld
For all supported platforms, platform.json should be extended with:
label_port_lanes_mapping (object):
a. Key: Label-port identifiers (strings, e.g., "1", "2").
b. Values: list of lane numbers (strings, e.g., ["1", "2", "3", "4"] ).
For multi-ASIC platforms only - number_of_lanes_per_asic (stringified integer) - Used to compute global lane offsets on multi-ASIC systems: global_lane = local_lane + (asic_index × number_of_lanes_per_asic).
Example:
platform.json
// Single-ASIC
"label_port_lanes_mapping": {
"1": ["0", "1", "2", "3"],
"2": ["4", "5", "6", "7"],
...
"127": ["504", "505", "506", "507"],
"128": ["508", "509", "510", "511"]
}
// Multi-ASIC
"number_of_lanes_per_asic": "512",
"label_port_lanes_mapping": {
"1": ["0", "512", "1024", "1536"],
"2": ["1", "513", "1025", "1537"],
...
"511": ["510", "1022", "1534", "2046"],
"512": ["511", "1023", "1535", "2047"]
}
- How I did it
Validate it on a simulation
- How to verify it
Run the following command: 'show interfaces label-port status'
Example output:
Single-ASIC ( 2 x 4x)
>> show interfaces label-port status
Label-port | Lane 1 | Lane 2 | Lane 3 | Lane 4
-----------|---------------|---------------|---------------|---------------
1 | Ethernet0(UP) | Ethernet0(UP) | Ethernet0(UP) | Ethernet0(UP)
2 | Ethernet4(UP) | Ethernet4(UP) | Ethernet4(UP) | Ethernet4(UP)
3 | Ethernet8(UP) | Ethernet8(UP) | Ethernet8(UP) | Ethernet8(UP)
...
128 | Ethernet508(UP) | Ethernet508(UP) | Ethernet508(DN) | Ethernet508(UP)
Single-ASIC ( 4 x 2x)
>> show interfaces label-port status
Label-port | Lane 1 | Lane 2 | Lane 3 | Lane 4
-----------|---------------|---------------|---------------|---------------
1 | Ethernet0(UP) | Ethernet0(UP) | Ethernet2(UP) | Ethernet2(UP)
2 | Ethernet4(UP) | Ethernet4(UP) | Ethernet6(UP) | Ethernet6(UP)
3 | Ethernet8(UP) | Ethernet8(UP) | Ethernet10(UP) | Ethernet10(UP)
...
128 | Ethernet508(UP) | Ethernet508(UP) | Ethernet510(DN) | Ethernet510(UP)
Multi-ASIC
>> show interfaces label-port status
Label-port | Lane 1 | Lane 2 | Lane 3 | Lane 4
-----------|---------------------|---------------------|---------------------|---------------------
1 | Ethernet0/asic0(UP) | Ethernet512/asic1(UP) | Ethernet1024/asic2(UP) | Ethernet1536/asic3(UP)
2 | Ethernet1/asic0(UP) | Ethernet513/asic1(UP) | Ethernet1025/asic2(UP) | Ethernet1537/asic3(UP)
3 | Ethernet2/asic0(UP) | Ethernet514/asic1(UP) | Ethernet1026/asic2(UP) | Ethernet1538/asic3(UP)
...
512 | Ethernet511/asic0(UP) | Ethernet1023/asic1(UP) | Ethernet1535/asic2(DN) | Ethernet2047/asic3(UP)
Signed-off-by: Zili Bombach <zbombach@nvidia.com>
- Why I did it To add fast-reboot support for multi-asic devices, according to this HLD - sonic-net/SONiC#2306 - How I did it Enhanced services startup scripts to support fast reboot on multiple ASICs - How to verify it by running fast-reboot on a multi-asic device and verifying that all services start with the fast-reboot path. Signed-off-by: Yair Raviv <yraviv@nvidia.com>
… what patches fix (#29237) #### Why I did it Eight things the SBOM and its vulnerability report got wrong, all in the `ENABLE_SBOM=y` path. | Problem | Consequence | |---|---| | A patch that fixes a CVE doesn't record which one | SONiC patches rather than rebasing, so the SBOM honestly reports the older upstream version — a scanner then reports issues we already fixed, with no way to tell which | | VEX-suppressed findings are dropped from the report entirely | Package, version and history unchanged, finding just gone — indistinguishable from a scan that failed | | An SBOM carries no identifier of its own | The vulnerability report can only reference it by filename, which breaks as soon as either file is copied | | syft catalogues every file on the image | **57,332 of 65,870 components, 24.8 MB of 54 MB.** No purl, version or CPE, so no feed can match one; the CycloneDX encoder drops syft's file-ownership links, so nothing says which package owns a file; and they aren't attested — the SLSA provenance names one subject, the `.bin` | | The dependency graph has no root | Nothing descends from the image, all 37 containers appear in no edge, **7,569 of 8,538 packages have no edge at all**. So the SBOM can say a package is vulnerable but not which container ships it — the first question anyone triaging asks. `README.sbom.md` already claimed this nesting existed | | One package is described as two components | **156 packages of 7,689**, each listed twice under a different package URL namespace — `pkg:deb/sonic/openssl` beside `pkg:deb/debian/openssl`, `pkg:deb/sonic/bash` beside `pkg:deb/bash`. Every finding against them is counted twice, and a consumer asking what is affected gets two answers for one thing | | A dependency read from a lockfile is not attributed to anything | A Go module is compiled into a program, and the program is what its `go.sum` sits beside. Of **952 such dependencies, 900 appear in no edge at all** and 16 hang off the image, which says the image depends on a Go module. So the SBOM can say a module is vulnerable but not which of our programs it was built into | | Code compiled into a program is attributed to the filesystem it sits in | syft records which executable a Go module was linked into and nothing reversed that, so `stdlib` was a direct child of the host filesystem when what it actually is is the runtime inside `/usr/bin/containerd` | ##### Work item tracking - Microsoft ADO **(number only)**: N/A #### How I did it | Change | How | |---|---| | Patches record what they fix | A CVE in a patch's filename, `Fixes:` or `Subject:` header goes into `pedigree.patches[].resolves[]`. Only those — a CVE mentioned in passing isn't a claim to fix it. Parsing moves from `sbom_extract_vex_from_patches.py` into a shared `scripts/sbom_cve_refs.py`, so the SBOM and the VEX statements can't disagree | | Suppressed findings stay in the report | Each carries an `analysis` block saying what the VEX statement claimed; "already fixed" is reported as fixed, not "does not apply". `--fail-on` still ignores them, so nothing newly fails | | Each SBOM gets a serial number | Derived from its own contents, not random — `README.sbom.md` promises identical builds produce identical SBOMs. The vulnerability report records it, so the two match by identity | | `affects[].ref` points at a component reference | It was a package URL. In our own SBOMs those are the same text, which is why it went unnoticed | | Files are no longer catalogued | syft runs with `file.metadata.selection=none` — stopped at the source, which also skips digesting every file. Output is filtered for `type: file` regardless, since trivy has its own defaults. The scanner cache is versioned: the input didn't change, only our reading of it | | One package is one component | `merge_components` already keyed on `(name, version)` so the three producers collapse into one record. The key also carried architecture, and only recipe-emit and observation fragments set the `sonic:arch` property it read — so all 5,826 syft components compared as architecture `""` and never matched the recipe fragment describing the same `.deb`. Architecture leaves the key: the recipe takes it from the `.deb` filename, which says `amd64` for a `symcrypt-openssl` whose control file says `all`; the observation stamps `CONFIGURED_ARCH` on everything, which says `amd64` for `Architecture: all` packages like `ifupdown2`; only syft reads dpkg. One document describes one image built for one architecture, and dpkg will not install one name at one version twice within it | | The winner keeps what only the filesystem knew | Merging costs the loser's record, and the loser is the only one that read a real filesystem. For 65 packages it held the only note of which Debian release they were installed on — syft's `distro=` qualifier, which grype uses to select an OS advisory feed. For 535 it held `upstream=`, the Debian **source** package a binary package was built from: libssl3 from openssl, apt-utils from apt. Debian publishes advisories against the source package, so a binary package without it cannot be matched to the advisory that covers it. Both move to the winner, the same reasoning that already moves the CPE. Named as a list of what only a real filesystem can know, rather than as a rule about `distro` that happens to be applied once — the first version of this promotion carried `distro` alone, and a full rebuild showed it had silently cost all 535 packages their source package | | A lockfile dependency says which program it was built into | Two causes, both fixed at the source. `scope_from_tarball_path` returned the tarball path when it could not derive a scope, so every tarball under `target/versions/build/log-*/` — which every build produces, and which `parse_lockfiles` collects because it walks all of `versions/` — gave its components a scope of `target/versions/build/log-.../lockfiles.tar.gz`. Nothing treats that as a scope, so 900 were placed nowhere; it now yields nothing, which is true rather than merely useless. And a lockfile's scope says which filesystem it was harvested from, not that the image depends on what it lists, so those no longer attach to the image. What was needed to do better is now kept: the parser records each lockfile's own path instead of discarding it, recipes record the source tree they were built from, and a dependency whose lockfile sits under a recipe's source tree is attached to what that recipe built — longest path first, so a vendored tree wins over the tree above it. Where the two do not line up nothing is emitted and the dependency stays unrooted, which is the rule the containment pass already holds to | | Package URLs are escaped once, in one place | Both producers built the string by interpolation, so one version reached the document as `3.5.6-1~deb13u2+fips` from the recipe and `3.5.6-1~deb13u2%2Bfips` from syft — one package, two spellings, because `+` is reserved and only one of them escaped it. A new `scripts/sbom_purl.py` assembles and escapes for both, so the two cannot disagree again | | The dependency graph is rooted | `run_scanner` stamps `sonic:scope` (`host-image` / `dockers/<name>`) on what it returns, after the cache so a cached archive stays reusable. `merge_components` carries scopes across the dedupe — the recipe-emit winner outranks the observation, but only the observation knows where it ended up. `sonic:scope` becomes multi-valued, since a shared library is in twenty containers. `build_dependency_graph` gains a containment class: image → the host filesystem and the containers it installs, and each of those → the packages it holds. The host filesystem gets a component of its own (`sonic:host-image`, type `operating-system`) so packages installed outside a container hang off a place rather than off the image | | Code compiled into a program hangs off the program | The same defect as the lockfile row above, arriving by the other route: that one comes from a lockfile in a source tree we built, this one from scanning a filesystem we assembled, and nothing was reversing the second attribution. Scanning names the program but emits no component for it, so one `type: application` component is synthesized per program per scope and the modules hang off it: `host-image -> /usr/bin/containerd -> stdlib`. The pairing is made at scan time rather than after `merge_components`, because syft emits one record per (module, program) and they all share a package URL — the dedupe unions every record's scope but keeps only one record's location, so pairing afterwards hands that one path every scope the merge unioned in. A location under `/var/lib/docker/overlay2/` is a container's own file reached through the host filesystem; the per-container scan sees it at its real path, so no program is named after the overlay directory (whose name changes every build) and the module is not attached to the host filesystem either | Two notes: - **Nothing new is collected.** syft already ran once per container and once over the host rootfs, so it always knew which filesystem each result described — that knowledge just stops being discarded. A component that still can't be placed is left unrooted rather than attached to the image on the assumption it must be somewhere. - **Dropping the file components removed two faults that only ever affected them:** the host and per-container scans shared one flat path namespace, so 10,921 paths were listed twice and 322 resolved to two different digests; and seven files were emitted with no digest at all, silently, because the scanner couldn't read them (`/etc/sudoers`, `/etc/pam_radius_auth.conf`, `chrony.keys`). #### How to verify it Run against a real build tree and a real 18 MB image SBOM — dropping the file inventory is what shrank it. **Files dropped, packages untouched** — one container, syft 1.44.0: | | default | `selection=none` | |---|---:|---:| | `type: file` components | 6,804 | **0** | | package components | 220 | **220** (identical bom-refs) | | dependency edges | 173 | **173** | | output size | 2,485,196 B | **606,726 B** | **Graph rooted** — builder run over a real broadcom SBOM's components. These are the graph builder's own before/after over the pre-branch document, so the totals are that document's, not the count a build at this branch's head produces: | | before | after | |---|---:|---:| | `dependencies[]` entries | 176 | **194** | | edges | 1,235 | **7,818** | | components reachable through `dependencies[]` | 969 of 8,538 (11%) | **7,420 of 8,539 (87%)** | | containers under the image root | 0 of 37 | **37 of 37** | | image component present in the graph | no | **yes** | | components left deliberately unplaced | 7,569 | **1,119** | The after column includes the `sonic:host-image` node: one extra `dependencies[]` entry, one extra edge from the image, and one extra component in the document — which is why the reachable denominator moves by one too. The image's direct children are the containers it installs plus the host filesystem; the host packages that used to hang off the image directly now hang off that. **Compiled-in code hangs off the program** — the builder run twice over one build tree, identical inputs, only the attribution code differing: | | before | after | |---|---:|---:| | program components | 17 | **21** | | ...named after a `/var/lib/docker/overlay2/` path | 9 | **0** | | `dependencies[]` entries | 179 | **183** | | components reachable from the image root | 6,782 | **6,800** | | host filesystem's direct children | 5,346 | **5,346** | | Go modules hanging off the host filesystem | 0 | **0** | | dangling references | 0 | **0** | | non-program components added or removed | — | **0 / 0** | The nine overlay2-named programs are the reason the pairing moved to scan time. A module seen through the directory docker unpacked a container into would otherwise name a program after a directory whose name changes every build, and the same collapse put `/usr/bin/containerd`, `/usr/bin/dockerd` and `/usr/bin/runc` inside `docker-sonic-otel`, which ships none of them, while nine of `docker-sonic-gnmi`'s own programs went unrecorded and `/usr/sbin/rest_server` was credited with 1 of its 40 modules. The host filesystem's direct children are unchanged because a module only ever seen inside a container layer is left to the per-container scan rather than attached to the filesystem that layer sits in. **One package, one component** — `merge_components` replayed over a real 8,374-component image SBOM's own components, fed back in the priority order `main()` uses. Again a replay over the pre-branch document: `7,680` is what that input merges to, not the component count of a document built at this branch's head. | | before | after | |---|---:|---:| | deb packages carrying more than one namespace | 156 | **0** | | merged components | 8,374 | **7,680** | | recipe-emit winners inheriting a `distro=` qualifier | 0 | **65** | | components carrying a `distro=` qualifier | 587 | **587** | | components carrying an `upstream=` qualifier | 535 | **535** | | components carrying a `publisher` | 587 | **587** | | packages whose stated version is not the one installed | 9 | **0** | | lockfile dependencies attributed to what was built beside them | 0 | **60** | | a crate and the .deb built from it merged into one component | 2 | **0** | | components asserted to be in the image that are the build toolchain | 658 | **0** | | vulnerabilities reported against that toolchain | 216 | **0** | | `cyclonedx validate --input-version v1_6` | **rejected** | **valid** | Re-running the *old* merge over that input returns it unchanged (8,374 → 8,374), which is the check that the harness reproduces the real merge: the input is that merge's own output. **The build environment is described in `formulation`, not in `components`.** A lockfile harvested from `versions/build/log-*/lockfiles.tar.gz` comes from the container that *compiles* SONiC, and it holds two unrelated things: paths under `sonic/` are our own source trees, whose dependencies really are linked into the binaries we ship, and everything else is the toolchain. `usr/share/go-1.19/src/go.sum` is the Go compiler's own source tree, and a real broadcom image ships no golang package at all — no shipped scope's harvest contains a single `usr/` path. Left in `components` they are asserted to be image contents, because CycloneDX reads a component with no `scope` as `required`; that is 658 components and 216 vulnerabilities reported against a compiler nobody runs, conspicuous because nothing pulls them in. `scope: "excluded"` does not fix that, and this was measured rather than assumed: against **grype 0.112.0 and 0.118.0**, one component reports the same 20 matches whether it is marked `excluded`, `optional`, `required`, or nothing at all. In `formulation` — the section CycloneDX 1.5 added for how an artifact was built — grype reports **0**. Nothing is discarded, so a build-chain compromise (xz-utils was introduced through a build system, not through source) stays answerable from the same document. **The build now checks its own document, and `SBOM_STRICT=1` makes a failure fatal.** That is the actual fix; the one below is the bug it would have caught. It runs at both write sites using the cyclonedx-cli already provisioned for the SPDX export, and it passes `--fail-on-errors` — without that flag cyclonedx-cli prints "BOM is not valid." and **exits 0**, so the obvious spelling of the check passes on a document the same command has just rejected. **The document validates now, and did not before.** `cyclonedx validate --input-version v1_6` rejected every SBOM this produced: `pedigree.patches[].diff` carries `url` and `text` and nothing else, and this emitted a `hashes` array beside them — 530 components carry one, so a single unschema'd field invalidated the whole file. Nothing in the build runs the validator, so the failure was silent and the tools we happened to use were lenient enough not to care. The digest moves to a `sonic:patch_sha256` property, which keeps *which* patch was applied, and the change-detection signature reads it from there — still reading the old spelling too, so a comparison against an older document does not read as every patch having changed. Those last four came out of a self-review done before rebuilding, by replaying the merge over the previous document — the previous merge's own output, so a real 8,374-component input — and comparing every field, property and qualifier either side of it. Three of the four were introduced by the dedupe in this branch, and the fourth was inert rather than wrong: attributing a lockfile dependency to what was built beside it matched 0 of 952, because harvested paths are rooted at the source tree and the source trees recipes record are repository-relative. Nothing reported it, because "nothing matched" and "nothing to match" produce the same empty result. The replay is the check worth keeping: a merge that drops a field states nothing about having dropped it, and every one of these was found by counting a property either side rather than by reading the diff. The merged count above was later confirmed by a full rebuild, which produced 7,680 components and no duplicate package URLs. That rebuild also caught the `upstream=` loss: it is the qualifier count in the table that made a regression visible which nothing else would have reported, since a package quietly losing its source package still scans, still resolves and still looks right. Of the 694 records absorbed, 686 are a syft observation of a package a recipe fragment or a post-versions observation already described, and every one carries the same name and version as the record it merged into. Ten do not, and all ten are the epoch drift `_normalize_version` was written for — `openssh-server 1:10.0p1-7+fips` into `openssh-server 10.0p1-7`, `fancontrol 1:3.6.0-7.1` into `3.6.0-7.1`. Two Rust crates absorb the `.deb` built from them (`syslog-counter`, `sonic-supervisord-utilities-rs`); eleven SONiC submodule packages absorb the `.deb` built from them, which is `build_purl` choosing the `pkg:github` identity as primary and is the intended behaviour. No two different upstream versions merge, and every `bom-ref` in the result is still unique. **A dependency knows which program it is in** — the graph builder over the same 8,374-component image: | | before | after | |---|---:|---:| | lockfile dependencies in no edge at all | 900 of 952 | **0 once the producer records the lockfile** | | lockfile dependencies hanging off the image | 16 | **0** | | edges over an *existing* document, lockfile attribution only | 25,128 | **25,128** (none added, none removed) | The last row is about the lockfile attribution specifically: it rests on facts the producer did not record before, so for that class an already-built SBOM is byte-identical and the improvement arrives with the next build. Hanging compiled-in code off the program is the deliberate exception — it reads `syft:package:foundBy` and `syft:location:0:path`, which syft has always emitted, so re-running the builder over an already-built document does move it. The scope derivation is checked against the real strings — `target/versions/build/log-20260830011338/lockfiles.tar.gz` now yields no scope, while `versions/dockers/docker-fpm-frr/post-versions/` and `versions/host-image/post-versions/` still yield theirs. Attribution is exercised directly: a module beside `sonic-gnmi`'s `go.sum` attaches to sonic-gnmi, a vendored tree inside it wins over the tree above and does not also attach to the outer one, a lockfile under nothing we built stays unrooted, and a `host-image` lockfile is not attached to the image. The lockfile path shape is taken from a real harvest: `collect_version_files` harvests from `/sonic`, which `Makefile.work` mounts as `$(PWD)`, so a harvested path is `sonic/<repo-relative path>` and the `sonic/` prefix the matcher strips is not a guess. The failure mode if a given build disagrees is that the dependency stays unrooted — the same place it is today, and never a wrong edge. No regression, same input: with no `root_ref` the builder reproduces the previous graph exactly (all 1,235 edges); with one, every one of those edges survives; no self-edges; every `dependsOn` target resolves to a component in the document or the root. Scanning one archive twice under two scopes returns 220 components each time carrying the scope asked for, while the cached entry stays unscoped and reusable. The 1,119 still unplaced are 932 lockfile-derived transitive deps (scope is the lockfile, not a filesystem) and 187 recipe-emit fragments the scanner didn't also see. Placing them needs build-side data not captured today. Other checks: - **VEX output unchanged** by the shared patch reader — `sbom_extract_vex_from_patches.py` before and after over the same `src/`: 17 statements, identical content and logs (0 of 17 differ, ignoring the generation timestamp). - **Patches resolve correctly.** `src/thrift_0_14_1/thrift.patch` has five patches, one CVE-named — only `0002-cve-2017-1000487.patch` gets a `resolves[]` entry, lower-case identifier normalised. - **Suppressed findings carry their reason** — `state: not_affected`, `justification: code_not_present`, statement namespace and reason in `detail`. - **`affects[].ref`** resolves to the component reference against an SBOM where it deliberately differs from the package URL. **Covered by a full build:** broadcom, broadcom-dnx and broadcom-legacy-th were built with `ENABLE_SBOM=y` at this branch's head, each producing a document that passes `cyclonedx validate --input-version v1_6 --fail-on-errors`, carries a deterministic serial number, has no `type: file` component and no duplicate package URL, and whose dependency graph the checker reports no problems on. **Not covered:** the non-broadcom platform legs. Builds without `ENABLE_SBOM` are unaffected — the path is skipped at the make level. #### Which release branch to backport (provide reason below if selected) - [ ] 202305 - [ ] 202311 - [ ] 202405 - [ ] 202411 - [ ] 202505 - [ ] 202511 - [ ] 202512 - [x] 202605 - [ ] 202608 Only 202605, and only the `sbom: emit a document that validates` change. That branch carries `scripts/sbom_fragment.py` with a `hashes` array inside `pedigree.patches[].diff`, which CycloneDX's schema does not allow, so every SBOM it produces is rejected by `cyclonedx validate --input-version v1_6`. That is a defect in a shipped release rather than an improvement. 202305 through 202512 do not carry the commit and need nothing. The rest of this PR improves an opt-in feature and should not be backported. Tracking issue/work item for backport/cherry-pick request (GitHub issue or Microsoft ADO): N/A Failure type: N/A #### Tested branch - [x] master - [ ] N/A #### Test result master: verified against a locally built `sonic-broadcom.bin.cdx.json` (18 MB) and the `src/` tree it was built from, as described above. #### Description for the changelog sbom: record in the SBOM which vulnerabilities a carried patch fixes, keep VEX-suppressed findings in the vulnerability report, give each SBOM a serial number, stop cataloguing individual files, root the dependency graph so the image, the host filesystem, the containers it installs and their packages form one tree, stop describing one package as two components under two package URL namespaces, attribute a dependency read from a lockfile to the program it was built into, hang code compiled into a program off that program rather than off the filesystem it sits in, move the build toolchain out of the image's component list into `formulation` so the document stops asserting the image contains its own compiler, and move each patch's digest from an unschema'd `hashes` array into a `sonic:patch_sha256` property so the document validates as CycloneDX 1.6 #### Link to config_db schema for YANG module changes N/A — no YANG changes.
Retain the upstream image names expected by Kubernetes after pulling images through the configured default registry. Signed-off-by: losha228 <46000205+losha228@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* consolidate hwsku-level pmon_daemon_control.json for SN5640,SN5610N,SN4280,SN5600,SN4700 Signed-off-by: Matt Hoffman <matthoffman@microsoft.com>
mssonicbld
force-pushed
the
sonicbld/master-merge
branch
from
September 10, 2026 03:05
cc8cde5 to
a96ade1
Compare
Collaborator
Author
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
…28990) Support for this feature was recently added to sonic-linux-kernel. For more details, see sonic-net/sonic-linux-kernel#589 Signed-off-by: Yury Murashka <yurypm@arista.com>
…omatically (#29450) #### Why I did it platform/alpinevs ``` * 7a620dc - (HEAD -> master, origin/master, origin/HEAD) [AVS-lite] Moved config_db as a config option (Azure#48) (12 hours ago) [Sree Iyer] ``` #### How I did it #### How to verify it #### Description for the changelog
…lly (#29741) #### Why I did it src/sonic-swss ``` * 6580479f - (HEAD -> master, origin/master, origin/HEAD) [sflow] Add Dropped Packet Notification (MOD) support. (#3970) (10 hours ago) [yehjunying] * b231e7d5 - [p4orch]: Initialize nexthop SAI OIDs so VerifyState is stable in profiling builds (#4890) (10 hours ago) [Nazarii Hnydyn] ``` #### How I did it #### How to verify it #### Description for the changelog
* Update tuning data. * update tuning data.
…tically (#29622) #### Why I did it src/sonic-sairedis ``` * 84f69782 - (HEAD -> master, origin/master, origin/HEAD) [syncd]: Drop host_tx_ready ntf when port RID is not mapped yet (Azure#2068) (2 days ago) [Nazarii Hnydyn] * 9b1fb2c5 - [micas] Add a new virtual switch type (Azure#1930) (6 days ago) [Griffin-micas] * fdcd3317 - vpp: fix CRM accounting for FDB entries (Azure#2081) (7 days ago) [yue-fred-gao] ``` #### How I did it #### How to verify it #### Description for the changelog
Signed-off-by: Mahdi Ramezani <mramezani@microsoft.com>
…9729) What: Advanced the aspeed/sonic-platform-modules-arista and broadcom/sonic-platform-modules-arista submodules to their latest HEAD. Why: The latest Arista driver changes are needed for the latest platform support and for addressing driver issues. How: Bumped the two arista platform-module submodule pointers. Testing: All Azure CI checks pass; Tested for 202605 branch. Signed-off-by: Justin Oliver <justinoliver@arista.com>
Some Eoptolink EO138HG cables, including the CSL1 Y-cables, report the
vendor name "EOPTERA" instead of "EOPTOLINK". xcvrd builds the media
settings lookup key as "<vendor name>-<part number>", so these modules
never matched the EOPTOLINK-EO138HGPCT\d{2}SL1 and
EOPTOLINK-EO138HGPCT\d{2}CSL1 keys on ports 45-52 and 77-84, and fell
back to the generic OPTICAL100 settings.
Accept either vendor name in both keys. The settings values are
unchanged.
Signed-off-by: dygodwin <179140848+dgodwin-nokia@users.noreply.github.com>
Co-authored-by: dygodwin <179140848+dgodwin-nokia@users.noreply.github.com>
Validated submodule pipeline runs for buildimage commit `595b3dbb382502bc69ad197cf98016c2181c1725` on master `5317ad2f`: ``` buildimage_vs=595b3dbb382502bc69ad197cf98016c2181c1725 common_libs=595b3dbb382502bc69ad197cf98016c2181c1725 src/sonic-dash-api=2ce7ce648ee77a76fcf567191eb4b9ed6cfeed38 platform/vpp=2b71bbd7c7197212e34d754df564e6cb11ea9d93 src/sonic-dbsyncd=d030540bca61cb32eda24699f6f83ece867860f8 src/sonic-host-services=a29f43cb154288eff0776230a53ad222aca63890 src/sonic-mgmt-common=13514bbb32d0e9cd4e1917d26da4cc4e99908f13 src/sonic-mgmt-framework=29b5acc965c7d761a82bd083c5f1f27117966b0e src/sonic-platform-common=c0af37dace2b73416bfb7970cee6c15f64da96cd src/sonic-platform-daemons=2c1a994b6a95b572b95d878fd06eb27400e57cd4 src/sonic-snmpagent=e09fd3805de3bd67f39a3797a5a1a79f8323dbb3 src/sonic-swss-common=10d14ae58ae73899a52a2447d1e791a2b7bd1a34 src/dhcpmon=ecebfe4c88e3c68dd5bbd78fa46c2a6b9ad47f87 src/dhcprelay=633c8e1736854fca52553255a9abb9d0f704ce0e src/linkmgrd=eb7fd014d3ed799e44f1976099c90b57ed6424e0 src/sonic-bmp=12e8c3958f6dfb6482509adee2718db8ea40ace6 src/sonic-dash-ha=5a2508a404569298d8958937dd4de772ba67b129 src/sonic-gnmi=d7837b7162e76f3b74e33116b9962774e7fb915e src/sonic-sairedis=be4e39da64bd4eff3e6e585c773b0489600d643d src/sonic-stp=b803a4ce45113c96a7626563df0b235a81e74729 src/sonic-utilities=2fe754a5df70cd43db66854c23b04e059a9132a5 src/wpasupplicant/sonic-wpa-supplicant=6ca19c73b9c868782b59a0d7adc6ff34de5bbdba src/sonic-swss=35fb54fdadbcd0c402f6bb070659920e83196926 docker_slave_bookworm=595b3dbb382502bc69ad197cf98016c2181c1725 docker_slave_trixie=595b3dbb382502bc69ad197cf98016c2181c1725 sonic_buildimage_ubuntu22_04=595b3dbb382502bc69ad197cf98016c2181c1725 ```
Why I did it The isolate and unisolate templates expect DEVICE_METADATA|localhost bgp_asn to be numeric, but currently render its value directly into their generated routing command streams. Strictly validate the value during template rendering so malformed input stops rendering instead of being coerced into a different BGP instance. Work item tracking Microsoft ADO (number only): N/A How I did it Add a reusable strict ASN filter to sonic-cfggen. Apply the filter in isolate.j2 and unisolate.j2. Preserve valid decimal ASN values unchanged. Render explicit successful no-op helpers when BGP is legitimately unconfigured (missing ASN, JSON null, or the existing case-insensitive none/null sentinels). Verify configured and non-BGP rendering while malformed, coercible, out-of-range, Unicode, oversized, and sentinel-lookalike values fail rendering for both templates.
Why I did it Ensure BGP table keys, ASN attributes, and peer-group references are validated consistently before entering frrcfgd command processing, queues, or caches. Work item tracking Microsoft ADO (number only): N/A How I did it Validate VRF names using the shared swsscommon validator. Parse and normalize IP neighbor addresses. Validate interface neighbors using the shared interface-name check. Validate complete composite key shapes and allow only supported AFI/SAFI values. Require local, remote, and confederation ASN values and lists to be within the modeled 32-bit range. Validate peer-group references with the same command-safe identifier rule used for key components. Reject control characters in neighbor and peer-group command fields while preserving printable free text and the structured command transport's literal-quote behavior. Route runtime updates and unified startup replay through one validation boundary, then revalidate every queued entry before cache or FRR mutation so dependent-table reapply cannot bypass the checks. Validate startup-loaded state and runtime DEVICE_METADATA updates while preserving the last known-good value. Add coverage for accepted boundaries, normalized keys, rejected live updates, unsafe peer-group references, and rejected replay entries. Update sonic-swss-common to include [common]: Add shared VRF name validation sonic-swss-common#1242.
Why I did it BGPAllowListMgr currently accepts partially matched keys and loosely parsed prefix rules. Trailing key data can be incorporated into generated FRR identifiers, while malformed prefixes can raise an exception during conversion. Work item tracking Microsoft ADO (number only): N/A How I did it Validate complete documented allow-list key layouts. Restrict neighbor and community fields to safe identifier characters. Bound deployment IDs to the unsigned 32-bit range. Parse IPv4 and IPv6 networks with ipaddress. Accept only complete optional le or ge modifiers whose lengths are valid for the prefix. Add regression tests for malformed keys, prefixes, masks, modifiers, and trailing data.
mssonicbld
force-pushed
the
sonicbld/master-merge
branch
from
September 25, 2026 03:04
f626a0f to
8f5c074
Compare
Collaborator
Author
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
…utomatically (#29758) #### Why I did it src/sonic-host-services ``` * 268ca64 - (HEAD -> master, origin/master, origin/HEAD) hostcfgd: Validate RADIUS server fields before creating PAM files (Azure#430) (3 hours ago) [Ashutosh Agrawal] ``` #### How I did it #### How to verify it #### Description for the changelog
…omatically (#29759) #### Why I did it src/sonic-mgmt-common ``` * ecec7f9 - (HEAD -> master, origin/master, origin/HEAD) Port System EEPROM handling from pfm_app.go to xfmr_platform.go (Azure#236) (10 hours ago) [bibhuprasad-hcl] ``` #### How I did it #### How to verify it #### Description for the changelog
…tomatically (#29739) #### Why I did it src/sonic-linux-kernel ``` * 537a9bb - (HEAD -> master, origin/master, origin/HEAD) Merge pull request Azure#631 from oleksandrivantsiv/hwmgmt-7.0070.1021-master (26 hours ago) [judyjoseph] |\ | CODE_OF_CONDUCT.md LICENSE README.md SECURITY.md SUPPORT.md azure-pipelines failure_prs.log scripts skip_prs.log 1139e05 - [Mellanox] Integrate HW-MGMT Version 7.0070.1021 (31 hours ago) [Oleksandr Ivantsiv] * 425edad - Name the patches that fix a CVE for the CVE they fix (Azure#629) (30 hours ago) [Brad House - Nexthop] ``` #### How I did it #### How to verify it #### Description for the changelog
Migrate enable_per_port_counter_discovery to runtime_vars.json
Description Adds a default value to the user_auth leaf in the GNMI YANG model. Motivation and Context The user_auth field had no schema-level default. This adds default "cert" so CVL populates a safe value when the field is omitted from CONFIG_DB, complementing the fail-closed default already applied at the docker startup script layer in #29500. How Has This Been Tested? Manual review of the YANG syntax (brace balance, single leaf addition). Note: pyang/yanglint were not available in this environment to run a full schema compile; existing yang_model_tests fixtures do not currently exercise a missing-user_auth case. Additional Information Related to #29500.
mssonicbld
force-pushed
the
sonicbld/master-merge
branch
from
September 26, 2026 03:05
8f5c074 to
1287183
Compare
Collaborator
Author
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
…lly (#29777) #### Why I did it src/sonic-swss ``` * 94a5ef8e - (HEAD -> master, origin/master, origin/HEAD) [pfcwd] Don't abort orchagent when the egress ACL table create fails (#4743) (7 hours ago) [Rajath] * aa8298e8 - orchagent: validate split horizon keys (#4928) (8 hours ago) [Ashutosh Agrawal] * 98909ba3 - Fix flakey dvs test test_multi_nexthop_all_standby_then_delete_route (#4923) (8 hours ago) [rajkumar1-arista] * 8550f409 - stpmgrd: reject malformed numeric configuration (#4927) (9 hours ago) [Ashutosh Agrawal] ``` #### How I did it #### How to verify it #### Description for the changelog
…lly (#29737) #### Why I did it src/sonic-gnmi ``` * 94ba8ae - (HEAD -> master, origin/master, origin/HEAD) Component test for Components Model - Eeprom (Azure#751) (8 hours ago) [bibhuprasad-hcl] * 1fe8e62 - Component test for front panel interface (Azure#716) (2 days ago) [niranjanivivek] ``` #### How I did it #### How to verify it #### Description for the changelog
…D automatically (#29776) #### Why I did it src/sonic-platform-daemons ``` * d6cd96c - (HEAD -> master, origin/master, origin/HEAD) populating chassis_serial_number to state_db DEVICE_METADATA Table (Azure#855) (4 hours ago) [Gaurav Nagesh] ``` #### How I did it #### How to verify it #### Description for the changelog
mssonicbld
force-pushed
the
sonicbld/master-merge
branch
from
September 27, 2026 03:05
1287183 to
4022c15
Compare
Collaborator
Author
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
yijingyan2
approved these changes
Sep 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.