Skip to content

Commit ef0a753

Browse files
committed
feat: Implement loading of extensions from config files....
添加了严格沙箱模式
1 parent c40805b commit ef0a753

4 files changed

Lines changed: 165 additions & 22 deletions

File tree

apps/ll-cli/src/main.cpp

Lines changed: 133 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,11 @@ static constexpr const char kConfigUsageLines[] =
665665
"PATH [--mode ro|rw] [--persist]\n"
666666
" ll-cli config rm-fs [--global | <appid> | --base <baseid>] (--target PATH | "
667667
"--index N)\n"
668+
" ll-cli config add-fs-allow [--global | <appid> | --base <baseid>] --host PATH --target "
669+
"PATH [--mode ro|rw] [--persist]\n"
670+
" ll-cli config rm-fs-allow [--global | <appid> | --base <baseid>] (--target PATH | "
671+
"--index N)\n"
672+
" ll-cli config clear-fs-allow [--global | <appid> | --base <baseid>]\n"
668673
" ll-cli config set-command [--global | <appid> | --base <baseid>] <cmd> [--entrypoint P] "
669674
"[--cwd D] [--args-prefix \"...\"] [--args-suffix \"...\"] [KEY=VAL ...]\n"
670675
" ll-cli config unset-command [--global | <appid> | --base <baseid>] <cmd>\n";
@@ -895,9 +900,9 @@ struct FsArg {
895900
bool persist = false;
896901
};
897902

898-
static void jsonAddFs(json &root, const FsArg &fs)
903+
static void jsonAddFsTo(json &root, const FsArg &fs, const char *field)
899904
{
900-
auto &arr = root["filesystem"];
905+
auto &arr = root[field];
901906
if (!arr.is_array()) {
902907
arr = json::array();
903908
}
@@ -919,12 +924,22 @@ static void jsonAddFs(json &root, const FsArg &fs)
919924
arr.push_back(std::move(o));
920925
}
921926

