Skip to content

Commit 1583c24

Browse files
Another fix for texture copy validation (#8019)
1 parent 7473844 commit 1583c24

File tree

2 files changed

+54
-2
lines changed

2 files changed

+54
-2
lines changed

tests/tests/wgpu-gpu/queue_transfer.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,54 @@ static QUEUE_WRITE_TEXTURE_OVERFLOW: GpuTestConfiguration =
9999
Some("end up overrunning the bounds of the destination texture"),
100100
);
101101
});
102+
103+
#[gpu_test]
104+
static QUEUE_WRITE_TEXTURE_BUFFER_OOB: GpuTestConfiguration =
105+
GpuTestConfiguration::new().run_sync(|ctx| {
106+
// Test that transfers overrunning the end of the source buffer, or
107+
// where offset + size overflows a u64, are rejected.
108+
for offset in [120, u64::MAX - 3] {
109+
let texture = ctx.device.create_texture(&wgpu::TextureDescriptor {
110+
label: None,
111+
size: wgpu::Extent3d {
112+
width: 146,
113+
height: 25,
114+
depth_or_array_layers: 192,
115+
},
116+
mip_level_count: 1,
117+
sample_count: 1,
118+
dimension: wgpu::TextureDimension::D2,
119+
format: wgpu::TextureFormat::Rgba32Float,
120+
usage: wgpu::TextureUsages::COPY_DST,
121+
view_formats: &[],
122+
});
123+
124+
let data = vec![255; 128];
125+
126+
fail(
127+
&ctx.device,
128+
|| {
129+
ctx.queue.write_texture(
130+
wgpu::TexelCopyTextureInfo {
131+
texture: &texture,
132+
mip_level: 0,
133+
origin: wgpu::Origin3d { x: 0, y: 0, z: 1 },
134+
aspect: wgpu::TextureAspect::All,
135+
},
136+
&data,
137+
wgpu::TexelCopyBufferLayout {
138+
offset,
139+
bytes_per_row: Some(16),
140+
rows_per_image: Some(1),
141+
},
142+
wgpu::Extent3d {
143+
width: 1,
144+
height: 1,
145+
depth_or_array_layers: 1,
146+
},
147+
);
148+
},
149+
Some("would end up overrunning the bounds of the source buffer"),
150+
);
151+
}
152+
});

wgpu-core/src/command/transfer.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -351,10 +351,11 @@ pub(crate) fn validate_linear_texture_data(
351351
}
352352
}
353353

354-
if offset + bytes_in_copy > buffer_size {
354+
// Avoid underflow in the subtraction by checking bytes_in_copy against buffer_size first.
355+
if bytes_in_copy > buffer_size || offset > buffer_size - bytes_in_copy {
355356
return Err(TransferError::BufferOverrun {
356357
start_offset: offset,
357-
end_offset: offset + bytes_in_copy,
358+
end_offset: offset.wrapping_add(bytes_in_copy),
358359
buffer_size,
359360
side: buffer_side,
360361
});

0 commit comments

Comments
 (0)