Skip to content

Ship synced custom SAI headers in libsaivs-dev#1984

Open
brcarr-nv wants to merge 1 commit into
sonic-net:masterfrom
brcarr-nv:mlnx-custom-headers-libsaivs-dev
Open

Ship synced custom SAI headers in libsaivs-dev#1984
brcarr-nv wants to merge 1 commit into
sonic-net:masterfrom
brcarr-nv:mlnx-custom-headers-libsaivs-dev

Conversation

@brcarr-nv

@brcarr-nv brcarr-nv commented Jul 10, 2026

Copy link
Copy Markdown

When vendor custom SAI headers are present in SAI/custom/, parse.pl emits "#include <saicustom.h>" into the generated saimetadata.h. Install those custom headers into libsaivs-dev so the include resolves in downstream builds (e.g. sonic-swss). libsaivs-dev conflicts with mlnx-sai, so there is no /usr/include/sai/saicustom.h overwrite clash. Guarded on header existence, so it is a no-op for builds without synced custom headers.

Description of PR

Type of change

  • Bug fix
  • New feature
  • Refactor / cleanup
  • Documentation update
  • Test improvement

Approach

What is the motivation for this PR?

ASAN-enabled syncd aborts with a heap-buffer-overflow when creating an ACL table on Mellanox:

AddressSanitizer: heap-buffer-overflow ... READ of size 24 in memcpy
  check_attribs_metadata / check_attribs_on_create_without_oid / mlnx_create_acl_table  (libsai.so.0)
  syncd::VendorSai::create (syncd/VendorSai.cpp:223)
0x... is located 0 bytes after 20-byte region allocated by calloc() in check_attribs_metadata

Root cause: SONiC generates the SAI metadata (libsaimetadata) from the OCP headers only and drops the vendor SAI/custom folder, so sai_acl_bind_point_type_t is emitted without SAI_ACL_BIND_POINT_TYPE_CPU_PORT (valuescount == 5). The vendor SAI (36.0.14+) defines a 6th value, CPU_PORT, and the vendor libsai is linked against this SONiC-generated metadata inside syncd, so the two disagree on the enum size. libsai sizes a scratch array from the undersized metadata (calloc(enum_metadata->valuescount, ...) → room for 5) but walks the full vendor enum space including CPU_PORT, touching the 6th entry past the end of the allocation → heap-buffer-overflow. The fix is to build SONiC's metadata with the vendor custom headers so it matches the vendor SAI.

This change is a small piece of the overall fix. It updates sonic-sairedis to handle custom SAI headers appropriately. A subsequent PR to sonic-buildimage will implement the rest of the fix for this issue.

Work item tracking
  • Microsoft ADO (number only):

How did you do it?

Ship the headers for downstream consumers. sonic-sairedis debian/rules installs the synced custom headers into libsaivs-dev so downstream builds of the public saimetadata.h (e.g. sonic-swss). The install is guarded on header presence so builds not including custom headers are unaffected.

How did you verify/test it?

This issue can be verified with the following test command (sonic-mgmt):

PYTHONPATH=/devts/ /ngts_venv/bin/pytest \
  ngts/tests/nightly/rocev2_acl_counter/test_rocev2_acl_counter.py::TestRocev2AclCounter::test_rocev2_acl_counter[physical] \
  --setup_name=sonic_leopard_r-leopard-32 \
  --rootdir=/root/mars/workspace/sonic-mgmt/ngts \
  -c /root/mars/workspace/sonic-mgmt/ngts/pytest.ini \
  --log-level=INFO --showlocals --timeout 3600 --session-timeout 3600

Additionally, simply running sudo config acl add table ASAN_REPRO L3 -p Ethernet128 -s ingress is enough to repro the issue. You can then check for ASAN results with sudo cat /var/log/asan/syncd-asan.log.*.

Any platform specific information?

Documentation

Summary by CodeRabbit

  • Chores
    • Improved package installation to include vendor-specific SAI custom headers when they are available.
    • Builds without those optional headers continue to work unchanged.

@linux-foundation-easycla

linux-foundation-easycla Bot commented Jul 10, 2026

Copy link
Copy Markdown

CLA Signed
The committers listed above are authorized under a signed CLA.

  • ✅ login: brcarr-nv / name: Brian Carr (c0eecf1)

@mssonicbld

Copy link
Copy Markdown
Collaborator

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@yxieca-admin yxieca-admin left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@brcarr-nv can you fix the indentation change?

As for the unit test coverage picked up Debian folder, I think this is a mistake. @lolyu @mramezani95 can you check and fix this?

@mssonicbld

Copy link
Copy Markdown
Collaborator

Hi, there are workflow run(s) waiting for approval, you may be first-time contributor. I will notify maintainers to help approve once PR is approved. Thanks!

---Powered by SONiC BuildBot

@mssonicbld

Copy link
Copy Markdown
Collaborator

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@brcarr-nv
brcarr-nv requested a review from yxieca-admin July 13, 2026 21:33
@brcarr-nv
brcarr-nv force-pushed the mlnx-custom-headers-libsaivs-dev branch from c0eecf1 to bfe1dbb Compare July 13, 2026 22:12
@mssonicbld

