diff --git a/interfaces/innerkits/client/appspawn_client.c b/interfaces/innerkits/client/appspawn_client.c index b81556d25c7b51b442e362d8a0dfeb36e5d7d0d1..9ff0081a9565fef144ec128d4444960a19dde8fc 100644 --- a/interfaces/innerkits/client/appspawn_client.c +++ b/interfaces/innerkits/client/appspawn_client.c @@ -35,6 +35,7 @@ #include "parameter.h" #include "securec.h" +#define USER_LOCK_STATUS_SIZE 8 static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; static AppSpawnReqMsgMgr *g_clientInstance[CLIENT_MAX] = {NULL}; @@ -358,3 +359,36 @@ int AppSpawnClientSendMsg(AppSpawnClientHandle handle, AppSpawnReqMsgHandle reqH AppSpawnReqMsgFree(reqHandle); return ret; } + +int AppSpawnClientSendUserLockStatus(uint32_t userId, bool isLocked) +{ + char lockstatus[USER_LOCK_STATUS_SIZE] = {0}; + int ret = snprintf_s(lockstatus, USER_LOCK_STATUS_SIZE, USER_LOCK_STATUS_SIZE - 1, "%u:%d", userId, isLocked); + APPSPAWN_CHECK(ret > 0, return ret, "Failed to build lockstatus req msg, ret = %{public}d", ret); + APPSPAWN_LOGI("Send lockstatus msg to appspawn %{public}s", lockstatus); + + AppSpawnReqMsgHandle reqHandle; + ret = AppSpawnReqMsgCreate(MSG_LOCK_STATUS, "storage_manager", &reqHandle); + APPSPAWN_CHECK(ret == 0, return ret, "Failed to create appspawn req msg, ret = %{public}d", ret); + + ret = AppSpawnReqMsgAddStringInfo(reqHandle, "lockstatus", lockstatus); + APPSPAWN_CHECK(ret == 0, AppSpawnReqMsgFree(reqHandle); + return ret, "Failed to add lockstatus message, ret=%{public}d", ret); + + AppSpawnClientHandle clientHandle; + ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle); + APPSPAWN_CHECK(ret == 0, AppSpawnReqMsgFree(reqHandle); + return ret, "Appspawn client failed to init, ret=%{public}d", ret); + + AppSpawnResult result = {0}; + ret = AppSpawnClientSendMsg(clientHandle, reqHandle, &result); + AppSpawnClientDestroy(clientHandle); + APPSPAWN_CHECK(ret == 0, return ret, "Send msg to appspawn failed, ret=%{public}d", ret); + + if (result.result != 0) { + APPSPAWN_LOGE("Appspawn failed to handle message, result=%{public}d", result.result); + return result.result; + } + APPSPAWN_LOGI("Send lockstatus msg to appspawn success"); + return 0; +} diff --git a/interfaces/innerkits/client/libappspawn_client.versionscript b/interfaces/innerkits/client/libappspawn_client.versionscript index 0863f5417c5880beb0d8f61e3381e650399e3435..03ebc5b465ce31e400603562e5a7fdc649fa2b4e 100644 --- a/interfaces/innerkits/client/libappspawn_client.versionscript +++ b/interfaces/innerkits/client/libappspawn_client.versionscript @@ -33,6 +33,7 @@ AppSpawnReqMsgAddStringInfo; AppSpawnTerminateMsgCreate; AppSpawnClientAddPermission; + AppSpawnClientSendUserLockStatus; GetPermissionIndex; GetMaxPermissionIndex; GetPermissionByIndex; diff --git a/interfaces/innerkits/include/appspawn.h b/interfaces/innerkits/include/appspawn.h index 93252cb2f715f1f7ef35398da4de84f9c25eb965..b0054b1fc8ac5eb595f0a8efe4156967c6631562 100644 --- a/interfaces/innerkits/include/appspawn.h +++ b/interfaces/innerkits/include/appspawn.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #ifdef __cplusplus @@ -97,6 +98,15 @@ int AppSpawnClientDestroy(AppSpawnClientHandle handle); */ int AppSpawnClientSendMsg(AppSpawnClientHandle handle, AppSpawnReqMsgHandle reqHandle, AppSpawnResult *result); +/** + * @brief send client user lock status request + * + * @param userId user id + * @param isLocked lock status + * @return if succeed return 0,else return other value + */ +int AppSpawnClientSendUserLockStatus(uint32_t userId, bool isLocked); + typedef enum { MSG_APP_SPAWN = 0, MSG_GET_RENDER_TERMINATION_STATUS, @@ -106,6 +116,7 @@ typedef enum { MSG_BEGET_SPAWNTIME, MSG_UPDATE_MOUNT_POINTS, MSG_RESTART_SPAWNER, + MSG_LOCK_STATUS, MAX_TYPE_INVALID } AppSpawnMsgType; diff --git a/modules/sandbox/sandbox_utils.cpp b/modules/sandbox/sandbox_utils.cpp index 61f1fe429424b901f9df7989683a5e0b0f40a3ec..0a6b07c94e49ca79e0146e16afdc3c1cb7dd27bc 100644 --- a/modules/sandbox/sandbox_utils.cpp +++ b/modules/sandbox/sandbox_utils.cpp @@ -50,6 +50,7 @@ #endif #define MAX_MOUNT_TIME 500 // 500us +#define LOCK_STATUS_SIZE 16 using namespace std; using namespace OHOS; @@ -1802,30 +1803,20 @@ int32_t SetAppSandboxProperty(AppSpawnMgr *content, AppSpawningCtx *property) #define DIR_MODE 0711 #ifndef APPSPAWN_SANDBOX_NEW -static bool IsUnlockStatus(uint32_t uid, const char *bundleName, size_t bundleNameLen) +static bool IsUnlockStatus(uint32_t uid) { - const int userIdBase = 200000; + const int userIdBase = UID_BASE; uid = uid / userIdBase; if (uid == 0) { return true; } - - const char rootPath[] = "/data/app/el2/"; - const char basePath[] = "/base/"; - size_t allPathSize = strlen(rootPath) + strlen(basePath) + 1 + USER_ID_SIZE + bundleNameLen; - char *path = reinterpret_cast(malloc(sizeof(char) * allPathSize)); - APPSPAWN_CHECK(path != NULL, return true, "Failed to malloc path"); - int len = sprintf_s(path, allPathSize, "%s%u%s%s", rootPath, uid, basePath, bundleName); - APPSPAWN_CHECK(len > 0 && ((size_t)len < allPathSize), free(path); - return true, "Failed to get base path"); - - if (access(path, F_OK) == 0) { - APPSPAWN_LOGI("bundleName:%{public}s this is unlock status", bundleName); - free(path); + std::string lockStatusParam = "startup.appspawn.lockstatus_" + std::to_string(uid); + char userLockStatus[LOCK_STATUS_SIZE] = {0}; + int ret = GetParameter(lockStatusParam.c_str(), "1", userLockStatus, sizeof(userLockStatus)); + APPSPAWN_LOGI("get param %{public}s %{public}s", lockStatusParam.c_str(), userLockStatus); + if (ret > 0 && (strcmp(userLockStatus, "0") == 0)) { // 0:unlock status 1:lock status return true; } - free(path); - APPSPAWN_LOGI("bundleName:%{public}s this is lock status", bundleName); return false; } @@ -2032,8 +2023,7 @@ static void MountDirToShared(const AppSpawningCtx *property) string sourcePath = "/data/app/el1/bundle/public/" + string(bundleName); MountDir(property, rootPath, sourcePath.c_str(), el1Path); - size_t bundleNameLen = strlen(bundleName); - if (IsUnlockStatus(info->uid, bundleName, bundleNameLen)) { + if (IsUnlockStatus(info->uid)) { return; } @@ -2062,7 +2052,10 @@ static int SpawnMountDirToShared(AppSpawnMgr *content, AppSpawningCtx *property) { #ifndef APPSPAWN_SANDBOX_NEW // mount dynamic directory - MountDirToShared(property); + if (!IsNWebSpawnMode(content)) { + // mount dynamic directory + MountDirToShared(property); + } #endif return 0; } diff --git a/standard/appspawn_service.c b/standard/appspawn_service.c index b5fa4983a4479e0c8de75986709fa9ea709b2076..9f19438c72770175fa09c37ffdd39996e30bc97a 100644 --- a/standard/appspawn_service.c +++ b/standard/appspawn_service.c @@ -50,7 +50,11 @@ #define PATH_SIZE 256 #define FD_PATH_SIZE 128 #define MAX_MEM_SIZE (4 * 1024) +#define APPSPAWN_MSG_USER_CHECK_COUNT 4 #define PREFORK_PROCESS "apppool" +#define USER_ID_MIN_VALUE 100 +#define USER_ID_MAX_VALUE 10736 +#define LOCK_STATUS_PARAM_SIZE 64 #ifndef PIDFD_NONBLOCK #define PIDFD_NONBLOCK O_NONBLOCK #endif @@ -340,8 +344,8 @@ static int OnConnection(const LoopHandle loopHandle, const TaskHandle server) struct ucred cred = {-1, -1, -1}; socklen_t credSize = sizeof(struct ucred); if ((getsockopt(LE_GetSocketFd(stream), SOL_SOCKET, SO_PEERCRED, &cred, &credSize) < 0) || - (cred.uid != DecodeUid("foundation") && cred.uid != DecodeUid("root") - && cred.uid != DecodeUid("app_fwk_update"))) { + (cred.uid != DecodeUid("foundation") && cred.uid != DecodeUid("root") && + cred.uid != DecodeUid("app_fwk_update") && cred.uid != DecodeUid("storage_manager"))) { APPSPAWN_LOGE("Invalid uid %{public}d from client", cred.uid); LE_CloseStreamTask(LE_GetDefaultLoop(), stream); return -1; @@ -1419,6 +1423,38 @@ static void ProcessSpawnRestartMsg(AppSpawnConnection *connection, AppSpawnMsgNo APPSPAWN_LOGE("Failed to execv, ret %{public}d, errno %{public}d", ret, errno); } +static void ProcessAppSpawnLockStatusMsg(AppSpawnMsgNode *message) +{ + APPSPAWN_CHECK_ONLY_EXPER(message != NULL, return); + uint32_t len = 0; + char *lockstatus = (char *)GetAppSpawnMsgExtInfo(message, "lockstatus", &len); + APPSPAWN_CHECK(lockstatus != NULL, return, "failed to get lockstatus"); + APPSPAWN_LOGI("appspawn get lockstatus %{public}s from storage_manager", lockstatus); + char *userLockStatus = NULL; + // userLockStatus format example: 100:0 100 for userid 0:unlock 1:lock + char *userIdStr = strtok_r(lockstatus, ":", &userLockStatus); + APPSPAWN_CHECK(userIdStr != NULL && userLockStatus != NULL, return, + "lockstatus not satisfied format, failed to get userLockStatus"); + int userId = atoi(userIdStr); + + + if (userId < USER_ID_MIN_VALUE || userId > USER_ID_MAX_VALUE) { + APPSPAWN_LOGE("userId err %{public}s", userIdStr); + return; + } + if (strcmp(userLockStatus, "0") != 0 && strcmp(userLockStatus, "1") != 0) { + APPSPAWN_LOGE("userLockStatus err %{public}s", userLockStatus); + return; + } + char lockStatusParam[LOCK_STATUS_PARAM_SIZE] = {0}; + int ret = snprintf_s(lockStatusParam, sizeof(lockStatusParam), sizeof(lockStatusParam) - 1, + "startup.appspawn.lockstatus_%d", userId); + + APPSPAWN_CHECK(ret > 0, return, "get lock status param failed, errno %{public}d", errno); + ret = SetParameter(lockStatusParam, userLockStatus); + APPSPAWN_CHECK(ret == 0, return, "failed to set lockstatus param value ret %{public}d", ret); +} + static void ProcessRecvMsg(AppSpawnConnection *connection, AppSpawnMsgNode *message) { AppSpawnMsg *msg = &message->msgHeader; @@ -1463,6 +1499,11 @@ static void ProcessRecvMsg(AppSpawnConnection *connection, AppSpawnMsgNode *mess case MSG_RESTART_SPAWNER: ProcessSpawnRestartMsg(connection, message); break; + case MSG_LOCK_STATUS: + ProcessAppSpawnLockStatusMsg(message); + SendResponse(connection, msg, 0, 0); + DeleteAppSpawnMsg(message); + break; default: SendResponse(connection, msg, APPSPAWN_MSG_INVALID, 0); DeleteAppSpawnMsg(message);