gfx-rs / wgpu

A cross-platform, safe, pure-Rust graphics API.
https://wgpu.rs
Apache License 2.0
12.42k stars 909 forks source link

Queue::write_texture crashes when supplying too much data #6054

Closed HalloIhr0 closed 2 months ago

HalloIhr0 commented 2 months ago

Description When trying to write more data than the texture expects with Queue::write_texture, the program crashes in a variety of different ways:

Repro steps

fn main() {
    let instance = wgpu::Instance::default();
    let adapter = pollster::block_on(instance.request_adapter(&wgpu::RequestAdapterOptionsBase {
        power_preference: wgpu::PowerPreference::HighPerformance,
        force_fallback_adapter: false,
        compatible_surface: None,
    }))
    .unwrap();

    let (device, queue) = pollster::block_on(adapter.request_device(
        &wgpu::DeviceDescriptor {
            label: None,
            required_features: wgpu::Features::empty(),
            required_limits: wgpu::Limits::default().using_resolution(adapter.limits()),
            memory_hints: wgpu::MemoryHints::Performance,
        },
        None,
    ))
    .unwrap();

    let size = wgpu::Extent3d {
        width: 1024,
        height: 1024,
        depth_or_array_layers: 1,
    };
    let texture = device.create_texture(&wgpu::TextureDescriptor {
        label: None,
        size,
        mip_level_count: 1,
        sample_count: 1,
        dimension: wgpu::TextureDimension::D2,
        format: wgpu::TextureFormat::Rgba8UnormSrgb,
        usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
        view_formats: &[],
    });

    // Slightly too large: assertion fails
    // wgpu-segfault: malloc.c:3079: __libc_malloc: Assertion `!victim || chunk_is_mmapped (mem2chunk (victim)) || ar_ptr == arena_for_chunk (mem2chunk (victim))' failed.
    // Aborted (core dumped)

    // let data = [255; 4*1024*1024 + 1];

    // Way to large: Stack overflow
    // thread 'main' has overflowed its stack
    // fatal runtime error: stack overflow
    // Aborted (core dumped)

    // let data = [255; 4*1024*1024 * 4];

    // Somewhere in the middle: Segfault (but sometimes also freeze or stack overflow)
    // Segmentation fault (core dumped)

    let data = [255; 4*1024*1024 + 1024];

    queue.write_texture(
        wgpu::ImageCopyTexture {
            texture: &texture,
            mip_level: 0,
            origin: wgpu::Origin3d::ZERO,
            aspect: wgpu::TextureAspect::All,
        },
        &data,
        wgpu::ImageDataLayout {
            offset: 0,
            bytes_per_row: Some(4 * 1024), // bytes_per_pixel * width
            rows_per_image: None,
        },
        size,
    );
}

Expected vs observed behavior I expect wgpu to panic with a Validation Error, similar to what happens when supplying too little data, instead of just segfaulting and possibly causing unsafe behaviour

Extra materials

Platform

teoxoy commented 2 months ago

This was fixed by https://github.com/gfx-rs/wgpu/pull/6009. It will be part of the next minor release.