Skip to content

Commit

Permalink
Make sure to call connection_is_allowed on xwayland sessions
Browse files Browse the repository at this point in the history
As xwayland/x11 has no way of telling us gid uid we assume it's
the same as mir itself.
  • Loading branch information
mariogrip committed Feb 23, 2023
1 parent a35b397 commit fb0a05e
Show file tree
Hide file tree
Showing 8 changed files with 44 additions and 4 deletions.
1 change: 1 addition & 0 deletions src/server/frontend_wayland/wayland_connector.cpp
Expand Up @@ -298,6 +298,7 @@ mf::WaylandConnector::WaylandConnector(
display.get(),
executor,
shell,
session_authorizer,
main_clipboard,
primary_selection_clipboard,
text_input_hub,
Expand Down
1 change: 1 addition & 0 deletions src/server/frontend_wayland/wayland_connector.h
Expand Up @@ -82,6 +82,7 @@ class WaylandExtensions
wl_display* display;
std::shared_ptr<Executor> wayland_executor;
std::shared_ptr<shell::Shell> shell;
std::shared_ptr<SessionAuthorizer> session_authorizer;
std::shared_ptr<scene::Clipboard> main_clipboard;
std::shared_ptr<scene::Clipboard> primary_selection_clipboard;
std::shared_ptr<scene::TextInputHub> text_input_hub;
Expand Down
Expand Up @@ -181,6 +181,7 @@ ExtensionBuilder const xwayland_builder {
return std::make_shared<mf::XWaylandWMShell>(
ctx.wayland_executor,
ctx.shell,
ctx.session_authorizer,
ctx.main_clipboard,
*ctx.seat,
ctx.surface_stack);
Expand Down
22 changes: 20 additions & 2 deletions src/server/frontend_xwayland/xwayland_client_manager.cpp
Expand Up @@ -20,6 +20,10 @@
#include "mir/shell/shell.h"
#include "mir/scene/session.h"
#include "mir/log.h"
#include "mir/frontend/session_authorizer.h"
#include "mir/frontend/session_credentials.h"

#include <sys/stat.h>

namespace mf = mir::frontend;
namespace msh = mir::shell;
Expand All @@ -43,8 +47,10 @@ auto mf::XWaylandClientManager::Session::session() const -> std::shared_ptr<scen
return _session;
}

mf::XWaylandClientManager::XWaylandClientManager(std::shared_ptr<shell::Shell> const& shell)
: shell{shell}
mf::XWaylandClientManager::XWaylandClientManager(std::shared_ptr<shell::Shell> const& shell,
std::shared_ptr<SessionAuthorizer> const& session_authorizer)
: shell{shell},
session_authorizer{session_authorizer}
{
}

Expand Down Expand Up @@ -80,6 +86,18 @@ auto mf::XWaylandClientManager::session_for_client(pid_t client_pid) -> std::sha
}
else
{
struct stat proc_stat;
std::string proc = "/proc/";
proc += std::to_string(client_pid);
stat(proc.c_str(), &proc_stat);
auto const uid = proc_stat.st_uid;
auto const gid = proc_stat.st_gid;

if (!session_authorizer->connection_is_allowed({client_pid, uid, gid}))
{
log_error("X11 session not authorized for PID %d, rejecting!", client_pid);
return nullptr;
}
session = std::make_shared<Session>(this, client_pid);
sessions_by_pid[client_pid] = session;
if (verbose_xwayland_logging_enabled())
Expand Down
6 changes: 5 additions & 1 deletion src/server/frontend_xwayland/xwayland_client_manager.h
Expand Up @@ -35,6 +35,8 @@ class Session;
}
namespace frontend
{
class SessionAuthorizer;

/// Keeps track of which session is associated with which XWayland client PID
class XWaylandClientManager
{
Expand All @@ -55,7 +57,8 @@ class XWaylandClientManager
std::shared_ptr<scene::Session> const _session;
};

XWaylandClientManager(std::shared_ptr<shell::Shell> const& shell);
XWaylandClientManager(std::shared_ptr<shell::Shell> const& shell,
std::shared_ptr<SessionAuthorizer> const& session_authorizer);
~XWaylandClientManager();

auto session_for_client(pid_t client_pid) -> std::shared_ptr<Session>;
Expand All @@ -64,6 +67,7 @@ class XWaylandClientManager
void drop_expired(pid_t client_pid);

std::shared_ptr<shell::Shell> const shell;
std::shared_ptr<SessionAuthorizer> const session_authorizer;
std::mutex mutex;
std::unordered_map<pid_t, std::weak_ptr<Session>> sessions_by_pid;
};
Expand Down
11 changes: 11 additions & 0 deletions src/server/frontend_xwayland/xwayland_surface.cpp
Expand Up @@ -688,12 +688,17 @@ void mf::XWaylandSurface::attach_wl_surface(WlSurface* wl_surface)

