Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 1.7.5 #39

Merged
merged 13 commits into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .github/workflows/backup-to-gitlab.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: backup to gitlab
on: [push]

concurrency:
group: ${{ github.workflow }}
cancel-in-progress: true

jobs:
backup-to-gitlabwh:
uses: deepin-community/.github/.github/workflows/backup-to-gitlabwh.yml@release
secrets:
BRIDGETOKEN: ${{ secrets.BRIDGETOKEN }}
16 changes: 0 additions & 16 deletions .github/workflows/call-auto-tag.yml

This file was deleted.

14 changes: 14 additions & 0 deletions .github/workflows/call-build-tag.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: tag build
on:
push:
tags: "*"

concurrency:
group: ${{ github.workflow }}
cancel-in-progress: true

jobs:
build:
uses: deepin-community/.github/.github/workflows/build-tag.yml@master
secrets:
BridgeToken: ${{ secrets.BridgeToken }}
9 changes: 9 additions & 0 deletions .github/workflows/call-chatOps.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name: chatOps
on:
issue_comment:
types: [created]

jobs:
chatopt:
uses: deepin-community/.github/.github/workflows/chatOps.yml@master
secrets: inherit
11 changes: 0 additions & 11 deletions .github/workflows/call-commitlint.yml

This file was deleted.

16 changes: 0 additions & 16 deletions .github/workflows/call-license-check.yml

This file was deleted.

26 changes: 0 additions & 26 deletions .github/workflows/cppcheck.yml

This file was deleted.

17 changes: 15 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ set(UAB_SPECIAL_INSTALL
OFF
CACHE BOOL "enable special installation of UAB")

if (${UAB_SPECIAL_INSTALL})
add_definitions(-DUAB_SPECIAL_INSTALL)
if(${UAB_SPECIAL_INSTALL})
add_definitions(-DUAB_SPECIAL_INSTALL)
endif()

set(ENABLE_UAB
Expand Down Expand Up @@ -187,6 +187,19 @@ add_definitions("-DQT_NO_KEYWORDS")
# NOTE(black_desk): Enable Qt logging with context.
add_definitions("-DQT_MESSAGELOGCONTEXT")

# FIXME: can not start container since the kernel does not support the
# CLONE_NEWUSER feature in the chroot environment, reference:
# https://man7.org/linux/man-pages/man2/unshare.2.html. so we skip font cache
# generator by LINGLONG_FONT_CACHE_GENERATOR, it can be removed when the above
# problem is solved.
set(ENABLE_FONT_CACHE_GENERATOR
OFF
CACHE BOOL "enable font cache generator")

if(ENABLE_FONT_CACHE_GENERATOR)
add_definitions(-DLINGLONG_FONT_CACHE_GENERATOR)
endif()

# We need to support both Qt5 and Qt6, and according to the Qt documentation, we
# should be using versioned targets and functions. These varible must be set
# before find_package()
Expand Down
2 changes: 2 additions & 0 deletions apps/ll-box/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ if(${STATIC_BOX})
endif()

pkg_search_module(SECCOMP REQUIRED IMPORTED_TARGET libseccomp)
pkg_search_module(CAP REQUIRED IMPORTED_TARGET libcap)

pfl_add_executable(
SOURCES
Expand Down Expand Up @@ -51,6 +52,7 @@ pfl_add_executable(
nlohmann_json::nlohmann_json
linglong::ocppi
PkgConfig::SECCOMP
PkgConfig::CAP
COMPILE_OPTIONS
PRIVATE
-DJSON_USE_IMPLICIT_CONVERSIONS=0)
Expand Down
98 changes: 91 additions & 7 deletions apps/ll-box/src/container/container.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,11 @@
#include "container/helper.h"
#include "container/mount/filesystem_driver.h"
#include "container/mount/host_mount.h"
#include "container/seccomp.h"
#include "util/debug/debug.h"
#include "util/filesystem.h"
#include "util/logger.h"
#include "util/platform.h"
#include "util/semaphore.h"

#include <sys/capability.h>
#include <sys/epoll.h>
#include <sys/mount.h>
#include <sys/prctl.h>
Expand Down Expand Up @@ -217,6 +215,82 @@ static bool parse_wstatus(const int &wstatus, std::string &info)
}
}

