/** * seccore_exefileguarddata - file target execute. * @pData: file access guard policy data pointer * @size: file access guard policy data size * * This function is file file target execute. * * return infomation * true:execute success * false:execute failed */ bool seccore_exefileguarddata(const char *pData, size_t size) { bool result = true; int targetSetIndex=-1; struct Header* pHeader = (struct Header*)(pData); struct FileGData **ppUpdateData = NULL; struct FileGData *pFileGData = NULL; struct FileGData **ppWork = NULL; while (!IS_NONDATA(pHeader->mType)) { targetSetIndex++; /* memory extend */ ppWork = (struct FileGData**)seccore_extenddata( (char *)ppUpdateData, sizeof(struct FileGData *) * (targetSetIndex + 1), sizeof(struct FileGData *)); if (ppWork == NULL) { result = false; break; } if (ppUpdateData != NULL) secfunc_free(ppUpdateData); ppUpdateData = ppWork; /* memory extend add target data */ pFileGData = secfunc_malloc(sizeof(struct FileGData)); if (pFileGData == NULL) { result = false; break; } secfunc_memset(pFileGData, 0, sizeof(struct FileGData)); ppUpdateData[targetSetIndex] = pFileGData; /* read target conditions */ pHeader = seccore_exefileg_target(pHeader, pFileGData); if (pHeader == NULL) { result = false; break; } /* read caller conditions */ result = seccore_execaller(pHeader, &pFileGData->mCallers, &pHeader); if (result == false) break; } if (result) { /* update data */ secpolicy_updatefileguarddata(ppUpdateData); } else { /* release data */ secpolicy_releasefileguarddata(ppUpdateData); } return result; }
/** * seccore_callerchk - caller check * @pCaller: caller infomation pointer * @pCallProcInfo: caller process infomation pointer * * This function is caller check. * * return infomation * true:check result OK * false:check result NG */ static bool seccore_callerchk(struct Caller *pCaller, struct ProcessInfo *pCallProcInfo, int parentPos) { bool result = false; /* default check result is false */ if (!(pCaller->mCheckMask & CALLER_CHECKMASK_ALL_DENIAL)) { bool cmdChk = true; bool uidChk = true; bool gidChk = true; bool pidChk = true; bool parentChk = true; /* command check */ if (pCaller->mCheckMask & CALLER_CHECKMASK_COMMANDNAME) cmdChk = seccore_callerchk_command(pCaller, pCallProcInfo); /* UID check */ if ((pCaller->mCheckMask & CALLER_CHECKMASK_UID) && cmdChk) uidChk = seccore_callerchk_uid(&pCaller->mCallerUid, pCallProcInfo); /* GID check */ if ((pCaller->mCheckMask & CALLER_CHECKMASK_GID) && cmdChk && uidChk) gidChk = seccore_callerchk_gid(&pCaller->mCallerGid, pCallProcInfo); /* PID check */ if ((pCaller->mCheckMask & CALLER_CHECKMASK_PID) && cmdChk && uidChk && gidChk) pidChk = seccore_callerchk_pid(&pCaller->mCallerPid, pCallProcInfo); /* parent cheack */ if ((pCaller->mCheckMask & CALLER_CHECKMASK_PARENT) && cmdChk && uidChk && gidChk && pidChk) { struct ProcessInfo procInfo; parentPos++; if (secfunc_getcallprocinfo(&procInfo, parentPos)) { /* parent caller check */ parentChk = seccore_callerchk(pCaller->mParent, &procInfo, parentPos); secfunc_free(procInfo.mpCmdLine); } else { /* Error. cant get parent caller infomation */ parentChk = false; } } if (cmdChk && uidChk && gidChk && pidChk && parentChk) result = true; } return result; }
/** * seccore_callerschk - caller condition check * @pCallers: callers infomation pointer * * This function is caller conditioin check. * * return infomation * true:check result OK * false:check result NG */ static bool seccore_callerschk(struct Callers *pCallers) { bool result = false; struct ProcessInfo procInfo; int i; if (secfunc_getcallprocinfo(&procInfo, 0)) { for (i = 0; i < pCallers->mMax; i++) { result = seccore_callerchk(&pCallers->mpCaller[i], &procInfo, 0); if (result == true) { result = true; break; } } secfunc_free(procInfo.mpCmdLine); } return result; }
/** * secpolicy_releasefileguarddata - release file access guard data. * @ppUpdateData: file access data pointer * * This function is to release process access guard data. * */ void secpolicy_releasefileguarddata(struct FileGData **ppReleaseData) { struct FileGData **ppData = ppReleaseData; if ((ppReleaseData != NULL) && (ppReleaseData != gpfileg_data_empty)) { while(*ppData != NULL) { int i; struct FileGData *pData = *ppData; /* free target data */ if (pData->mTarget.mpPath != NULL) { secfunc_free(pData->mTarget.mpPath); pData->mTarget.mpPath = NULL; } /* free caller data */ for (i = 0; i < pData->mCallers.mMax; i++) { /* free parent data */ struct Caller *pParentCaller; if (pData->mCallers.mpCaller[i].mpCmdLine != NULL) secfunc_free(pData->mCallers.mpCaller[i].mpCmdLine); pParentCaller = pData->mCallers.mpCaller[i].mParent; while(pParentCaller != NULL) { struct Caller *pWorkCaller = NULL; pWorkCaller = pParentCaller->mParent; secfunc_free(pParentCaller); pParentCaller = pWorkCaller; } } if (i != 0) { secfunc_free(pData->mCallers.mpCaller); pData->mCallers.mpCaller = NULL; } /* free data */ secfunc_free(*ppData); *ppData = NULL; ppData++; } secfunc_free(ppReleaseData); } }
/** * secfs_ctl_write - control file write * @file: file pointer * @buf: write data pointer * @count: write data size * @ppos: loff_t pointer * * This function is control file write. * SECFS_FILENAME_CONTROL * * return infomation * ssize_t:write success size */ static ssize_t secfs_ctl_write( struct file *file, const char __user *buf, size_t count, loff_t *ppos) { bool bret = false; char *pData; int idx; idx = secfunc_lock(); pData = (char *)secfunc_malloc(count); if (pData != NULL) { if (copy_from_user(pData, buf, count) == 0) bret = seccore_exectldata(pData, count); secfunc_free(pData); } secfunc_unlock(idx); return count; }
/** * seccore_execaller - caller data execute. * @pHeader: header data pointer * @pCallers: callers data pointer * @ppNextHeader: next caller header pointer * * This function is caller execute. * * return infomation * true:execute success * false:execute failed */ static bool seccore_execaller(struct Header *pHeader, struct Callers *pCallers, struct Header **ppNextHeader) { bool result = true; struct Caller *pSetCaller = NULL; while (true) { if (pHeader->mType == SEPARATE_NEXT) { /* header shift */ pHeader = seccore_nextheader(pHeader, sizeof(struct Header)); if (IS_CALLER(pHeader->mType)) { /* memory extended */ struct Caller* pCaller; pCallers->mMax++; pCaller = (struct Caller *)seccore_extenddata( (char *)pCallers->mpCaller, sizeof(struct Caller) * pCallers->mMax, sizeof(struct Caller)); if (pCaller == NULL) { result = false; break; } if (pCallers->mpCaller != NULL) secfunc_free(pCallers->mpCaller); pCallers->mpCaller = pCaller; pSetCaller = &pCallers->mpCaller[pCallers->mMax - 1]; } else if (IS_TARGET(pHeader->mType)) { break; } } else if (pHeader->mType == SEPARATE_PARENT) { struct Caller* pWorkCaller = pSetCaller; if (pSetCaller == NULL) { result = false; break; } pSetCaller->mCheckMask |= CALLER_CHECKMASK_PARENT; /* header shift */ pHeader = seccore_nextheader(pHeader, sizeof(struct Header)); /* parent data set */ pSetCaller = secfunc_malloc(sizeof(struct Caller)); if (pSetCaller == NULL) { result = false; break; } secfunc_memset(pSetCaller, 0, sizeof(struct Caller)); pWorkCaller->mParent = pSetCaller; } else if (IS_NONDATA(pHeader->mType)) { /* end */ break; } /* read caller condifions */ while (IS_CALLER(pHeader->mType)) { int size; struct PolicyCaller* pCaller; pCaller = (struct PolicyCaller *)pHeader; size = seccore_parsecaller(pSetCaller, pCaller); if (size == 0) break; /* header shift */ pHeader = seccore_nextheader(pHeader, size); } if (IS_CALLER(pHeader->mType)) { result = false; break; } } *ppNextHeader = pHeader; return result; }