Skip to content

Commit 19ce37f

Browse files
committed
feature: resolving snap desktop files using app armor as the primary source
1 parent b5486c1 commit 19ce37f

File tree

7 files changed

+52
-5
lines changed

7 files changed

+52
-5
lines changed

CMakeLists.txt

+11
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,17 @@ CMAKE_DEPENDENT_OPTION(
206206
MIR_SIGBUS_HANDLER_ENVIRONMENT_BROKEN "Expect WLCS BadBuffer tests to fail" OFF
207207
"MIR_RUN_WLCS_TESTS" OFF
208208
)
209+
210+
pkg_check_modules(APPARMOR IMPORTED_TARGET libapparmor)
211+
212+
CMAKE_DEPENDENT_OPTION(
213+
MIR_USE_APPARMOR "Whether or not Mir should build with support for AppArmor" ON
214+
"APPARMOR_FOUND" OFF
215+
)
216+
if (MIR_USE_APPARMOR)
217+
add_compile_definitions(MIR_USE_APPARMOR)
218+
endif()
219+
209220
SET(MIR_EXCLUDE_TESTS "" CACHE STRING "Semicolon-separated list of tests to exclude (wildcards accepted)")
210221

211222

debian/control

+2-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ Build-Depends: cmake,
5555
libnvidia-egl-wayland-dev,
5656
eglexternalplatform-dev,
5757
systemtap-sdt-dev,
58-
wlcs
58+
wlcs,
59+
libapparmor-dev
5960
Standards-Version: 4.6.1
6061
Homepage: https://mir-server.io/
6162
Vcs-Browser: https://github.com/MirServer/mir/

snap/snapcraft.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ parts:
5252
- nettle-dev
5353
- python3-pil
5454
- systemtap-sdt-dev
55+
- libapparmor-dev
5556
stage-packages:
5657
- libboost-filesystem1.83.0
5758
- libboost-iostreams1.83.0
@@ -98,3 +99,4 @@ parts:
9899
- libxml2
99100
- libxrender1
100101
- libyaml-cpp0.8
102+
- libapparmor1

spread/build/alpine/task.yaml

+2-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ execute: |
3131
py3-pillow \
3232
umockdev-dev \
3333
wayland-dev \
34-
yaml-cpp-dev
34+
yaml-cpp-dev \
35+
libapparmor-dev
3536
3637
BUILD_DIR=$PWD/../build
3738
cmake \

src/server/CMakeLists.txt

+4
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,10 @@ target_link_libraries(mirserver
149149
atomic
150150
)
151151

152+
if (MIR_USE_APPARMOR)
153+
target_link_libraries(mirserver PUBLIC PkgConfig::APPARMOR)
154+
endif()
155+
152156
set(MIRSERVER_INCLUDE_DIRS ${UUID_INCLUDE_DIRS} PARENT_SCOPE)
153157

154158
install(TARGETS mirserver

src/server/frontend_wayland/desktop_file_manager.cpp

+30-2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@
2222
#include <fstream>
2323
#include <filesystem>
2424

25+
#ifdef MIR_USE_APPARMOR
26+
#include <sys/apparmor.h>
27+
#endif
28+
2529
namespace mf = mir::frontend;
2630

2731
namespace
@@ -89,9 +93,10 @@ std::string mf::DesktopFileManager::resolve_app_id(const scene::Surface* surface
8993

9094
auto session = surface->session().lock();
9195
auto pid = session->process_id();
96+
auto socket_fd = session->socket_fd();
9297

9398
// Fourth, check if the window belongs to snap
94-
found = resolve_if_snap(pid);
99+
found = resolve_if_snap(pid, socket_fd);
95100
if (found)
96101
return found->id;
97102

@@ -157,8 +162,31 @@ std::string mf::DesktopFileManager::parse_snap_security_profile_to_desktop_id(st
157162
return sandboxed_app_id + DESKTOP_FILE_POSTFIX;
158163
}
159164

160-
std::shared_ptr<mf::DesktopFile> mf::DesktopFileManager::resolve_if_snap(int pid)
165+
std::shared_ptr<mf::DesktopFile> mf::DesktopFileManager::resolve_if_snap(int pid, mir::Fd const& socket_fd)
161166
{
167+
#ifdef MIR_USE_APPARMOR
168+
// First, try to resolve the AppArmor profile
169+
char* label_cstr;
170+
char* mode_cstr;
171+
172+
if (aa_getpeercon(socket_fd, &label_cstr, &mode_cstr) >= 0)
173+
{
174+
std::string const label{label_cstr};
175+
free(label_cstr);
176+
// mode_cstr should NOT be freed, as it's from the same buffer as label_cstr
177+
178+
auto sandboxed_app_id = parse_snap_security_profile_to_desktop_id(label);
179+
if (!sandboxed_app_id.empty())
180+
{
181+
if (auto file = cache->lookup_by_app_id(sandboxed_app_id))
182+
return file;
183+
}
184+
}
185+
#else
186+
(void)socket_fd;
187+
#endif
188+
189+
// If that fails, try to read /proc/<PID>/attr/current
162190
std::string attr_file = "/proc/" + std::to_string(pid) + "/attr/current";
163191
if (!std::filesystem::exists(attr_file))
164192
return nullptr;

src/server/frontend_wayland/desktop_file_manager.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class DesktopFileManager
6464
std::shared_ptr<DesktopFileCache> cache;
6565
std::shared_ptr<DesktopFile> resolve_from_wayland_app_id(std::string& app_id);
6666
std::shared_ptr<DesktopFile> lookup_basename(std::string& name);
67-
std::shared_ptr<DesktopFile> resolve_if_snap(int pid);
67+
std::shared_ptr<DesktopFile> resolve_if_snap(int pid, mir::Fd const& socket_fd);
6868
std::shared_ptr<DesktopFile> resolve_if_flatpak(int pid);
6969
std::shared_ptr<DesktopFile> resolve_if_executable_matches(int pid);
7070
};

0 commit comments

Comments
 (0)