Skip to content

fix: validate embedding ids unconditionally in CPU kernel to prevent OOB read (CWE-125)#79507

Open
Pandya-mayur wants to merge 2 commits into
PaddlePaddle:developfrom
Pandya-mayur:fix/cwe-125-embedding-oob-read
Open

fix: validate embedding ids unconditionally in CPU kernel to prevent OOB read (CWE-125)#79507
Pandya-mayur wants to merge 2 commits into
PaddlePaddle:developfrom
Pandya-mayur:fix/cwe-125-embedding-oob-read

Conversation

@Pandya-mayur

@Pandya-mayur Pandya-mayur commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

PR Category

Operator Mechanism

PR Types

Security

Description

Fixes #79491 — out-of-bounds read in the CPU embedding kernel when padding_idx is set.

Problem

In paddle/phi/kernels/cpu/embedding_kernel.cc, EmbeddingCPUFunctor::apply validates each id only inside:

if (padding_idx_ == kNoPadding && ids[i] != padding_idx_) {
  PADDLE_ENFORCE_LT(ids[i], row_number, ...);
  PADDLE_ENFORCE_GE(ids[i], 0, ...);
}

kNoPadding is -1, so as soon as an embedding layer is created with any padding_idx (e.g. the very common padding_idx=0 used in NLP models), the entire range check is skipped for every id. The copy loop then indexes the weight table with an unvalidated, attacker-controlled ids[i]:

memcpy(output + i * row_width,
       table + ids[i] * row_width,   // ids[i] unchecked
       row_width * sizeof(T));
  • An out-of-range id (e.g. 40 on a 16-row table) returns raw heap bytes past the weight matrix — information disclosure.
  • A large id (e.g. 1e9) crashes the process with SIGSEGV in EmbeddingCPUFunctor::apply.

A reproducible PoC and an AddressSanitizer trace (heap-buffer-overflow READ) are in issue #79491.

Solution

  • Make the range check 0 <= id < row_number unconditional for every id.
  • Keep only the padding-row zeroing conditional on padding_idx.

Valid inputs are unaffected (padding indices are always in range); only genuinely out-of-range ids are now rejected with the existing InvalidArgument error instead of reading out of bounds.

Note: this PR fixes the CPU kernel reported in the issue. The GPU/XPU embedding kernels share the same padding pattern and can be hardened as a follow-up.

This vulnerability has also been responsibly disclosed to the Baidu security team (international_bsrc@baidu.com).

cc @luotao1

是否引起精度变化

The id-range check in EmbeddingCPUFunctor::apply was nested inside
`if (padding_idx_ == kNoPadding && ids[i] != padding_idx_)`. Because
kNoPadding is -1, creating an embedding layer with any padding_idx
(e.g. the common padding_idx=0) skipped the bounds check for every id,
and the copy loop then indexed the weight table with an unvalidated,
attacker-controlled id, causing an out-of-bounds read (heap disclosure
or crash).

Make the range check (0 <= id < row_number) unconditional; only the
padding-row zeroing remains conditional on padding_idx.

Ref: PaddlePaddle#79491
@paddle-bot

paddle-bot Bot commented Jul 18, 2026

Copy link
Copy Markdown

你的PR提交成功,感谢你对开源项目的贡献!
请关注后续CI自动化测试结果,详情请参考Paddle-CI手册
Your PR has been submitted. Thanks for your contribution!
Please wait for the result of CI firstly. See Paddle CI Manual for details.

@paddle-bot paddle-bot Bot added the contributor External developers label Jul 18, 2026

@risemeup1111 risemeup1111 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.

已发现需要修复的问题,细节已写在 inline review comments 里。

Powered by Nyanpasu with gpt-5.5 xhigh, please check the suggestions carefully.

row_number,
ids[i]));
}
PADDLE_ENFORCE_LT(

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.

P1 优先级:P1

这次把检查条件改对了,但没有补回归测试。现有 test_ai_nn_functional_input.py / test_ai_embedding_onehot.py 只覆盖合法 padding_idx、负 padding_idxpadding_idx 越界,没有覆盖“padding_idx 已设置时输入 id 越界”的 CPU 路径。没有这个 case,后续很容易把这段保护逻辑改回去,CI 也拦不住这类 OOB 回归。

建议补一个 CPU 动态图用例,至少验证 padding_idx=0 时越界 id 会抛 ValueError,例如:

paddle.disable_static(paddle.CPUPlace())
x = paddle.to_tensor([0, 6], dtype='int64')
w = paddle.randn([5, 3])
with self.assertRaises(ValueError):
    paddle.nn.functional.embedding(x, w, padding_idx=0)

处理要求:请针对该评论修复并提交新的 commit。

Verifies that with padding_idx set, an out-of-range (or negative) input id
raises ValueError on the CPU kernel instead of reading out of bounds. Forces
the CPU place so the test is independent of the build target.

@risemeup1111 risemeup1111 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.

已复查新增 commit,CPU 越界 id 的回归测试已经补上,之前的 P1 现在看起来已覆盖。当前未发现需要阻塞合入的问题,细节见之前的 inline review comments。

Powered by Nyanpasu with gpt-5.5 xhigh, please check the suggestions carefully.

@Pandya-mayur

Copy link
Copy Markdown
Contributor Author

Thanks for the review — addressed the P1.

  • Added a CPU regression test: test/ai_edited_test/test_ai_nn_functional_input.py::TestEmbedding::test_embedding_out_of_range_id_with_padding_idx. It asserts that with padding_idx=0, an out-of-range id (40 on a 16-row table) and a negative id raise ValueError instead of reading out of bounds. It forces the CPU place (paddle.set_device('cpu'), restored afterward) so it exercises the fixed kernel regardless of the build target.
  • Also fixed the PR-template check (removed the leading HTML comment so ### PR Category is the first line).

@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (develop@8d917cd). Learn more about missing BASE report.

Additional details and impacted files
@@             Coverage Diff             @@
##             develop    #79507   +/-   ##
===========================================
  Coverage           ?   100.00%           
===========================================
  Files              ?         1           
  Lines              ?         2           
  Branches           ?         0           
===========================================
  Hits               ?         2           
  Misses             ?         0           
  Partials           ?         0           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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

Labels

contributor External developers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Out-of-bounds read in the CPU embedding kernel when padding_idx is set (heap memory disclosure + remote crash)

3 participants