Copy link
Copy Markdown
Collaborator

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@brcarr-nv

Copy link
Copy Markdown
Author

The tab spacing is necessary because my additions are shell commands, not make directives like the "ifneq" and similar statements above. This is all supposed to be nested under the override_dh_install recipe.

@yxieca
yxieca dismissed yxieca-admin’s stale review July 14, 2026 00:01

Issue explained.

When vendor custom SAI headers are present in SAI/custom/, parse.pl emits
"#include <saicustom.h>" into the generated saimetadata.h. Install those
custom headers into libsaivs-dev so the include resolves in downstream
builds (e.g. sonic-swss). libsaivs-dev conflicts with mlnx-sai, so there is
no /usr/include/sai/saicustom.h overwrite clash. Guarded on header
existence, so it is a no-op for builds without synced custom headers.

Signed-off-by: Brian Carr <brcarr@nvidia.com>
@brcarr-nv
brcarr-nv force-pushed the mlnx-custom-headers-libsaivs-dev branch from bfe1dbb to c3031f7 Compare July 14, 2026 00:08
@mssonicbld

Copy link
Copy Markdown
Collaborator

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@mssonicbld

Copy link
Copy Markdown
Collaborator

Hi @sonic-net/sonic-sairedis-maintainer, this approved PR has workflow run(s) waiting for approval. Please help review. Thanks!

---Powered by SONiC BuildBot

1 similar comment
@mssonicbld

Copy link
Copy Markdown
Collaborator

Hi @sonic-net/sonic-sairedis-maintainer, this approved PR has workflow run(s) waiting for approval. Please help review. Thanks!

---Powered by SONiC BuildBot

@mssonicbld

Copy link
Copy Markdown
Collaborator

This PR has backport request label(s) for branch(es): 202605, but is missing required test information. Please make sure you tick the tested branch(es) in the Tested branch section and provide test evidence (e.g., 202605: <test result>) in the Test result section as well in your PR description.

---Powered by SONiC BuildBot

@yxieca-admin
yxieca-admin requested a review from lolyu July 23, 2026 23:55

@lolyu lolyu left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left an inline comment on the header-install glob (*custom*.h coverage). Otherwise the change and root-cause analysis look sound. Also worth filling in the Tested branch / test-evidence section — the 202605 backport bot is flagging it as missing.

@lolyu lolyu left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One comment on the header-install glob (*custom*.h coverage vs. the aggregated saicustom.h include chain). Root-cause analysis and overall approach look sound.

Comment thread debian/rules
if ls SAI/custom/*custom*.h >/dev/null 2>&1 && [ -d debian/libsaivs-dev/usr/include/sai ]; then \
install -m 644 SAI/custom/*custom*.h debian/libsaivs-dev/usr/include/sai/; \
fi

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The *custom*.h glob is narrower than the include chain the generated metadata actually consumes, and the failure mode is silent + deferred to downstream build time.

parse.pl emits #include <saicustom.h> into the public saimetadata.h (guarded if scalar@ch), but that saicustom.h is an aggregator: parse.pl discovers custom content by scanning $CUSTOM_DIR = "../custom/" and emits per-API includes named saicustom$shortapi.h (parse.pl ~L4688) — saicustomacl.h, saicustomswitch.h, etc. So the real downstream include chain is:

saimetadata.h -> saicustom.h -> saicustomacl.h, saicustomswitch.h, ...

Every link in that chain has to be present in libsaivs-dev for the downstream saimetadata.h compile (e.g. sonic-swss) to resolve.

Two problems with *custom*.h:

  1. Coverage relies on the "custom" substring being in every filename. Mellanox's split happens to name everything saicustom*.h today, so the glob catches them — but nothing in the SAI meta build requires that. saicustom.h (or a per-API custom header) is free to #include a vendor header in SAI/custom/ whose name doesn't contain "custom" (a shared typedef/defs header, etc.). Any such header is silently dropped and the chain breaks at swss build time with a confusing "no such file" far from here.

  2. The guard doesn't verify coverage. ls SAI/custom/*custom*.h >/dev/null 2>&1 only checks that at least one matching file exists, not that the installed set matches what the aggregator includes. Install a partial set and the guard still passes.

Since libsaivs-dev conflicts with vendor dev packages (as the PR description establishes), there's no file-overwrite risk — which removes the only reason to be conservative about what's installed. Suggest just shipping the whole custom dir the metadata build consumes:

install -m 644 SAI/custom/*.h debian/libsaivs-dev/usr/include/sai/;

That mirrors parse.pl's $CUSTOM_DIR scan exactly and guarantees the full aggregated include chain resolves.

Question: does the vendor SAI/custom/ ever contain headers — directly, or transitively #included by saicustom*.h — that don't match *custom*? If so this glob drops them. Given there's no overwrite risk, is there any reason not to install SAI/custom/*.h?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants