[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:
parent
f4f2725132
commit
5f5dbc5155
1 changed files with 9 additions and 6 deletions
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue