Skip to content

Commit

Permalink
feature: resolving snap desktop files using app armor as the primary …
Browse files Browse the repository at this point in the history
…source (#3426)

## What's new?
- AppArmor is now the primary source of snap desktop files in the
`DesktopFileManager`
  • Loading branch information
Saviq committed Jun 21, 2024
2 parents 720b13c + 19ce37f commit cd2a1db
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 5 deletions.
11 changes: 11 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,17 @@ CMAKE_DEPENDENT_OPTION(
MIR_SIGBUS_HANDLER_ENVIRONMENT_BROKEN "Expect WLCS BadBuffer tests to fail" OFF
"MIR_RUN_WLCS_TESTS" OFF
)

pkg_check_modules(APPARMOR IMPORTED_TARGET libapparmor)

CMAKE_DEPENDENT_OPTION(
MIR_USE_APPARMOR "Whether or not Mir should build with support for AppArmor" ON
"APPARMOR_FOUND" OFF
)
if (MIR_USE_APPARMOR)
add_compile_definitions(MIR_USE_APPARMOR)
endif()

SET(MIR_EXCLUDE_TESTS "" CACHE STRING "Semicolon-separated list of tests to exclude (wildcards accepted)")


Expand Down
3 changes: 2 additions & 1 deletion debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ Build-Depends: cmake,
libnvidia-egl-wayland-dev,
eglexternalplatform-dev,
systemtap-sdt-dev,
wlcs
wlcs,
libapparmor-dev
Standards-Version: 4.6.1
Homepage: https://mir-server.io/
Vcs-Browser: https://github.com/MirServer/mir/
Expand Down
2 changes: 2 additions & 0 deletions snap/snapcraft.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ parts:
- nettle-dev
- python3-pil
- systemtap-sdt-dev
- libapparmor-dev
stage-packages:
- libboost-filesystem1.83.0
- libboost-iostreams1.83.0
Expand Down Expand Up @@ -98,3 +99,4 @@ parts:
- libxml2
- libxrender1
- libyaml-cpp0.8
- libapparmor1
3 changes: 2 additions & 1 deletion spread/build/alpine/task.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ execute: |
py3-pillow \
umockdev-dev \
wayland-dev \
yaml-cpp-dev
yaml-cpp-dev \
libapparmor-dev
BUILD_DIR=$PWD/../build
cmake \
Expand Down
4 changes: 4 additions & 0 deletions src/server/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,10 @@ target_link_libraries(mirserver
atomic
)

if (MIR_USE_APPARMOR)
target_link_libraries(mirserver PUBLIC PkgConfig::APPARMOR)
endif()

set(MIRSERVER_INCLUDE_DIRS ${UUID_INCLUDE_DIRS} PARENT_SCOPE)

install(TARGETS mirserver
Expand Down
32 changes: 30 additions & 2 deletions src/server/frontend_wayland/desktop_file_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
#include <fstream>
#include <filesystem>

#ifdef MIR_USE_APPARMOR
#include <sys/apparmor.h>
#endif

namespace mf = mir::frontend;

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

auto session = surface->session().lock();
auto pid = session->process_id();
auto socket_fd = session->socket_fd();

// Fourth, check if the window belongs to snap
found = resolve_if_snap(pid);
found = resolve_if_snap(pid, socket_fd);
if (found)
return found->id;

Expand Down Expand Up @@ -157,8 +162,31 @@ std::string mf::DesktopFileManager::parse_snap_security_profile_to_desktop_id(st
return sandboxed_app_id + DESKTOP_FILE_POSTFIX;
}

std::shared_ptr<mf::DesktopFile> mf::DesktopFileManager::resolve_if_snap(int pid)
std::shared_ptr<mf::DesktopFile> mf::DesktopFileManager::resolve_if_snap(int pid, mir::Fd const& socket_fd)
{
#ifdef MIR_USE_APPARMOR
// First, try to resolve the AppArmor profile
char* label_cstr;
char* mode_cstr;

if (aa_getpeercon(socket_fd, &label_cstr, &mode_cstr) >= 0)
{
std::string const label{label_cstr};
free(label_cstr);
// mode_cstr should NOT be freed, as it's from the same buffer as label_cstr

auto sandboxed_app_id = parse_snap_security_profile_to_desktop_id(label);
if (!sandboxed_app_id.empty())
{
if (auto file = cache->lookup_by_app_id(sandboxed_app_id))
return file;
}
}
#else
(void)socket_fd;
#endif

// If that fails, try to read /proc/<PID>/attr/current
std::string attr_file = "/proc/" + std::to_string(pid) + "/attr/current";
if (!std::filesystem::exists(attr_file))
return nullptr;
Expand Down
2 changes: 1 addition & 1 deletion src/server/frontend_wayland/desktop_file_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class DesktopFileManager
std::shared_ptr<DesktopFileCache> cache;
std::shared_ptr<DesktopFile> resolve_from_wayland_app_id(std::string& app_id);
std::shared_ptr<DesktopFile> lookup_basename(std::string& name);
std::shared_ptr<DesktopFile> resolve_if_snap(int pid);
std::shared_ptr<DesktopFile> resolve_if_snap(int pid, mir::Fd const& socket_fd);
std::shared_ptr<DesktopFile> resolve_if_flatpak(int pid);
std::shared_ptr<DesktopFile> resolve_if_executable_matches(int pid);
};
Expand Down

0 comments on commit cd2a1db

Please sign in to comment.