std::shared_ptr<XWaylandClientManager::Session> local_client_session;
std::shared_ptr<ms::Session> session;
bool rejected = false;
reply_functions.push_back(connection->read_property(
window, connection->_NET_WM_PID,
XCBConnection::Handler<uint32_t>{
[&](uint32_t pid)
{
local_client_session = client_manager->session_for_client(pid);
if (!local_client_session) {
rejected = true;
return;
}
session = local_client_session->session();
},
[&](std::string const&)
Expand All @@ -709,6 +714,12 @@ void mf::XWaylandSurface::attach_wl_surface(WlSurface* wl_surface)
reply_function();
}

if (rejected) {
scene_surface_close_requested();
close();
return;
}

if (!session)
{
fatal_error("Property handlers did not set a valid session");
Expand Down
2 changes: 1 addition & 1 deletion src/server/frontend_xwayland/xwayland_wm.cpp
Expand Up @@ -148,7 +148,7 @@ mf::XWaylandWM::XWaylandWM(
clipboard_provider{std::make_unique<XWaylandClipboardProvider>(connection, dispatcher, wm_shell->clipboard)},
wm_window{create_wm_window(*connection)},
scene_observer{std::make_shared<XWaylandSceneObserver>(this)},
client_manager{std::make_shared<XWaylandClientManager>(wm_shell->shell)},
client_manager{std::make_shared<XWaylandClientManager>(wm_shell->shell, wm_shell->session_authorizer)},
assumed_surface_scale{assumed_surface_scale}
{
uint32_t const attrib_values[]{
Expand Down
4 changes: 4 additions & 0 deletions src/server/frontend_xwayland/xwayland_wm_shell.h
Expand Up @@ -39,18 +39,21 @@ class SurfaceStack;
class WlSeat;
class WlSurface;
class XWaylandSurface;
class SessionAuthorizer;

class XWaylandWMShell
{
public:
XWaylandWMShell(
std::shared_ptr<Executor> const& wayland_executor,
std::shared_ptr<shell::Shell> const& shell,
std::shared_ptr<SessionAuthorizer> const& session_authorizer,
std::shared_ptr<scene::Clipboard> const& clipboard,
WlSeat& seat,
std::shared_ptr<SurfaceStack> const& surface_stack)
: wayland_executor{wayland_executor},
shell{shell},
session_authorizer{session_authorizer},
clipboard{clipboard},
seat{seat},
surface_stack{surface_stack}
Expand All @@ -59,6 +62,7 @@ class XWaylandWMShell

std::shared_ptr<Executor> const wayland_executor;
std::shared_ptr<shell::Shell> const shell;
std::shared_ptr<SessionAuthorizer> const session_authorizer;
std::shared_ptr<scene::Clipboard> const clipboard;
WlSeat& seat;
std::shared_ptr<SurfaceStack> const surface_stack;
Expand Down

0 comments on commit fb0a05e

Please sign in to comment.