int setCapabilities(const Capabilities &capabilities)
{
auto get_cap_list = [](const util::str_vec &cap_str_vec) -> std::vector<cap_value_t> {
std::vector<cap_value_t> cap_list;
for (const auto &cap : cap_str_vec) {
if (auto it = capsMap.find(cap); it != capsMap.end()) {
cap_list.push_back(it->second);
}
}

return cap_list;
};

std::unique_ptr<_cap_struct, decltype(&cap_free)> caps(cap_get_proc(), cap_free);
if (caps == nullptr) {
logErr() << "call cap_get_proc failed" << util::RetErrString(0);
return 1;
}

if (!capabilities.effective.empty()
&& cap_set_flag(caps.get(),
CAP_EFFECTIVE,
capabilities.effective.size(),
get_cap_list(capabilities.effective).data(),
CAP_SET)
== -1) {
logErr() << "cap_set_flag CAP_EFFECTIVE" << util::RetErrString(-1);
return -1;
}

if (!capabilities.permitted.empty()
&& cap_set_flag(caps.get(),
CAP_PERMITTED,
capabilities.permitted.size(),
get_cap_list(capabilities.permitted).data(),
CAP_SET)
== -1) {
logErr() << "cap_set_flag CAP_PERMITTED" << util::RetErrString(-1);
return -1;
}

if (!capabilities.inheritable.empty()
&& cap_set_flag(caps.get(),
CAP_INHERITABLE,
capabilities.inheritable.size(),
get_cap_list(capabilities.inheritable).data(),
CAP_SET)
== -1) {
logErr() << "cap_set_flag CAP_INHERITABLE" << util::RetErrString(-1);
return -1;
}

// apply the modified capabilities to the process
if (cap_set_proc(caps.get()) == -1) {
logErr() << "cap_set_proc" << util::RetErrString(-1);
return -1;
}

for (auto cap : get_cap_list(capabilities.ambient)) {
if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, cap, 0, 0) == -1) {
logErr() << "prctl PR_CAP_AMBIENT PR_CAP_AMBIENT_RAISE" << cap
<< util::RetErrString(-1);
return -1;
}
}

for (auto cap : get_cap_list(capabilities.bounding)) {
if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_LOWER, cap, 0, 0) == -1) {
logErr() << "prctl PR_CAP_AMBIENT PR_CAP_AMBIENT_LOWER" << util::RetErrString(-1);
return -1;
}
}

return 0;
}

