Skip to content

Commit 48c1297

Browse files
committed
Fix security issues in native bridges: add Vulkan error checking, bounds-safe memset, volatile dispose flags, cleanup on probe failure
1 parent 98d9ab1 commit 48c1297

4 files changed

Lines changed: 25 additions & 6 deletions

File tree

osu.Android/Native/OboeAudioBridge.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ namespace osu.Android.Native
1414
public sealed class OboeAudioBridge : IDisposable
1515
{
1616
private long nativePtr;
17-
private bool disposed;
17+
private volatile bool disposed;
1818

1919
/// <summary>
2020
/// Creates and opens a new low-latency Oboe audio stream.

osu.Android/Native/VulkanProbe.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ namespace osu.Android.Native
1414
public sealed class VulkanProbe : IDisposable
1515
{
1616
private long nativePtr;
17-
private bool disposed;
17+
private volatile bool disposed;
1818

1919
/// <summary>
2020
/// Creates a Vulkan probe. Returns null if native library is unavailable.

osu.Android/Native/oboe_bridge.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,10 @@ oboe::DataCallbackResult OboeBridge::onAudioReady(
8787

8888
// Output silence - the primary purpose of this stream is latency measurement.
8989
// Future: route game audio through this path for lowest possible latency.
90-
memset(audioData, 0, numFrames * stream->getChannelCount() * sizeof(float));
90+
size_t byteCount = static_cast<size_t>(numFrames)
91+
* static_cast<size_t>(stream->getChannelCount())
92+
* sizeof(float);
93+
memset(audioData, 0, byteCount);
9194

9295
updateLatency();
9396

osu.Android/Native/vulkan_bridge.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
VulkanProbe::VulkanProbe() {
1515
available_ = createInstance() && queryDevice();
1616

17+
if (!available_) {
18+
cleanup();
19+
}
20+
1721
if (available_) {
1822
LOGI("Vulkan available: %s (API %u.%u.%u, driver %u)",
1923
deviceInfo_.deviceName.c_str(),
@@ -65,7 +69,11 @@ bool VulkanProbe::queryDevice() {
6569
}
6670

6771
std::vector<VkPhysicalDevice> devices(deviceCount);
68-
vkEnumeratePhysicalDevices(instance_, &deviceCount, devices.data());
72+
73+
if (vkEnumeratePhysicalDevices(instance_, &deviceCount, devices.data()) != VK_SUCCESS || deviceCount == 0) {
74+
LOGE("Failed to enumerate Vulkan physical devices");
75+
return false;
76+
}
6977

7078
// Pick the first discrete GPU, or fall back to the first device.
7179
VkPhysicalDevice selected = devices[0];
@@ -90,10 +98,18 @@ bool VulkanProbe::queryDevice() {
9098

9199
// Check for swapchain extension support.
92100
uint32_t extCount = 0;
93-
vkEnumerateDeviceExtensionProperties(selected, nullptr, &extCount, nullptr);
101+
102+
if (vkEnumerateDeviceExtensionProperties(selected, nullptr, &extCount, nullptr) != VK_SUCCESS || extCount == 0) {
103+
deviceInfo_.supportsSwapchain = false;
104+
return true;
105+
}
94106

95107
std::vector<VkExtensionProperties> extensions(extCount);
96-
vkEnumerateDeviceExtensionProperties(selected, nullptr, &extCount, extensions.data());
108+
109+
if (vkEnumerateDeviceExtensionProperties(selected, nullptr, &extCount, extensions.data()) != VK_SUCCESS) {
110+
deviceInfo_.supportsSwapchain = false;
111+
return true;
112+
}
97113

98114
deviceInfo_.supportsSwapchain = false;
99115

0 commit comments

Comments
 (0)