diff --git a/services/modules/seccomp/seccomp_policy.c b/services/modules/seccomp/seccomp_policy.c index 6c57fb3687d4fe43a6ab210e04cbb3975ded16de..12bd90fac38c686cd4341e6fa712a95a0ad317db 100644 --- a/services/modules/seccomp/seccomp_policy.c +++ b/services/modules/seccomp/seccomp_policy.c @@ -26,6 +26,7 @@ #include #include #include +#include #ifndef SECCOMP_SET_MODE_FILTER #define SECCOMP_SET_MODE_FILTER (1) @@ -39,6 +40,13 @@ #define FILTER_NAME_FORMAT "g_%sSeccompFilter" #define FILTER_SIZE_STRING "Size" +typedef enum { + SECCOMP_SUCCESS, + INPUT_ERROR, + RETURN_NULL, + RETURN_ERROR +} SeccompErrorCode; + static bool IsSupportFilterFlag(unsigned int filterFlag) { errno = 0; @@ -75,43 +83,101 @@ static bool InstallSeccompPolicy(const struct sock_filter* filter, size_t filter return true; } -bool SetSeccompPolicyWithName(const char *filterName) +static char *GetFilterFileByName(const char *filterName) { - char filterLibPath[512] = {0}; - char filterVaribleName[512] = {0}; - struct sock_filter *filterPtr = NULL; - size_t *filterSize = NULL; + size_t maxFilterNameLen = PATH_MAX - strlen(FILTER_LIB_PATH_FORMAT) + strlen("%s") - 1; + if (filterName == NULL && strlen(filterName) > maxFilterNameLen) { + return NULL; + } + + char filterLibPath[PATH_MAX] = {0}; int rc = snprintf_s(filterLibPath, sizeof(filterLibPath), \ - strlen(filterName) + strlen(FILTER_LIB_PATH_FORMAT) - strlen("%s"), \ - FILTER_LIB_PATH_FORMAT, filterName); - PLUGIN_CHECK(rc != -1, return false, "snprintf_s filterLibPath failed"); + strlen(filterName) + strlen(FILTER_LIB_PATH_FORMAT) - strlen("%s"), \ + FILTER_LIB_PATH_FORMAT, filterName); + if (rc == -1) { + return NULL; + } + + return realpath(filterLibPath, NULL); +} - rc = snprintf_s(filterVaribleName, sizeof(filterVaribleName), \ +static int GetSeccompPolicy(const char *filterName, int **handler, + char *filterLibRealPath, struct sock_fprog *prog) +{ + char filterVaribleName[PATH_MAX] = {0}; + struct sock_filter *filter = NULL; + size_t *filterSize = NULL; + void *policyHanlder = NULL; + int ret = SECCOMP_SUCCESS; + do { + int rc = snprintf_s(filterVaribleName, sizeof(filterVaribleName), \ strlen(filterName) + strlen(FILTER_NAME_FORMAT) - strlen("%s"), \ FILTER_NAME_FORMAT, filterName); - PLUGIN_CHECK(rc != -1, return false, "snprintf_s faiVribleName failed"); - const char *filterLibRealPath = realpath(filterLibPath, NULL); - PLUGIN_CHECK(filterLibRealPath != NULL, return false, "format filter lib real path failed"); - - void *handler = dlopen(filterLibRealPath, RTLD_LAZY); - PLUGIN_CHECK(handler != NULL, return false, "dlopen %s failed", filterLibRealPath); - - filterPtr = (struct sock_filter *)dlsym(handler, filterVaribleName); - PLUGIN_CHECK(filterPtr != NULL, dlclose(handler); - return false, "dlsym %s failed", filterVaribleName); + if (rc == -1) { + ret = RETURN_ERROR; + break; + } + + policyHanlder = dlopen(filterLibRealPath, RTLD_LAZY); + if (policyHanlder == NULL) { + ret = RETURN_NULL; + break; + } + + filter = (struct sock_filter *)dlsym(policyHanlder, filterVaribleName); + if (filter == NULL) { + ret = RETURN_NULL; + break; + } + + rc = strcat_s(filterVaribleName, strlen(filterVaribleName) + \ + strlen(FILTER_SIZE_STRING) + 1, FILTER_SIZE_STRING); + if (rc != 0) { + ret = RETURN_ERROR; + break; + } + + filterSize = (size_t *)dlsym(policyHanlder, filterVaribleName); + if (filterSize == NULL) { + ret = RETURN_NULL; + break; + } + } while (0); + + *handler = (int *)policyHanlder; + prog->filter = filter; + if (filterSize != NULL) { + prog->len = (unsigned short)(*filterSize); + } - rc = strcat_s(filterVaribleName, strlen(filterVaribleName) + strlen(FILTER_SIZE_STRING) + 1, FILTER_SIZE_STRING); - PLUGIN_CHECK(rc == 0, dlclose(handler); - return false, "strcat_s filterVaribleName failed"); + return ret; +} - filterSize = (size_t *)dlsym(handler, filterVaribleName); - PLUGIN_CHECK(filterSize != NULL, dlclose(handler); - return false, "dlsym %s failed", filterVaribleName); +bool SetSeccompPolicyWithName(const char *filterName) +{ + void *handler = NULL; + char *filterLibRealPath = NULL; + struct sock_fprog prog = {0}; + bool ret = false; + + filterLibRealPath = GetFilterFileByName(filterName); + PLUGIN_CHECK(filterLibRealPath != NULL, return false, "get filter file name faield"); + + int retCode = GetSeccompPolicy(filterName, (int **)&handler, filterLibRealPath, &prog); + if (retCode == SECCOMP_SUCCESS) { + ret = InstallSeccompPolicy(prog.filter, prog.len, SECCOMP_FILTER_FLAG_LOG); + } else { + PLUGIN_LOGE("GetSeccompPolicy failed return is %d", retCode); + } - bool ret = InstallSeccompPolicy(filterPtr, *filterSize, SECCOMP_FILTER_FLAG_LOG); + if (handler != NULL) { + dlclose(handler); + } - dlclose(handler); + if (filterLibRealPath != NULL) { + free(filterLibRealPath); + } return ret; }