return (*subdir == '/');
}
-static inline bool installRequestAuthCheck(const app_inst_req &req, uid_t uid)
+static bool getUserAppDir(const uid_t &uid, std::string &userAppDir)
{
- struct passwd *pwd;
- do {
- errno = 0;
- pwd = getpwuid(uid);
- if (!pwd && errno != EINTR) {
- LogError("getpwuid failed with '" << uid
- << "' as parameter: " << strerror(errno));
- return false;
- }
- } while (!pwd);
+ struct tzplatform_context *tz_ctx = nullptr;
- std::unique_ptr<char, std::function<void(void*)>> home(
- realpath(pwd->pw_dir, NULL), free);
- if (!home.get()) {
- LogError("realpath failed with '" << pwd->pw_dir
- << "' as parameter: " << strerror(errno));
+ if (tzplatform_context_create(&tz_ctx))
return false;
+
+ if (tzplatform_context_set_user(tz_ctx, uid)) {
+ tzplatform_context_destroy(tz_ctx);
+ tz_ctx = nullptr;
+ return false;
+ }
+
+ enum tzplatform_variable id =
+ (uid == getGlobalUserId()) ? TZ_SYS_RW_APP : TZ_USER_APP;
+ const char *appDir = tzplatform_context_getenv(tz_ctx, id);
+ if (!appDir) {
+ tzplatform_context_destroy(tz_ctx);
+ tz_ctx = nullptr;
+ return false;
}
+ userAppDir = appDir;
+
+ tzplatform_context_destroy(tz_ctx);
+ tz_ctx = nullptr;
+
+ return true;
+}
+
+static inline bool installRequestAuthCheck(const app_inst_req &req, uid_t uid, bool &isCorrectPath, std::string &appPath)
+{
+ std::string userHome;
+ std::string userAppDir;
+ std::stringstream correctPath;
+
+ if (uid != getGlobalUserId())
+ LogDebug("Installation type: single user");
+ else
+ LogDebug("Installation type: global installation");
+
+ if (!getUserAppDir(uid, userAppDir)) {
+ LogError("Failed getting app dir for user uid: " << uid);
+ return false;
+ }
+
+ appPath = userAppDir;
+ correctPath.clear();
+ correctPath << userAppDir << "/" << req.pkgId << "/" << req.appId;
+ LogDebug("correctPath: " << correctPath.str());
+
for (const auto &appPath : req.appPaths) {
std::unique_ptr<char, std::function<void(void*)>> real_path(
realpath(appPath.first.c_str(), NULL), free);
return false;
}
LogDebug("Requested path is '" << appPath.first.c_str()
- << "'. User's HOME is '" << pwd->pw_dir << "'");
- if (!isSubDir(home.get(), real_path.get())) {
- LogWarning("User's apps may have registered folders only in user's home dir");
+ << "'. User's APPS_DIR is '" << userAppDir << "'");
+ if (!isSubDir(userAppDir.c_str(), real_path.get())) {
+ LogWarning("User's apps may have registered folders only in user's APPS_DIR");
return false;
}
+ if (!isSubDir(correctPath.str().c_str(), real_path.get())) {
+ LogWarning("Installation is outside correct path: " << correctPath.str());
+ //return false;
+ } else
+ isCorrectPath = true;
+
app_install_path_type pathType = static_cast<app_install_path_type>(appPath.second);
if (pathType == SECURITY_MANAGER_PATH_PUBLIC) {
LogWarning("Only root can register SECURITY_MANAGER_PATH_PUBLIC path");
std::vector<std::string> removedPermissions;
std::vector<std::string> pkgContents;
std::string uidstr;
+ bool isCorrectPath = false;
+ std::string appPath;
if (uid) {
if (uid != req.uid) {
LogError("User " << uid <<
}
checkGlobalUser(uid, uidstr);
- if (!installRequestAuthCheck(req, uid)) {
+ if (!installRequestAuthCheck(req, uid, isCorrectPath, appPath)) {
LogError("Request from uid " << uid << " for app installation denied");
return SECURITY_MANAGER_API_ERROR_AUTHENTICATION_FAILED;
}
return SECURITY_MANAGER_API_ERROR_SERVER_ERROR;
}
+ if (isCorrectPath)
+ if (!setupCorrectPath(req.pkgId, req.appId, appPath)) {
+ LogError("Can't setup <APP_ROOT> dirs");
+ return false;
+ }
+
// register paths
for (const auto &appPath : req.appPaths) {
const std::string &path = appPath.first;
return FileDecision::SKIP;
}
+static inline bool pathSetSmack(const char *path, const std::string &label,
+ const char *xattr_name)
+{
+ if (lsetxattr(path, xattr_name, label.c_str(), label.length(), 0) != 0)
+ return false;
+
+ return true;
+}
+
static bool dirSetSmack(const std::string &path, const std::string &label,
const char *xattr_name, LabelDecisionFn fn)
{
}
if (ret == FileDecision::LABEL) {
- if (lsetxattr(ftsent->fts_path, xattr_name, label.c_str(), label.length(), 0) != 0) {
- LogError("lsetxattr failed.");
+ if (!pathSetSmack(ftsent->fts_path, label, xattr_name)) {
+ LogError("pathSetSmack failed.");
return false;
}
}
return true;
}
-
static bool labelDir(const std::string &path, const std::string &label,
bool set_transmutable, bool set_executables)
{
return label;
}
+bool setupCorrectPath(const std::string &pkgId, const std::string &appId, const std::string &appPath)
+{
+ std::string tmpPath;
+ std::string label;
+
+ tmpPath.clear();
+ tmpPath = appPath + "/" + pkgId;
+
+ label.clear();
+ generatePkgLabel(pkgId, label);
+
+ if (!pathSetSmack(tmpPath.c_str(), label, XATTR_NAME_SMACK)) {
+ LogError("pathSetSmack failed (access label) on: " << tmpPath);
+ return false;
+ }
+
+ label.clear();
+ generateAppLabel(appId, label);
+ tmpPath += "/" + appId;
+
+ if (!pathSetSmack(tmpPath.c_str(), label, XATTR_NAME_SMACK)) {
+ LogError("pathSetSmack failed (access label) on: " << tmpPath);
+ return false;
+ }
+
+ if (!pathSetSmack(tmpPath.c_str(), "TRUE", XATTR_NAME_SMACKTRANSMUTE)) {
+ LogError("pathSetSmack failed (transmute) on: " << tmpPath);
+ return false;
+ }
+
+ return true;
+}
+
bool generateAppLabel(const std::string &appId, std::string &label)
{
(void) appId;