[server] Compare ClientConnection instead of wl_client in SeatInterface

A downstream KWin test shows a possible heap-use-after-free if we
access the wl_client pointer. Basically we get the client disconnected
just before the focused surface gets unbind. Thus for a short moment
the ClientConnection pointer is gone. This needs to be extended with
a test case, but for the moment it should be good enough to get KWin
green again.
This commit is contained in:
Martin Gräßlin 2016-05-23 10:43:45 +02:00
parent f4f2725132
commit 5f5dbc5155

View file

@ -349,14 +349,15 @@ void SeatInterface::Private::getPointer(wl_client *client, wl_resource *resource
{ {
// TODO: only create if seat has pointer? // TODO: only create if seat has pointer?
PointerInterface *pointer = new PointerInterface(q, resource); PointerInterface *pointer = new PointerInterface(q, resource);
pointer->create(display->getConnection(client), qMin(wl_resource_get_version(resource), s_pointerVersion), id); auto clientConnection = display->getConnection(client);
pointer->create(clientConnection, qMin(wl_resource_get_version(resource), s_pointerVersion), id);
if (!pointer->resource()) { if (!pointer->resource()) {
wl_resource_post_no_memory(resource); wl_resource_post_no_memory(resource);
delete pointer; delete pointer;
return; return;
} }
pointers << pointer; pointers << pointer;
if (globalPointer.focus.surface && globalPointer.focus.surface->client()->client() == client) { if (globalPointer.focus.surface && globalPointer.focus.surface->client() == clientConnection) {
// this is a pointer for the currently focused pointer surface // this is a pointer for the currently focused pointer surface
if (!globalPointer.focus.pointer) { if (!globalPointer.focus.pointer) {
globalPointer.focus.pointer = pointer; globalPointer.focus.pointer = pointer;
@ -385,7 +386,8 @@ void SeatInterface::Private::getKeyboard(wl_client *client, wl_resource *resourc
{ {
// TODO: only create if seat has keyboard? // TODO: only create if seat has keyboard?
KeyboardInterface *keyboard = new KeyboardInterface(q, resource); KeyboardInterface *keyboard = new KeyboardInterface(q, resource);
keyboard->create(display->getConnection(client), qMin(wl_resource_get_version(resource), s_keyboardVersion) , id); auto clientConnection = display->getConnection(client);
keyboard->create(clientConnection, qMin(wl_resource_get_version(resource), s_keyboardVersion) , id);
if (!keyboard->resource()) { if (!keyboard->resource()) {
wl_resource_post_no_memory(resource); wl_resource_post_no_memory(resource);
delete keyboard; delete keyboard;
@ -396,7 +398,7 @@ void SeatInterface::Private::getKeyboard(wl_client *client, wl_resource *resourc
keyboard->setKeymap(keys.keymap.fd, keys.keymap.size); keyboard->setKeymap(keys.keymap.fd, keys.keymap.size);
} }
keyboards << keyboard; keyboards << keyboard;
if (keys.focus.surface && keys.focus.surface->client()->client() == client) { if (keys.focus.surface && keys.focus.surface->client() == clientConnection) {
// this is a keyboard for the currently focused keyboard surface // this is a keyboard for the currently focused keyboard surface
if (!keys.focus.keyboard) { if (!keys.focus.keyboard) {
keys.focus.keyboard = keyboard; keys.focus.keyboard = keyboard;
@ -423,14 +425,15 @@ void SeatInterface::Private::getTouch(wl_client *client, wl_resource *resource,
{ {
// TODO: only create if seat has touch? // TODO: only create if seat has touch?
TouchInterface *touch = new TouchInterface(q, resource); TouchInterface *touch = new TouchInterface(q, resource);
touch->create(display->getConnection(client), qMin(wl_resource_get_version(resource), s_touchVersion), id); auto clientConnection = display->getConnection(client);
touch->create(clientConnection, qMin(wl_resource_get_version(resource), s_touchVersion), id);
if (!touch->resource()) { if (!touch->resource()) {
wl_resource_post_no_memory(resource); wl_resource_post_no_memory(resource);
delete touch; delete touch;
return; return;
} }
touchs << touch; touchs << touch;
if (touchInterface.focus.surface && touchInterface.focus.surface->client()->client() == client) { if (touchInterface.focus.surface && touchInterface.focus.surface->client() == clientConnection) {
// this is a touch for the currently focused touch surface // this is a touch for the currently focused touch surface
if (!touchInterface.focus.touch) { if (!touchInterface.focus.touch) {
touchInterface.focus.touch = touch; touchInterface.focus.touch = touch;