mirror of
https://gitee.com/openharmony/third_party_e2fsprogs
synced 2024-11-23 09:59:49 +00:00
bd33031fc2
Signed-off-by: fangzhiyi18 <fangzhiyi1@huawei.com>
405 lines
12 KiB
Diff
405 lines
12 KiB
Diff
diff --git a/contrib/android/dac_config.cpp b/contrib/android/dac_config.cpp
|
|
new file mode 100644
|
|
index 00000000..422e0d52
|
|
--- /dev/null
|
|
+++ b/contrib/android/dac_config.cpp
|
|
@@ -0,0 +1,246 @@
|
|
+/*
|
|
+ * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; version 2.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but WITHOUT
|
|
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License along with
|
|
+ * this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
|
|
+ * Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
+ */
|
|
+
|
|
+#define __cpluscplus
|
|
+#include "dac_config.h"
|
|
+
|
|
+#include <fstream>
|
|
+#include <iostream>
|
|
+#include <sstream>
|
|
+#include <string>
|
|
+#include <unordered_map>
|
|
+#include <vector>
|
|
+#include <linux/capability.h>
|
|
+#include <limits.h>
|
|
+
|
|
+using namespace std;
|
|
+
|
|
+namespace {
|
|
+struct DacConfig {
|
|
+ unsigned int uid;
|
|
+ unsigned int gid;
|
|
+ unsigned int mode;
|
|
+ uint64_t capabilities;
|
|
+ string path;
|
|
+
|
|
+ DacConfig() : uid(0), gid(0), mode(0), capabilities(0), path("") {}
|
|
+ DacConfig(unsigned int m, unsigned int u, unsigned int g, uint64_t c, string p) :
|
|
+ uid(u),
|
|
+ gid(g),
|
|
+ mode(m),
|
|
+ capabilities(c),
|
|
+ path(p) {}
|
|
+
|
|
+ void SetDefault(unsigned int m, unsigned int u, unsigned int g, uint64_t c, string p)
|
|
+ {
|
|
+ this->uid = u;
|
|
+ this->gid = g;
|
|
+ this->mode = m;
|
|
+ this->capabilities = c;
|
|
+ this->path = p;
|
|
+ }
|
|
+};
|
|
+
|
|
+unordered_map<string, DacConfig> g_configMap;
|
|
+
|
|
+static string Trim(const string& s)
|
|
+{
|
|
+ if (s.size() == 0) {
|
|
+ return s;
|
|
+ }
|
|
+
|
|
+ size_t start = 0;
|
|
+ size_t end = s.size() - 1;
|
|
+
|
|
+ while (start < s.size() && isspace(s[start])) {
|
|
+ start++;
|
|
+ }
|
|
+
|
|
+ while (end >= start && isspace(s[end])) {
|
|
+ end--;
|
|
+ }
|
|
+
|
|
+ if (end < start) {
|
|
+ return "";
|
|
+ }
|
|
+
|
|
+ return s.substr(start, end - start + 1);
|
|
+}
|
|
+
|
|
+unordered_map<string, unsigned int> g_capStrCapNum = {
|
|
+ { "CAP_CHOWN", CAP_CHOWN },
|
|
+ { "CAP_DAC_OVERRIDE", CAP_DAC_OVERRIDE },
|
|
+ { "CAP_DAC_READ_SEARCH", CAP_DAC_READ_SEARCH },
|
|
+ { "CAP_FOWNER", CAP_FOWNER },
|
|
+ { "CAP_FSETID", CAP_FSETID },
|
|
+ { "CAP_KILL", CAP_KILL },
|
|
+ { "CAP_SETGID", CAP_SETGID },
|
|
+ { "CAP_SETUID", CAP_SETUID },
|
|
+ { "CAP_LINUX_IMMUTABLE", CAP_LINUX_IMMUTABLE },
|
|
+ { "CAP_NET_BIND_SERVICE", CAP_NET_BIND_SERVICE },
|
|
+ { "CAP_NET_BROADCAST", CAP_NET_BROADCAST },
|
|
+ { "CAP_NET_ADMIN", CAP_NET_ADMIN },
|
|
+ { "CAP_NET_RAW", CAP_NET_RAW },
|
|
+ { "CAP_IPC_LOCK", CAP_IPC_LOCK },
|
|
+ { "CAP_IPC_OWNER", CAP_IPC_OWNER },
|
|
+ { "CAP_SYS_MODULE", CAP_SYS_MODULE },
|
|
+ { "CAP_SYS_RAWIO", CAP_SYS_RAWIO },
|
|
+ { "CAP_SYS_CHROOT", CAP_SYS_CHROOT },
|
|
+ { "CAP_SYS_PTRACE", CAP_SYS_PTRACE },
|
|
+ { "CAP_SYS_PACCT", CAP_SYS_PACCT },
|
|
+ { "CAP_SYS_ADMIN", CAP_SYS_ADMIN },
|
|
+ { "CAP_SYS_ROOT", CAP_SYS_BOOT },
|
|
+ { "CAP_SYS_NICE", CAP_SYS_NICE },
|
|
+ { "CAP_SYS_RESOURCE", CAP_SYS_RESOURCE },
|
|
+ { "CAP_SYS_TIME", CAP_SYS_TIME },
|
|
+ { "CAP_SYS_TTY_CONFIG", CAP_SYS_TTY_CONFIG },
|
|
+ { "CAP_MKNOD", CAP_MKNOD },
|
|
+ { "CAP_LEASE", CAP_LEASE },
|
|
+ { "CAP_AUDIT_WRITE", CAP_AUDIT_WRITE },
|
|
+ { "CAP_AUDIT_CONTROL", CAP_AUDIT_CONTROL },
|
|
+ { "CAP_SETFCAP", CAP_SETFCAP },
|
|
+ { "CAP_MAC_OVERRIDE", CAP_MAC_OVERRIDE },
|
|
+ { "CAP_MAC_ADMIN", CAP_MAC_ADMIN },
|
|
+ { "CAP_SYSLOG", CAP_SYSLOG },
|
|
+ { "CAP_WAKE_ALARM", CAP_WAKE_ALARM },
|
|
+ { "CAP_BLOCK_SUSPEND", CAP_BLOCK_SUSPEND },
|
|
+};
|
|
+
|
|
+static uint64_t GetCap(string cap)
|
|
+{
|
|
+ if (isdigit(cap[0])) {
|
|
+ return stoll(cap);
|
|
+ }
|
|
+
|
|
+ stringstream ss(cap);
|
|
+ string value;
|
|
+ uint64_t c = 0;
|
|
+ while (getline(ss, value, '|')) {
|
|
+ value = Trim(value);
|
|
+ if (g_capStrCapNum.count(value)) {
|
|
+ c |= (1ULL << g_capStrCapNum[value]);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return c;
|
|
+}
|
|
+
|
|
+enum {
|
|
+ DAC_PATH_IDX = 0,
|
|
+ DAC_MODE_IDX,
|
|
+ DAC_UID_IDX,
|
|
+ DAC_GID_IDX,
|
|
+ DAC_CAP_IDX,
|
|
+ DAC_NUM
|
|
+};
|
|
+
|
|
+extern "C" {
|
|
+ int LoadDacConfig(const char* fn)
|
|
+ {
|
|
+ char resolvedPath[PATH_MAX] = {'\0'};
|
|
+ char *canonicalPath = realpath(fn, resolvedPath);
|
|
+ if (canonicalPath == nullptr) {
|
|
+ return -1;
|
|
+ }
|
|
+ ifstream readFile(canonicalPath);
|
|
+ if (readFile.fail()) {
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ string str;
|
|
+ vector<string> values(DAC_NUM, ""); // path, mode, uid, gid, cap
|
|
+ while (getline(readFile, str)) {
|
|
+ str = Trim(str);
|
|
+ if (str.empty() || str[0] == '#') {
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ stringstream ss(str);
|
|
+ string value;
|
|
+ int i = 0;
|
|
+ while (getline(ss, value, ',')) {
|
|
+ if (i >= DAC_NUM) {
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ value = Trim(value);
|
|
+ if (value.empty()) {
|
|
+ continue;
|
|
+ }
|
|
+ values[i++] = value;
|
|
+ }
|
|
+
|
|
+ if (i != DAC_NUM) {
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ int uid = 0;
|
|
+ if (isdigit(values[DAC_UID_IDX][0])) {
|
|
+ uid = stoi(values[DAC_UID_IDX]);
|
|
+ }
|
|
+
|
|
+ int gid = 0;
|
|
+ if (isdigit(values[DAC_GID_IDX][0])) {
|
|
+ gid = stoi(values[DAC_GID_IDX]);
|
|
+ }
|
|
+
|
|
+ uint64_t cap = GetCap(values[DAC_CAP_IDX]);
|
|
+ DacConfig dacConfig(stoi(values[DAC_MODE_IDX], 0, 8), uid, gid, cap, values[DAC_PATH_IDX]); // 8 oct
|
|
+ g_configMap[dacConfig.path] = dacConfig;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ void GetDacConfig(const char* path, int dir, char* targetOutPath,
|
|
+ unsigned* uid, unsigned* gid, unsigned* mode,
|
|
+ uint64_t* capabilities)
|
|
+ {
|
|
+ if (path && path[0] == '/') {
|
|
+ path++;
|
|
+ }
|
|
+
|
|
+ (void)targetOutPath;
|
|
+ string str = path;
|
|
+ string str2;
|
|
+ DacConfig dacConfig(00755, 0, 0, 0, "");
|
|
+
|
|
+ if (dir == 0) {
|
|
+ dacConfig.SetDefault(00644, 0, 0, 0, "");
|
|
+ }
|
|
+
|
|
+ if (g_configMap.count(str)) {
|
|
+ dacConfig = g_configMap[str];
|
|
+ } else if (dir == 0 && !str.empty()) {
|
|
+ for (auto i = str.size() - 1; i >= 0; i--) {
|
|
+ if (str[i] == '/') {
|
|
+ break;
|
|
+ } else {
|
|
+ str2 = str.substr(0, i) + "*";
|
|
+ if (g_configMap.count(str2)) {
|
|
+ dacConfig = g_configMap[str2];
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ *uid = dacConfig.uid;
|
|
+ *gid = dacConfig.gid;
|
|
+ *mode = dacConfig.mode;
|
|
+ *capabilities = dacConfig.capabilities;
|
|
+ }
|
|
+}
|
|
+}
|
|
diff --git a/contrib/android/dac_config.h b/contrib/android/dac_config.h
|
|
new file mode 100644
|
|
index 00000000..45b89393
|
|
--- /dev/null
|
|
+++ b/contrib/android/dac_config.h
|
|
@@ -0,0 +1,32 @@
|
|
+/*
|
|
+ * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; version 2.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but WITHOUT
|
|
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License along with
|
|
+ * this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
|
|
+ * Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
+ */
|
|
+
|
|
+#ifndef __DAC_CONFIG
|
|
+#define __DAC_CONFIG
|
|
+#include <stdint.h>
|
|
+
|
|
+#ifdef __cpluscplus
|
|
+extern "C" {
|
|
+#endif
|
|
+
|
|
+int LoadDacConfig(const char* fn);
|
|
+void GetDacConfig(const char* path, int dir, char* targetOutPath,
|
|
+ unsigned* uid, unsigned* gid, unsigned* mode,
|
|
+ uint64_t* capabilities);
|
|
+
|
|
+#ifdef __cpluscplus
|
|
+}
|
|
+#endif
|
|
+#endif
|
|
diff --git a/contrib/android/perms.c b/contrib/android/perms.c
|
|
index 9c5ec05b..680d348e 100644
|
|
--- a/contrib/android/perms.c
|
|
+++ b/contrib/android/perms.c
|
|
@@ -358,16 +358,25 @@ errcode_t android_configure_fs(ext2_filsys fs, char *src_dir, char *target_out,
|
|
|
|
/* Load the FS config */
|
|
if (fs_config_file) {
|
|
+#if defined(__ANDROID__)
|
|
retval = load_canned_fs_config(fs_config_file);
|
|
+#else
|
|
+ retval = LoadDacConfig(fs_config_file);
|
|
+#endif
|
|
if (retval < 0) {
|
|
com_err(__func__, retval,
|
|
_("while loading fs_config \"%s\""),
|
|
fs_config_file);
|
|
return retval;
|
|
}
|
|
+#if defined(__ANDROID__)
|
|
fs_config_func = canned_fs_config;
|
|
} else if (mountpoint)
|
|
fs_config_func = fs_config;
|
|
+#else
|
|
+ fs_config_func = GetDacConfig;
|
|
+ }
|
|
+#endif
|
|
|
|
return __android_configure_fs(fs, src_dir, target_out, mountpoint,
|
|
fs_config_func, sehnd, fixed_time,
|
|
diff --git a/contrib/android/perms.h b/contrib/android/perms.h
|
|
index 6d6a2129..2bb0021f 100644
|
|
--- a/contrib/android/perms.h
|
|
+++ b/contrib/android/perms.h
|
|
@@ -48,11 +48,12 @@ static inline errcode_t android_configure_fs(ext2_filsys fs,
|
|
# include <selinux/label.h>
|
|
# if defined(__ANDROID__)
|
|
# include <selinux/android.h>
|
|
-# endif
|
|
# include <private/android_filesystem_config.h>
|
|
# include <private/canned_fs_config.h>
|
|
# include <private/fs_config.h>
|
|
-
|
|
+# else /* !__ANDROID__ */
|
|
+#include "dac_config.h"
|
|
+# endif
|
|
errcode_t android_configure_fs(ext2_filsys fs, char *src_dir,
|
|
char *target_out,
|
|
char *mountpoint,
|
|
--
|
|
diff --git a/contrib/android/dac_config.cpp b/contrib/android/dac_config.cpp
|
|
index 422e0d52280ff4f142b278c5fedb04790846b9ee..1c76dfd7e7d1b067941b79e73311144d548a3179 100644
|
|
--- a/contrib/android/dac_config.cpp
|
|
+++ b/contrib/android/dac_config.cpp
|
|
@@ -35,14 +35,14 @@ struct DacConfig {
|
|
string path;
|
|
|
|
DacConfig() : uid(0), gid(0), mode(0), capabilities(0), path("") {}
|
|
- DacConfig(unsigned int m, unsigned int u, unsigned int g, uint64_t c, string p) :
|
|
+ DacConfig(unsigned int m, unsigned int u, unsigned int g, uint64_t c, const string &p) :
|
|
uid(u),
|
|
gid(g),
|
|
mode(m),
|
|
capabilities(c),
|
|
path(p) {}
|
|
|
|
- void SetDefault(unsigned int m, unsigned int u, unsigned int g, uint64_t c, string p)
|
|
+ void SetDefault(unsigned int m, unsigned int u, unsigned int g, uint64_t c, const string &p)
|
|
{
|
|
this->uid = u;
|
|
this->gid = g;
|
|
@@ -198,33 +198,28 @@ extern "C" {
|
|
return 0;
|
|
}
|
|
|
|
- void GetDacConfig(const char* path, int dir, char* targetOutPath,
|
|
+ void GetDacConfig(const char* path, int dir, char*,
|
|
unsigned* uid, unsigned* gid, unsigned* mode,
|
|
uint64_t* capabilities)
|
|
{
|
|
- if (path && path[0] == '/') {
|
|
- path++;
|
|
- }
|
|
-
|
|
- (void)targetOutPath;
|
|
- string str = path;
|
|
- string str2;
|
|
+ string str = (path != nullptr && *path == '/') ? path + 1 : path;
|
|
DacConfig dacConfig(00755, 0, 0, 0, "");
|
|
|
|
if (dir == 0) {
|
|
dacConfig.SetDefault(00644, 0, 0, 0, "");
|
|
}
|
|
|
|
- if (g_configMap.count(str)) {
|
|
- dacConfig = g_configMap[str];
|
|
+ auto it = g_configMap.find(str);
|
|
+ if (it != g_configMap.end()) {
|
|
+ dacConfig = it->second;
|
|
} else if (dir == 0 && !str.empty()) {
|
|
- for (auto i = str.size() - 1; i >= 0; i--) {
|
|
+ for (int i = static_cast<int>(str.size()) - 1; i >= 0; i--) {
|
|
if (str[i] == '/') {
|
|
break;
|
|
} else {
|
|
- str2 = str.substr(0, i) + "*";
|
|
- if (g_configMap.count(str2)) {
|
|
- dacConfig = g_configMap[str2];
|
|
+ it = g_configMap.find(str.substr(0, i) + "*");
|
|
+ if (it != g_configMap.end()) {
|
|
+ dacConfig = it->second;
|
|
break;
|
|
}
|
|
}
|