screenshooter: Add SHM buffer destroy listener to avoid invalid memcpy
This adds a destroy listener on the SHM buffer provided by our client. It will unregister the frame notify listener in case our buffer is destroyed before the frame signal is emitted and thus avoid a memcpy to invalid memory. Signed-off-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
This commit is contained in:
parent
036a76e3eb
commit
0afd3428dc
|
@ -45,7 +45,8 @@
|
|||
#include "wcap/wcap-decode.h"
|
||||
|
||||
struct screenshooter_frame_listener {
|
||||
struct wl_listener listener;
|
||||
struct wl_listener frame_listener;
|
||||
struct wl_listener buffer_destroy_listener;
|
||||
struct weston_buffer *buffer;
|
||||
struct weston_output *output;
|
||||
weston_screenshooter_done_func_t done;
|
||||
|
@ -120,7 +121,8 @@ screenshooter_frame_notify(struct wl_listener *listener, void *data)
|
|||
{
|
||||
struct screenshooter_frame_listener *l =
|
||||
container_of(listener,
|
||||
struct screenshooter_frame_listener, listener);
|
||||
struct screenshooter_frame_listener,
|
||||
frame_listener);
|
||||
struct weston_output *output = l->output;
|
||||
struct weston_compositor *compositor = output->compositor;
|
||||
const pixman_format_code_t pixman_format =
|
||||
|
@ -130,6 +132,8 @@ screenshooter_frame_notify(struct wl_listener *listener, void *data)
|
|||
|
||||
weston_output_disable_planes_decr(output);
|
||||
wl_list_remove(&listener->link);
|
||||
wl_list_remove(&l->buffer_destroy_listener.link);
|
||||
|
||||
stride = l->buffer->width * (PIXMAN_FORMAT_BPP(pixman_format) / 8);
|
||||
pixels = malloc(stride * l->buffer->height);
|
||||
|
||||
|
@ -177,6 +181,22 @@ screenshooter_frame_notify(struct wl_listener *listener, void *data)
|
|||
free(l);
|
||||
}
|
||||
|
||||
static void
|
||||
buffer_destroy_handle(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct screenshooter_frame_listener *l =
|
||||
container_of(listener,
|
||||
struct screenshooter_frame_listener,
|
||||
buffer_destroy_listener);
|
||||
|
||||
weston_output_disable_planes_decr(l->output);
|
||||
wl_list_remove(&listener->link);
|
||||
wl_list_remove(&l->frame_listener.link);
|
||||
l->done(l->data, WESTON_SCREENSHOOTER_BAD_BUFFER);
|
||||
|
||||
free(l);
|
||||
}
|
||||
|
||||
WL_EXPORT int
|
||||
weston_screenshooter_shoot(struct weston_output *output,
|
||||
struct weston_buffer *buffer,
|
||||
|
@ -205,8 +225,13 @@ weston_screenshooter_shoot(struct weston_output *output,
|
|||
l->output = output;
|
||||
l->done = done;
|
||||
l->data = data;
|
||||
l->listener.notify = screenshooter_frame_notify;
|
||||
wl_signal_add(&output->frame_signal, &l->listener);
|
||||
|
||||
l->frame_listener.notify = screenshooter_frame_notify;
|
||||
wl_signal_add(&output->frame_signal, &l->frame_listener);
|
||||
|
||||
l->buffer_destroy_listener.notify = buffer_destroy_handle;
|
||||
wl_signal_add(&buffer->destroy_signal, &l->buffer_destroy_listener);
|
||||
|
||||
weston_output_disable_planes_incr(output);
|
||||
weston_output_schedule_repaint(output);
|
||||
|
||||
|
|
Loading…
Reference in New Issue