922-
static bool jsonRmFsByTarget(json &root, const std::string &target)
927+
static void jsonAddFs(json &root, const FsArg &fs)
928+
{
929+
jsonAddFsTo(root, fs, "filesystem");
930+
}
931+
932+
static void jsonAddFsAllow(json &root, const FsArg &fs)
933+
{
934+
jsonAddFsTo(root, fs, "filesystem_allow_only");
935+
}
936+
937+
static bool jsonRmFsByTargetFrom(json &root, const std::string &target, const char *field)
923938
{
924-
if (!root.contains("filesystem") || !root["filesystem"].is_array()) {
939+
if (!root.contains(field) || !root[field].is_array()) {
925940
return false;
926941
}
927-
auto &arr = root["filesystem"];
942+
auto &arr = root[field];
928943
auto old = arr.size();
929944
arr.erase(std::remove_if(arr.begin(), arr.end(), [&](const json &e) {
930945
return e.is_object() && e.value("target", "") == target;
@@ -933,19 +948,44 @@ static bool jsonRmFsByTarget(json &root, const std::string &target)
933948
return arr.size() != old;
934949
}
935950

936-
static bool jsonRmFsByIndex(json &root, size_t idx)
951+
static bool jsonRmFsByTarget(json &root, const std::string &target)
937952
{
938-
if (!root.contains("filesystem") || !root["filesystem"].is_array()) {
953+
return jsonRmFsByTargetFrom(root, target, "filesystem");
954+
}
955+
956+
static bool jsonRmFsAllowByTarget(json &root, const std::string &target)
957+
{
958+
return jsonRmFsByTargetFrom(root, target, "filesystem_allow_only");
959+
}
960+
961+
static bool jsonRmFsByIndexFrom(json &root, size_t idx, const char *field)
962+
{
963+
if (!root.contains(field) || !root[field].is_array()) {
939964
return false;
940965
}
941-
auto &arr = root["filesystem"];
966+
auto &arr = root[field];
942967
if (idx >= arr.size()) {
943968
return false;
944969
}
945970
arr.erase(arr.begin() + idx);
946971
return true;
947972
}
948973

974+
static bool jsonRmFsByIndex(json &root, size_t idx)
975+
{
976+
return jsonRmFsByIndexFrom(root, idx, "filesystem");
977+
}
978+
979+
static bool jsonRmFsAllowByIndex(json &root, size_t idx)
980+
{
981+
return jsonRmFsByIndexFrom(root, idx, "filesystem_allow_only");
982+
}
983+
984+
static void jsonClearFsAllow(json &root)
985+
{
986+
root["filesystem_allow_only"] = json::array();
987+
}
988+
949989
struct CmdSetArg {
950990
std::string cmd;
951991
std::optional<std::string> entrypoint;
@@ -1264,6 +1304,40 @@ int runCliApplication(int argc, char **mainArgv)
12641304
}
12651305
return 0;
12661306
}
1307+
if (sub == "add-fs-allow") {
1308+
auto [scope, appId, baseId, i] = parseScope(3);
1309+
FsArg fs;
1310+
fs.mode = "ro";
1311+
fs.persist = false;
1312+
for (; i < argc; ++i) {
1313+
std::string a = mainArgv[i];
1314+
if (a == "--persist") {
1315+
fs.persist = true;
1316+
} else if (a == "--host" && i + 1 < argc) {
1317+
fs.host = mainArgv[++i];
1318+
} else if (a == "--target" && i + 1 < argc) {
1319+
fs.target = mainArgv[++i];
1320+
} else if (a == "--mode" && i + 1 < argc) {
1321+
fs.mode = mainArgv[++i];
1322+
} else {
1323+
fprintf(stderr, "unknown arg: %s\n", a.c_str());
1324+
return 1;
1325+
}
1326+
}
1327+
if (fs.host.empty() || fs.target.empty()) {
1328+
printConfigUsage();
1329+
return 1;
1330+
}
1331+
auto j = openConfig(scope, appId, baseId);
1332+
if (!j) {
1333+
return 1;
1334+
}
1335+
jsonAddFsAllow(*j, fs);
1336+
if (!saveConfig(scope, appId, baseId, *j)) {
1337+
return 1;
1338+
}
1339+
return 0;
1340+
}
12671341
if (sub == "rm-fs") {
12681342
auto [scope, appId, baseId, i] = parseScope(3);
12691343
std::optional<std::string> target;
@@ -1303,6 +1377,57 @@ int runCliApplication(int argc, char **mainArgv)
13031377
}
13041378
return 0;
13051379
}
1380+
if (sub == "rm-fs-allow") {
1381+
auto [scope, appId, baseId, i] = parseScope(3);
1382+
std::optional<std::string> target;
1383+
std::optional<size_t> index;
1384+
for (; i < argc; ++i) {
1385+
std::string a = mainArgv[i];
1386+
if (a == "--target" && i + 1 < argc) {
1387+
target = mainArgv[++i];
1388+
} else if (a == "--index" && i + 1 < argc) {
1389+
index = static_cast<size_t>(std::stoul(mainArgv[++i]));
1390+
} else {
1391+
fprintf(stderr, "unknown arg: %s\n", a.c_str());
1392+
return 1;
1393+
}
1394+
}
1395+
if (!target && !index) {
1396+
printConfigUsage();
1397+
return 1;
1398+
}
1399+
auto j = openConfig(scope, appId, baseId);
1400+
if (!j) {
1401+
return 1;
1402+
}
1403+
bool ok = false;
1404+
if (target) {
1405+
ok = jsonRmFsAllowByTarget(*j, *target);
1406+
}
1407+
if (!ok && index) {
1408+
ok = jsonRmFsAllowByIndex(*j, *index);
1409+
}
1410+
if (!ok) {
1411+
fprintf(stderr, "no filesystem_allow entry removed\n");
1412+
return 1;
1413+
}
1414+
if (!saveConfig(scope, appId, baseId, *j)) {
1415+
return 1;
1416+
}
1417+
return 0;
1418+
}
1419+
if (sub == "clear-fs-allow") {
1420+
auto [scope, appId, baseId, i] = parseScope(3);
1421+
auto j = openConfig(scope, appId, baseId);
1422+
if (!j) {
1423+
return 1;
1424+
}
1425+
jsonClearFsAllow(*j);
1426+
if (!saveConfig(scope, appId, baseId, *j)) {
1427+
return 1;
1428+
}
1429+
return 0;
1430+
}
13061431
if (sub == "set-command") {
13071432
auto [scope, appId, baseId, i] = parseScope(3);
13081433
if (i >= argc) {

libs/linglong/src/linglong/cli/cli.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -790,6 +790,10 @@ int Cli::run(const RunOptions &options)
790790

791791
cfgBuilder.bindHome(homeEnv).enablePrivateDir();
792792

793+
if (restrictFilesystem) {
794+
cfgBuilder.disableHostHomeBind();
795+
}
796+
793797
if (restrictFilesystem) {
794798
cfgBuilder.mapPrivate(std::string{ homeEnv }, true);
795799
} else {

libs/oci-cfg-generators/src/linglong/oci-cfg-generators/container_cfg_builder.cpp

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -769,11 +769,12 @@ bool ContainerCfgBuilder::buildMountHome() noexcept
769769
.type = "tmpfs" });
770770

771771
auto containerHome = homePath->string();
772-
773-
homeMount->emplace_back(Mount{ .destination = containerHome,
774-
.options = string_list{ "rbind" },
775-
.source = *homePath,
776-
.type = "bind" });
772+
if (!skipHostHome) {
773+
homeMount->emplace_back(Mount{ .destination = containerHome,
774+
.options = string_list{ "rbind" },
775+
.source = *homePath,
776+
.type = "bind" });
777+
}
777778
environment["HOME"] = containerHome;
778779

779780
auto mountDir = [this](const std::filesystem::path &hostDir, const std::string &containerDir) {
@@ -803,7 +804,7 @@ bool ContainerCfgBuilder::buildMountHome() noexcept
803804
value ? std::filesystem::path{ value } : *homePath / ".local" / "share";
804805
std::string containerDataHome = containerHome + "/.local/share";
805806
if (XDG_DATA_HOME != containerDataHome) {
806-
if (!mountDir(XDG_DATA_HOME, containerDataHome)) {
807+
if (!skipHostHome && !mountDir(XDG_DATA_HOME, containerDataHome)) {
807808
error_.reason = XDG_DATA_HOME.string() + " can't be mount";
808809
error_.code = BUILD_MOUNT_HOME_ERROR;
809810
return false;
@@ -834,7 +835,7 @@ bool ContainerCfgBuilder::buildMountHome() noexcept
834835
}
835836
std::string containerConfigHome = containerHome + "/.config";
836837
if (XDGConfigHome != containerConfigHome) {
837-
if (!mountDir(XDGConfigHome, containerConfigHome)) {
838+
if (!skipHostHome && !mountDir(XDGConfigHome, containerConfigHome)) {
838839
error_.reason = XDGConfigHome.string() + " can't be mount";
839840
error_.code = BUILD_MOUNT_HOME_ERROR;
840841
return false;
@@ -852,7 +853,7 @@ bool ContainerCfgBuilder::buildMountHome() noexcept
852853
}
853854
std::string containerCacheHome = containerHome + "/.cache";
854855
if (XDGCacheHome != containerCacheHome) {
855-
if (!mountDir(XDGCacheHome, containerCacheHome)) {
856+
if (!skipHostHome && !mountDir(XDGCacheHome, containerCacheHome)) {
856857
error_.reason = XDGCacheHome.string() + " can't be mount";
857858
error_.code = BUILD_MOUNT_HOME_ERROR;
858859
return false;
@@ -869,7 +870,7 @@ bool ContainerCfgBuilder::buildMountHome() noexcept
869870
}
870871
std::string containerStateHome = containerHome + "/.local/state";
871872
if (XDG_STATE_HOME != containerStateHome) {
872-
if (!mountDir(XDG_STATE_HOME, containerStateHome)) {
873+
if (!skipHostHome && !mountDir(XDG_STATE_HOME, containerStateHome)) {
873874
error_.reason = XDG_STATE_HOME.string() + " can't be mount";
874875
error_.code = BUILD_MOUNT_HOME_ERROR;
875876
return false;
@@ -881,10 +882,12 @@ bool ContainerCfgBuilder::buildMountHome() noexcept
881882
auto hostSystemdUserDir = XDG_CONFIG_HOME / "systemd" / "user";
882883
if ((XDG_CONFIG_HOME != containerConfigHome)
883884
&& std::filesystem::exists(hostSystemdUserDir, ec)) {
884-
homeMount->emplace_back(Mount{ .destination = containerConfigHome + "/systemd/user",
885+
if (!skipHostHome) {
886+
homeMount->emplace_back(Mount{ .destination = containerConfigHome + "/systemd/user",
885887
.options = string_list{ "rbind" },
886888
.source = hostSystemdUserDir,
887889
.type = "bind" });
890+
}
888891
}
889892

890893
// FIXME: Many applications get configurations from dconf, so we expose dconf to all
@@ -893,15 +896,18 @@ bool ContainerCfgBuilder::buildMountHome() noexcept
893896
auto hostUserDconfPath = XDG_CONFIG_HOME / "dconf";
894897
if ((XDG_CONFIG_HOME != containerConfigHome)
895898
&& std::filesystem::exists(hostUserDconfPath, ec)) {
896-
homeMount->emplace_back(Mount{ .destination = containerConfigHome + "/dconf",
899+
if (!skipHostHome) {
900+
homeMount->emplace_back(Mount{ .destination = containerConfigHome + "/dconf",
897901
.options = string_list{ "rbind" },
898902
.source = hostUserDconfPath,
899903
.type = "bind" });
904+
}
900905
}
901906

902907
// for dde application theme
903908
auto hostDDEApiPath = XDG_CACHE_HOME / "deepin" / "dde-api";
904-
if ((XDG_CACHE_HOME != containerCacheHome) && std::filesystem::exists(hostDDEApiPath, ec)) {
909+
if (!skipHostHome && (XDG_CACHE_HOME != containerCacheHome)
910+
&& std::filesystem::exists(hostDDEApiPath, ec)) {
905911
homeMount->emplace_back(Mount{ .destination = containerCacheHome + "/deepin/dde-api",
906912
.options = string_list{ "rbind" },
907913
.source = hostDDEApiPath,
@@ -910,15 +916,17 @@ bool ContainerCfgBuilder::buildMountHome() noexcept
910916

911917
// for xdg-user-dirs
912918
auto XDGUserDirs = XDG_CONFIG_HOME / "user-dirs.dirs";
913-
if ((XDG_CONFIG_HOME != containerConfigHome) && std::filesystem::exists(XDGUserDirs, ec)) {
919+
if (!skipHostHome && (XDG_CONFIG_HOME != containerConfigHome)
920+
&& std::filesystem::exists(XDGUserDirs, ec)) {
914921
homeMount->push_back(Mount{ .destination = containerConfigHome + "/user-dirs.dirs",
915922
.options = string_list{ "rbind" },
916923
.source = XDGUserDirs,
917924
.type = "bind" });
918925
}
919926

920927
auto XDGUserLocale = XDG_CONFIG_HOME / "user-dirs.locale";
921-
if ((XDG_CONFIG_HOME != containerConfigHome) && std::filesystem::exists(XDGUserLocale, ec)) {
928+
if (!skipHostHome && (XDG_CONFIG_HOME != containerConfigHome)
929+
&& std::filesystem::exists(XDGUserLocale, ec)) {
922930
homeMount->push_back(Mount{ .destination = containerConfigHome + "/user-dirs.locale",
923931
.options = string_list{ "rbind" },
924932
.source = XDGUserLocale,

libs/oci-cfg-generators/src/linglong/oci-cfg-generators/container_cfg_builder.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,11 @@ class ContainerCfgBuilder
142142
ContainerCfgBuilder &bindHostRoot() noexcept;
143143
ContainerCfgBuilder &bindHostStatics() noexcept;
144144
ContainerCfgBuilder &bindHome(std::filesystem::path hostHome) noexcept;
145+
ContainerCfgBuilder &disableHostHomeBind() noexcept
146+
{
147+
skipHostHome = true;
148+
return *this;
149+
}
145150

146151
ContainerCfgBuilder &bindXOrgSocket(const std::filesystem::path &socket) noexcept;
147152
ContainerCfgBuilder &bindXAuthFile(const std::filesystem::path &authFile) noexcept;
@@ -299,6 +304,7 @@ class ContainerCfgBuilder
299304
// home dir
300305
std::optional<std::filesystem::path> homePath;
301306
std::optional<std::vector<ocppi::runtime::config::types::Mount>> homeMount;
307+
bool skipHostHome{ false };
302308

303309
// private dir
304310
std::filesystem::path privatePath;

0 commit comments

Comments
 (0)