security-context: avoid UB in C macro (#8229)

to safely use wl_container_of with a class the class has to be no
virtual functions, no inheritance, and uniform access control (e.g all
public)

work around this by putting this into a destroywrapper struct.
This commit is contained in:
Tom Englund 2024-10-25 12:26:48 +02:00 committed by GitHub
parent 3cec45d821
commit f0e023bff2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 17 additions and 7 deletions

View File

@ -22,7 +22,8 @@ SP<CSecurityContextSandboxedClient> CSecurityContextSandboxedClient::create(int
} }
static void onSecurityContextClientDestroy(wl_listener* l, void* d) { static void onSecurityContextClientDestroy(wl_listener* l, void* d) {
CSecurityContextSandboxedClient* client = wl_container_of(l, client, destroyListener); CSecurityContextSandboxedClientDestroyWrapper* wrap = wl_container_of(l, wrap, listener);
CSecurityContextSandboxedClient* client = wrap->parent;
client->onDestroy(); client->onDestroy();
} }
@ -31,12 +32,15 @@ CSecurityContextSandboxedClient::CSecurityContextSandboxedClient(int clientFD_)
if (!client) if (!client)
return; return;
destroyListener.notify = ::onSecurityContextClientDestroy; wl_list_init(&destroyListener.listener.link);
wl_client_add_destroy_late_listener(client, &destroyListener); destroyListener.listener.notify = ::onSecurityContextClientDestroy;
destroyListener.parent = this;
wl_client_add_destroy_late_listener(client, &destroyListener.listener);
} }
CSecurityContextSandboxedClient::~CSecurityContextSandboxedClient() { CSecurityContextSandboxedClient::~CSecurityContextSandboxedClient() {
wl_list_remove(&destroyListener.link); wl_list_remove(&destroyListener.listener.link);
wl_list_init(&destroyListener.listener.link);
close(clientFD); close(clientFD);
} }

View File

@ -37,14 +37,20 @@ class CSecurityContextManagerResource {
SP<CWpSecurityContextManagerV1> resource; SP<CWpSecurityContextManagerV1> resource;
}; };
class CSecurityContextSandboxedClient;
struct CSecurityContextSandboxedClientDestroyWrapper {
wl_listener listener;
CSecurityContextSandboxedClient* parent = nullptr;
};
class CSecurityContextSandboxedClient { class CSecurityContextSandboxedClient {
public: public:
static SP<CSecurityContextSandboxedClient> create(int clientFD); static SP<CSecurityContextSandboxedClient> create(int clientFD);
~CSecurityContextSandboxedClient(); ~CSecurityContextSandboxedClient();
void onDestroy(); void onDestroy();
wl_listener destroyListener; CSecurityContextSandboxedClientDestroyWrapper destroyListener;
private: private:
CSecurityContextSandboxedClient(int clientFD_); CSecurityContextSandboxedClient(int clientFD_);
@ -81,4 +87,4 @@ class CSecurityContextProtocol : public IWaylandProtocol {
namespace PROTO { namespace PROTO {
inline UP<CSecurityContextProtocol> securityContext; inline UP<CSecurityContextProtocol> securityContext;
}; };