Skip to content

Conversation

@cobalt-github-releaser-bot
Copy link
Collaborator

Refer to the original PR: #8865

Bug: 474508805

Issue[RDK]:
mediakeys.getmetrics fails() as

  • C26 : FAIL
  • c25 newly built (25.lts.1+) FAIL
  • c25 with default RDK image: PASS

This PR fixes the above YTS failure

Bug: 474508805

**Issue[RDK]:**
mediakeys.getmetrics fails() as
- C26 : FAIL
- c25 newly built (25.lts.1+)  FAIL
- c25 with default RDK image:  PASS

This PR fixes the above YTS failure

---------

Co-authored-by: Jonas Tsai <jonastsai@google.com>
(cherry picked from commit 8cacfce)
@github-actions
Copy link

🤖 Gemini Suggested Commit Message


starboard: Fix MediaKeys.GetMetrics failures on RDK

Implement a fallback mechanism in DrmSystemOcdm to use
opencdm_get_metrics when opencdm_get_metric_system_data fails. This
addresses issues on RDK/Amlogic platforms where the older API may
return INTERFACE_NOT_IMPLEMENTED or error.

Additionally, update MojoCdm to explicitly reject the GetMetrics
promise when no metrics string is received, providing clear error
signaling to the caller.

Bug: 474508805

💡 Pro Tips for a Better Commit Message:

  1. Influence the Result: Want to change the output? You can write custom prompts or instructions directly in the Pull Request description. The model uses that text to generate the message.
  2. Re-run the Generator: Post a comment with: /generate-commit-message

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request cherry-picks a fix for MediaKeys.GetMetrics failures on RDK platforms by introducing a fallback mechanism using a new opencdm_get_metrics function and improving promise handling for unavailable metrics. However, a critical heap-based buffer overflow vulnerability has been identified in drm_system_ocdm.cc. This vulnerability, stemming from improper uint16_t usage for length calculations, can lead to integer truncation and overflow, resulting in an undersized buffer allocation during Base64 encoding, potentially causing denial of service or arbitrary code execution. It is strongly recommended to use size_t for all length variables and validate input sizes. Please address this critical vulnerability before merging.

Comment on lines +816 to +822
uint16_t buffer_length = buffer.size();
uint16_t out_length = (((buffer_length * 8) / 6) + 4) * sizeof(TCHAR);
metrics_.resize(out_length, '\0');
out_length = WPEFramework::Core::URL::Base64Encode(
reinterpret_cast<const uint8_t*>(buffer.data()), buffer_length,
reinterpret_cast<char*>(metrics_.data()), out_length, false);
metrics_.resize(out_length);
Copy link
Contributor

Choose a reason for hiding this comment

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

security-critical critical

A critical heap-based buffer overflow vulnerability exists in the GetMetrics function. This occurs because buffer.size() (a size_t) is truncated to a uint16_t for buffer_length, which can lead to incorrect size calculations if the input exceeds 65,535 bytes. Consequently, the out_length calculation for Base64 encoding can also overflow a uint16_t, causing metrics_.resize() to allocate an undersized buffer. The subsequent Base64Encode call then writes beyond this buffer's bounds, leading to a heap overflow, which could result in denial of service or arbitrary code execution. It is crucial to use size_t for all length variables and to validate input sizes to prevent this.

      size_t buffer_length = buffer.size();
// Add a reasonable size limit check to prevent extreme memory allocation.
const size_t kMaxMetricsSize = 1024 * 1024; // 1MB limit, adjust as needed
if (buffer_length > kMaxMetricsSize) {
  SB_LOG(ERROR) << "Metrics data exceeds size limit.";
  return;
}
size_t out_length = (((buffer_length * 8) / 6) + 4) * sizeof(TCHAR);
metrics_.resize(out_length, '\0');
size_t encoded_length = WPEFramework::Core::URL::Base64Encode(
    reinterpret_cast<const uint8_t*>(buffer.data()), buffer_length,
    reinterpret_cast<char*>(metrics_.data()), out_length, false);
metrics_.resize(encoded_length);

Comment on lines +431 to +432
cdm_promise_adapter_.ResolvePromise(promise_id,
metrics_string.value_or(std::string()));
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Since you're already checking if metrics_string has a value with if (metrics_string), you can directly dereference it using *metrics_string. This is slightly more efficient as it avoids the value_or call which may create a temporary std::string.

    cdm_promise_adapter_.ResolvePromise(promise_id, *metrics_string);

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants