mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-07 07:58:51 +00:00
shmsink: fix memory corruption when a client disconnects (fixes #675640)
Also, add a check to make sure a client isn't dumped twice
This commit is contained in:
parent
9503daa56a
commit
3971ef089c
1 changed files with 23 additions and 6 deletions
|
@ -177,7 +177,7 @@ struct CommandBuffer
|
||||||
static ShmArea *sp_open_shm (char *path, int id, mode_t perms, size_t size);
|
static ShmArea *sp_open_shm (char *path, int id, mode_t perms, size_t size);
|
||||||
static void sp_close_shm (ShmArea * area);
|
static void sp_close_shm (ShmArea * area);
|
||||||
static int sp_shmbuf_dec (ShmPipe * self, ShmBuffer * buf,
|
static int sp_shmbuf_dec (ShmPipe * self, ShmBuffer * buf,
|
||||||
ShmBuffer * prev_buf);
|
ShmBuffer * prev_buf, ShmClient * client);
|
||||||
static void sp_shm_area_dec (ShmPipe * self, ShmArea * area);
|
static void sp_shm_area_dec (ShmPipe * self, ShmArea * area);
|
||||||
|
|
||||||
|
|
||||||
|
@ -696,7 +696,7 @@ sp_writer_recv (ShmPipe * self, ShmClient * client)
|
||||||
for (buf = self->buffers; buf; buf = buf->next) {
|
for (buf = self->buffers; buf; buf = buf->next) {
|
||||||
if (buf->shm_area->id == cb.area_id &&
|
if (buf->shm_area->id == cb.area_id &&
|
||||||
buf->offset == cb.payload.ack_buffer.offset) {
|
buf->offset == cb.payload.ack_buffer.offset) {
|
||||||
sp_shmbuf_dec (self, buf, prev_buf);
|
sp_shmbuf_dec (self, buf, prev_buf, client);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
prev_buf = buf;
|
prev_buf = buf;
|
||||||
|
@ -811,8 +811,27 @@ error:
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
sp_shmbuf_dec (ShmPipe * self, ShmBuffer * buf, ShmBuffer * prev_buf)
|
sp_shmbuf_dec (ShmPipe * self, ShmBuffer * buf, ShmBuffer * prev_buf,
|
||||||
|
ShmClient * client)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
int had_client = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove client from the list of buffer users. Here we make sure that
|
||||||
|
* if a client closes connection but already decremented the use count
|
||||||
|
* for this buffer, but other clients didn't have time to decrement
|
||||||
|
* buffer will not be freed too early in sp_writer_close_client.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < buf->num_clients; i++) {
|
||||||
|
if (buf->clients[i] == client->fd) {
|
||||||
|
buf->clients[i] = -1;
|
||||||
|
had_client = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert (had_client);
|
||||||
|
|
||||||
buf->use_count--;
|
buf->use_count--;
|
||||||
|
|
||||||
if (buf->use_count == 0) {
|
if (buf->use_count == 0) {
|
||||||
|
@ -827,7 +846,6 @@ sp_shmbuf_dec (ShmPipe * self, ShmBuffer * buf, ShmBuffer * prev_buf)
|
||||||
spalloc_free1 (sizeof (ShmBuffer) + sizeof (int) * buf->num_clients, buf);
|
spalloc_free1 (sizeof (ShmBuffer) + sizeof (int) * buf->num_clients, buf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -845,8 +863,7 @@ again:
|
||||||
|
|
||||||
for (i = 0; i < buffer->num_clients; i++) {
|
for (i = 0; i < buffer->num_clients; i++) {
|
||||||
if (buffer->clients[i] == client->fd) {
|
if (buffer->clients[i] == client->fd) {
|
||||||
buffer->clients[i] = -1;
|
if (!sp_shmbuf_dec (self, buffer, prev_buf, client))
|
||||||
if (!sp_shmbuf_dec (self, buffer, prev_buf))
|
|
||||||
goto again;
|
goto again;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue