//-------------------------------------------------------------------------------------------------- le_result_t cgrp_Delete ( cgrp_SubSys_t subsystem, ///< Sub-system of the cgroup. const char* cgroupNamePtr ///< Name of the cgroup to delete. ) { // Create the path to the cgroup. char path[LIMIT_MAX_PATH_BYTES] = ROOT_PATH; LE_ASSERT(le_path_Concat("/", path, sizeof(path), SubSysName[subsystem], cgroupNamePtr, (char*)NULL) == LE_OK); // Attempt to remove the cgroup directory. if (rmdir(path) != 0) { if (errno == EBUSY) { LE_ERROR("Could not remove cgroup '%s'. Tasks (process) list may not be empty. %m.", path); return LE_BUSY; } else { LE_ERROR("Could not remove cgroup '%s'. %m.", path); return LE_FAULT; } } LE_DEBUG("Deleted cgroup %s.", path); return LE_OK; }
//-------------------------------------------------------------------------------------------------- void cgrp_Init ( void ) { // Setup the cgroup root directory if it does not already exist. if (!fs_IsMounted(ROOT_NAME, ROOT_PATH)) { LE_FATAL_IF(mount(ROOT_NAME, ROOT_PATH, "tmpfs", 0, NULL) != 0, "Could not mount cgroup root file system. %m."); } // Setup a separate cgroup hierarch for each supported subsystem. cgrp_SubSys_t subSys = 0; for (; subSys < CGRP_NUM_SUBSYSTEMS; subSys++) { char dir[LIMIT_MAX_PATH_BYTES] = ROOT_PATH; LE_ASSERT(le_path_Concat("/", dir, sizeof(dir), SubSysName[subSys], (char*)NULL) == LE_OK); LE_ASSERT(le_dir_Make(dir, S_IRWXU) != LE_FAULT); if (!fs_IsMounted(SubSysName[subSys], dir)) { LE_FATAL_IF(mount(SubSysName[subSys], dir, "cgroup", 0, SubSysName[subSys]) != 0, "Could not mount cgroup subsystem '%s'. %m.", SubSysName[subSys]); LE_INFO("Mounted cgroup hiearchy for subsystem '%s'.", SubSysName[subSys]); } } }
//-------------------------------------------------------------------------------------------------- le_result_t cgrp_Create ( cgrp_SubSys_t subsystem, ///< Sub-system the cgroup belongs to. const char* cgroupNamePtr ///< Name of the cgroup to create. ) { // Create the path to the cgroup. char path[LIMIT_MAX_PATH_BYTES] = ROOT_PATH; LE_ASSERT(le_path_Concat("/", path, sizeof(path), SubSysName[subsystem], cgroupNamePtr, (char*)NULL) == LE_OK); // Create the cgroup. le_result_t result = le_dir_Make(path, S_IRWXU); if (result == LE_DUPLICATE) { LE_ERROR("Cgroup %s already exists.", path); return LE_DUPLICATE; } else if (result == LE_FAULT) { LE_ERROR("Could not create cgroup %s.", path); return LE_FAULT; } return LE_OK; }
//-------------------------------------------------------------------------------------------------- static int OpenCgrpFile ( cgrp_SubSys_t subsystem, ///< [IN] Sub-system of the cgroup. const char* cgroupNamePtr, ///< [IN] Name of the cgroup. const char* fileNamePtr, ///< [IN] Name of the file. int accessMode ///< [IN] Either O_RDONLY, O_WRONLY, or O_RDWR. ) { // Create the path to the cgroup file. char path[LIMIT_MAX_PATH_BYTES] = ROOT_PATH; LE_ASSERT(le_path_Concat("/", path, sizeof(path), SubSysName[subsystem], cgroupNamePtr, fileNamePtr, (char*)NULL) == LE_OK); // Open the cgroup file. int fd; do { fd = open(path, accessMode); } while ((fd < 0) && (errno == EINTR)); if (fd < 0) { LE_ERROR("Could not open file '%s'. %m.", path); } return fd; }
//-------------------------------------------------------------------------------------------------- static void SetPath ( const char* argPtr ///< [IN] Command-line argument. ) { Path[0] = '/'; if (le_path_Concat("/", Path, sizeof(Path), argPtr, NULL) != LE_OK) { fprintf(stderr, "Path is too long.\n"); exit(EXIT_FAILURE); } }
//-------------------------------------------------------------------------------------------------- static app_Ref_t GetAppRef ( const char * appNamePtr ///< [IN] App name ) { app_Ref_t appRef; char configPath[LIMIT_MAX_PATH_BYTES] = ""; INTERNAL_ERR_IF(le_path_Concat("/", configPath, LIMIT_MAX_PATH_BYTES, "apps", appNamePtr, (char*)NULL) != LE_OK, "Buffer size too small."); app_Init(); appRef = app_Create(configPath); LE_FATAL_IF(appRef == NULL, "There was an error when getting app info for '%s'.", appNamePtr); return appRef; }
//-------------------------------------------------------------------------------------------------- static le_clk_Time_t GetConfigKickTimeoutInterval ( pid_t procId, ///< The process id of the client uid_t appId ///< The user id of the application ) { char appName[LIMIT_MAX_APP_NAME_BYTES] = ""; char procName[LIMIT_MAX_PROCESS_NAME_BYTES] = ""; char configPath[LIMIT_MAX_PATH_BYTES] = ""; const int defaultTimeout = TIMEOUT_DEFAULT; int proc_milliseconds = CFG_TIMEOUT_USE_DEFAULT; int app_milliseconds = CFG_TIMEOUT_USE_DEFAULT; if (LE_OK == user_GetAppName(appId, appName, sizeof(appName) )) { // Check if there is a config for the process name first else check under the app name // It's a real app. Let's look up the config! LE_DEBUG("Getting configured watchdog timeout for app %s", appName); if (le_path_Concat("/", configPath, sizeof(configPath), "apps", appName, "watchdogTimeout", NULL) == LE_OK) { app_milliseconds = le_cfg_QuickGetInt(configPath, CFG_TIMEOUT_USE_DEFAULT); } if (LE_OK == GetProcessNameFromPid( procId, procName, sizeof(procName))) { // get the config configPath[0]='\0'; LE_DEBUG("Getting configured watchdog timeout for process %s", procName); if(le_path_Concat("/", configPath, sizeof(configPath), "apps", appName, "procs", procName, "watchdogTimeout", NULL) == LE_OK) { proc_milliseconds = le_cfg_QuickGetInt(configPath, CFG_TIMEOUT_USE_DEFAULT); } } // find a valid value starting at proc level and working up if (proc_milliseconds == CFG_TIMEOUT_USE_DEFAULT) { if (app_milliseconds == CFG_TIMEOUT_USE_DEFAULT) { proc_milliseconds = defaultTimeout; LE_WARN("No watchdog timeout configured for %s - using default %d ms", appName, proc_milliseconds); } else { proc_milliseconds = app_milliseconds; LE_INFO("No watchdog timeout configured for process %s - using app timeout %d ms", procName, proc_milliseconds); } } else { LE_DEBUG("Watchdog timeout configured for %s - timeout %d ms", procName, proc_milliseconds); } } else { // We have no idea what process is calling us, but we can set a default timeout // and play along. // TODO: Find a way to get the configured watchdog timeout duration for unsandboxed // apps, which run as root. proc_milliseconds = defaultTimeout; LE_WARN("Unknown app with uid %u requested watchdog - using default timeout %d ms", appId, proc_milliseconds); } return MakeTimerInterval(proc_milliseconds); }
static void TestConcatenation(void) { LE_INFO("======== Test Concatenations."); { char buf[100] = "hello/"; le_result_t result = le_path_Concat("/", buf, sizeof(buf), "there", "how/", "/are", "/you/", (char*)NULL); LE_TEST((result == LE_OK) && (strcmp(buf, "hello/there/how/are/you/") == 0)); } { char buf[100] = "/hello//"; le_result_t result = le_path_Concat("/", buf, sizeof(buf), "there", "how/", "//are", "//you", (char*)NULL); LE_TEST((result == LE_OK) && (strcmp(buf, "/hello/there/how/are/you") == 0)); } { char buf[100] = ""; le_result_t result = le_path_Concat("/", buf, sizeof(buf), "hello", "there", "how/", "/are", "/you/", (char*)NULL); LE_TEST((result == LE_OK) && (strcmp(buf, "hello/there/how/are/you/") == 0)); } { char buf[100] = "/"; le_result_t result = le_path_Concat("/", buf, sizeof(buf), "/", "//", (char*)NULL); LE_TEST((result == LE_OK) && (strcmp(buf, "/") == 0)); } { char buf[100] = ""; le_result_t result = le_path_Concat("/", buf, sizeof(buf), "/", "//", (char*)NULL); LE_TEST((result == LE_OK) && (strcmp(buf, "/") == 0)); } { char buf[100] = "__"; le_result_t result = le_path_Concat("__", buf, sizeof(buf), "__", "____", (char*)NULL); LE_TEST((result == LE_OK) && (strcmp(buf, "__") == 0)); } { char buf[100] = ""; le_result_t result = le_path_Concat("__", buf, sizeof(buf), "__", "____", (char*)NULL); LE_TEST((result == LE_OK) && (strcmp(buf, "__") == 0)); } { char buf[100] = "__hello___"; le_result_t result = le_path_Concat("__", buf, sizeof(buf), "there", "how__", "_____are", "____you", (char*)NULL); LE_TEST((result == LE_OK) && (strcmp(buf, "__hello___there__how___are__you") == 0)); } { // Test overflow. char buf[35] = ""; le_result_t result = le_path_Concat("__", buf, sizeof(buf), "__hello___", "there", "how__", "_____are", "____you_doing", (char*)NULL); LE_TEST((result == LE_OVERFLOW) && (strcmp(buf, "__hello___there__how___are__you_do") == 0)); } { // Test overflow on the separator boundary. char buf[35] = ""; le_result_t result = le_path_Concat("__", buf, sizeof(buf), "__hello___", "there", "how__", "_____are_you_do", "__ing", (char*)NULL); LE_TEST((result == LE_OVERFLOW) && (strcmp(buf, "__hello___there__how___are_you_do") == 0)); } { // Test no segments. char buf[100] = ""; le_result_t result = le_path_Concat("__", buf, sizeof(buf), (char*)NULL); LE_TEST((result == LE_OK) && (strcmp(buf, "") == 0)); } { // Test single segment. char buf[100] = ""; le_result_t result = le_path_Concat("__", buf, sizeof(buf), "__h___", (char*)NULL); LE_TEST((result == LE_OK) && (strcmp(buf, "__h___") == 0)); } { char buf[100] = "/"; le_result_t result = le_path_Concat("/", buf, sizeof(buf), "h", "", "i/", (char*)NULL); LE_TEST((result == LE_OK) && (strcmp(buf, "/h/i/") == 0)); } { char buf[100] = "////"; le_result_t result = le_path_Concat("/", buf, sizeof(buf), "h", "/", "/i/", (char*)NULL); LE_TEST((result == LE_OK) && (strcmp(buf, "/h/i/") == 0)); } { char buf[100] = "h***"; le_result_t result = le_path_Concat("***", buf, sizeof(buf), "i", (char*)NULL); LE_TEST((result == LE_OK) && (strcmp(buf, "h***i") == 0)); } { char buf[100] = "***h***"; le_result_t result = le_path_Concat("***", buf, sizeof(buf), "***i", (char*)NULL); LE_TEST((result == LE_OK) && (strcmp(buf, "***h***i") == 0)); } }
//-------------------------------------------------------------------------------------------------- static void ListEntries ( void ) { // Iterate over the Path and print the values to stdout. secStoreAdmin_IterRef_t iterRef = secStoreAdmin_CreateIter(Path); if (iterRef != NULL) { while (secStoreAdmin_Next(iterRef) == LE_OK) { bool isDir; char entryName[SECSTOREADMIN_MAX_PATH_BYTES]; if (secStoreAdmin_GetEntry(iterRef, entryName, sizeof(entryName), &isDir) == LE_OK) { char sizeStr[100] = ""; // See if we have to print the entry size. if (ListSizeFlag) { // Get the entry size. char fullPath[SECSTOREADMIN_MAX_PATH_BYTES] = ""; if (le_path_Concat("/", fullPath, sizeof(fullPath), Path, entryName, NULL) != LE_OK) { INTERNAL_ERR("Secure storage path for entry '%s' is too long.", entryName); } uint64_t size; le_result_t r = secStoreAdmin_GetSize(fullPath, &size); if (r != LE_OK) { LE_ERROR("Could not get size for secure storage item '%s'. Result code %s.", fullPath, LE_RESULT_TXT(r)); snprintf(sizeStr, sizeof(sizeStr), "%s", "unknown"); } else { snprintf(sizeStr, sizeof(sizeStr), "%" PRIu64, size); } printf("%-12s %s", sizeStr, entryName); } else { printf("%s", entryName); } if (isDir) { printf("/\n"); } else { printf("\n"); } } else { break; } } } else { fprintf(stderr, "Could not list entries. Path may be malformed.\n"); exit(EXIT_FAILURE); } }