struct ContainerPrivate
{
ContainerPrivate(Runtime r, const std::string &bundle, Container * /*unused*/)
Expand Down Expand Up @@ -583,12 +657,22 @@ int NonePrivilegeProc(void *arg)
idMap.size = 1;
linux.gidMappings.push_back(idMap);

if (auto ret = ConfigUserNamespace(linux, 0); ret != 0) {
return ret;
int ret{ -1 };
if (containerPrivate.runtime.process.capabilities) {
ret = setCapabilities(containerPrivate.runtime.process.capabilities.value());
if (ret == -1) {
logErr() << "setCapabilities failed";
return -1;
}
}

auto ret = mount("proc", "/proc", "proc", 0, nullptr);
if (0 != ret) {
if (ret = ConfigUserNamespace(linux, 0); ret != 0) {
logErr() << "ConfigUserNamespace failed";
return -1;
}

ret = mount("proc", "/proc", "proc", 0, nullptr);
if (ret == -1) {
logErr() << "mount proc failed" << util::RetErrString(ret);
return -1;
}
Expand Down
46 changes: 46 additions & 0 deletions apps/ll-box/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,52 @@ Overload(Ts...) -> Overload<Ts...>;

int main(int argc, char **argv)
{
// detecting some kernel features at runtime to reporting errors friendly
std::error_code ec;
std::filesystem::path feature{ "/proc/sys/kernel/unprivileged_userns_clone" };

auto check = [](const std::filesystem::path &setting, int expected) {
// We assume that the fact that a file does not exist or that an error occurs during the
// detection process does not mean that the feature is disabled.
std::error_code ec;
if (!std::filesystem::exists(setting, ec)) {
return true;
}

std::ifstream stream{ setting };
if (!stream.is_open()) {
return true;
}

std::string content;
std::getline(stream, content);

try {
return std::stoi(content) == expected;
} catch (std::exception &e) {
logWan() << "ignore exception" << e.what() << "and continue"; // NOLINT
return true;
}
};

// for debian:
// https://salsa.debian.org/kernel-team/linux/-/blob/debian/latest/debian/patches/debian/add-sysctl-to-disallow-unprivileged-CLONE_NEWUSER-by-default.patch
if (!check("/proc/sys/kernel/unprivileged_userns_clone", 1)) {
logErr() << "unprivileged_userns_clone is not enabled";
return EPERM;
}

// for ubuntu:
// https://gitlab.com/apparmor/apparmor/-/wikis/unprivileged_userns_restriction#disabling-unprivileged-user-namespaces
if (!check("/proc/sys/kernel/apparmor_restrict_unprivileged_unconfined", 0)) {
logErr() << "apparmor_restrict_unprivileged_unconfined is not disabled";
return EPERM;
}
if (!check("/proc/sys/kernel/apparmor_restrict_unprivileged_userns", 0)) {
logErr() << "apparmor_restrict_unprivileged_userns is not disabled";
return EPERM;
}

if (argc == 1) {
logErr() << "please specify a command";
return -1;
Expand Down
31 changes: 31 additions & 0 deletions apps/ll-box/src/util/debug/debug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

#include "util/logger.h"

#include <sys/capability.h>

#include <dirent.h>
#include <grp.h>
#include <pwd.h>
Expand All @@ -19,7 +21,36 @@
#define DUMP_DBG(func, line) /*NOLINT*/ \
(linglong::util::Logger(linglong::util::Logger::Debug, func, line))

void DumpCap()

Check warning on line 24 in apps/ll-box/src/util/debug/debug.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

The function 'DumpCap' is never used.
{
cap_flag_value_t cap_value;
cap_value_t cap;

logDbg() << "start -----------";

// Get the current process capabilities
std::unique_ptr<_cap_struct, decltype(cap_free) *> caps(cap_get_proc(), cap_free);

// Iterate through all capabilities
for (cap = 0; cap <= CAP_LAST_CAP; cap++) {
if (cap_get_flag(caps.get(), cap, CAP_EFFECTIVE, &cap_value) == -1) {
logDbg() << "cap_get_flag failed";
continue;
}

const char *cap_name = cap_to_name(cap);
if (cap_name == nullptr) {
logDbg() << "Unknown capability: " << cap;
continue;
}

logDbg() << cap_name << ": " << (cap_value == CAP_SET ? "yes" : "no");
}

logDbg() << "end -----------";
}

void DumpIDMap()

Check warning on line 53 in apps/ll-box/src/util/debug/debug.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

The function 'DumpIDMap' is never used.
{
logDbg() << "DumpIDMap Start -----------";
std::ifstream uidMap("/proc/self/uid_map");
Expand Down
2 changes: 2 additions & 0 deletions apps/ll-box/src/util/debug/debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ namespace linglong {

#define DUMP_FILE_INFO(path) DumpFileInfo1(path, __FUNCTION__, __LINE__)

void DumpCap();

void DumpIDMap();

void DumpUidGidGroup();
Expand Down
Loading
Loading