/** * seccore_exefileg_target - file target execute. * @pHeader: header pointer * @pFileGData: file access data pointer * * This function is file guard target execute. * * return infomation * struct Header*:update header pointer */ static struct Header* seccore_exefileg_target(struct Header *pHeader, struct FileGData *pFileGData) { while (IS_TARGET(pHeader->mType)) { int size = 0; struct PolicyFileGTarget *pTarget; pTarget = (struct PolicyFileGTarget *)pHeader; switch (pTarget->mHeader.mType) { case POLICY_FILE_TARGET_TYPE_FULLPATH: pFileGData->mTarget.mCheckMask |= FILEGDATA_TARGET_CHECKMASK_FULLPATH; size = pTarget->mData.mFullPath.mSize; pFileGData->mTarget.mpPath = secfunc_malloc(size + 1); if (pFileGData->mTarget.mpPath != NULL) { secfunc_memset(pFileGData->mTarget.mpPath, 0, size + 1); secfunc_memcpy(pFileGData->mTarget.mpPath, pTarget->mData.mFullPath.mPath, size); size = sizeof(struct Header) + sizeof(pTarget->mData.mFullPath.mSize) + pTarget->mData.mFullPath.mSize; } else { pHeader = NULL; } break; case POLICY_FILE_TARGET_TYPE_FOLDERPATH: pFileGData->mTarget.mCheckMask |= FILEGDATA_TARGET_CHECKMASK_FOLDERPATH; size = pTarget->mData.mFolderPath.mSize; pFileGData->mTarget.mpPath = secfunc_malloc(size + 1); if (pFileGData->mTarget.mpPath != NULL) { secfunc_memset(pFileGData->mTarget.mpPath, 0, size + 1); secfunc_memcpy(pFileGData->mTarget.mpPath, pTarget->mData.mFolderPath.mPath, size); size = sizeof(struct Header) + sizeof(pTarget->mData.mFolderPath.mSize) + pTarget->mData.mFolderPath.mSize; } else { pHeader = NULL; } break; } if (pHeader == NULL) break; /* header shift */ pHeader = seccore_nextheader(pHeader, size); } return pHeader; }
/** * 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_extenddata - extend data. * @pArray: data pointer * @srcSize: data size * @addSize: additional data size * * This function is data extened. * * return infomation * char*: extend pointer */ static char* seccore_extenddata(char *pArray, int srcSize, int addSize) { char *p = secfunc_malloc(srcSize + addSize); if (p != NULL) { secfunc_memset(p, 0, srcSize+addSize); if (pArray != NULL && srcSize != 0) secfunc_memcpy(p, pArray, srcSize); } return p; }
/** * seccore_exeprocg_target - process target execute. * @pHeader: header data pointer * @pProcGData: process access data pointer * * This function is process guard target execute. * * return infomation * struct Header*:update header pointer */ static struct Header* seccore_exeprocg_target(struct Header *pHeader, struct ProcGData *pProcGData) { while (IS_TARGET(pHeader->mType)) { int size = 0; struct PolicyProcGTarget *pTarget; pTarget = (struct PolicyProcGTarget *)pHeader; switch (pTarget->mHeader.mType) { case POLICY_PROC_TARGET_TYPE_COMMANDNAME: pProcGData->mTarget.mCheckMask |= PROCGDATA_TARGET_CHECKMASK_COMMANDNAME; size = pTarget->mData.mCommandName.mSize; pProcGData->mTarget.mCmdLength = pTarget->mData.mCommandName.mSize; pProcGData->mTarget.mpCmdLine = secfunc_malloc(pProcGData->mTarget.mCmdLength + 1); if (pProcGData->mTarget.mpCmdLine != NULL) { secfunc_memset(pProcGData->mTarget.mpCmdLine, 0, pProcGData->mTarget.mCmdLength + 1); secfunc_memcpy(pProcGData->mTarget.mpCmdLine, &pTarget->mData.mCommandName.mName[0], pProcGData->mTarget.mCmdLength); size = sizeof(struct Header) + sizeof(pTarget->mData.mCommandName.mSize) + pTarget->mData.mCommandName.mSize; } else { pHeader = NULL; } break; case POLICY_PROC_TARGET_TYPE_UID: pProcGData->mTarget.mCheckMask |= PROCGDATA_TARGET_CHECKMASK_UID; pProcGData->mTarget.mUid = pTarget->mData.mUid.mUid; size = sizeof(struct Header) + sizeof(pTarget->mData.mUid.mUid); break; } if (pHeader == NULL) break; /* header shift */ pHeader = seccore_nextheader(pHeader, size); } return pHeader; }
/** * 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; }
/** * seccore_parsecaller - caller data prase. * @pAccessData: access data pointer * @pCaller: caller policy data pointer * * This function is caller policy prase. * * return infomation * int: update caller policy data size */ static int seccore_parsecaller(struct Caller *pAccessData, struct PolicyCaller *pCaller) { int size = 0; switch (pCaller->mHeader.mType) { case POLICY_CALLER_TYPE_COMMANDNAME: pAccessData->mCheckMask |= CALLER_CHECKMASK_COMMANDNAME; size = pCaller->mData.mCommandName.mSize; pAccessData->mCmdLength = pCaller->mData.mCommandName.mSize; pAccessData->mpCmdLine = secfunc_malloc(pAccessData->mCmdLength + 1); if (pAccessData->mpCmdLine != NULL) { secfunc_memset(pAccessData->mpCmdLine, 0, pAccessData->mCmdLength + 1); secfunc_memcpy(pAccessData->mpCmdLine, pCaller->mData.mCommandName.mName, pAccessData->mCmdLength); size = sizeof(struct Header) + sizeof(pCaller->mData.mCommandName.mSize) + pCaller->mData.mCommandName.mSize; } break; case POLICY_CALLER_TYPE_UID_ONE: pAccessData->mCheckMask |= CALLER_CHECKMASK_UID; pAccessData->mCallerUid.mCheckMask |= CALLER_CHECKMASK_UID_ONE; pAccessData->mCallerUid.mUid = pCaller->mData.mUidOne.mUid; size = sizeof(struct Header) + sizeof(pCaller->mData.mUidOne.mUid); break; case POLICY_CALLER_TYPE_UID_LESS: pAccessData->mCheckMask |= CALLER_CHECKMASK_UID; pAccessData->mCallerUid.mCheckMask |= CALLER_CHECKMASK_UID_LESS; pAccessData->mCallerUid.mUid_Less = pCaller->mData.mUidLess.mUid; size = sizeof(struct Header) + sizeof(pCaller->mData.mUidLess.mUid); break; case POLICY_CALLER_TYPE_UID_MORE: pAccessData->mCheckMask |= CALLER_CHECKMASK_UID; pAccessData->mCallerUid.mCheckMask |= CALLER_CHECKMASK_UID_MORE; pAccessData->mCallerUid.mUid_More = pCaller->mData.mUidMore.mUid; size = sizeof(struct Header) + sizeof(pCaller->mData.mUidMore.mUid); break; case POLICY_CALLER_TYPE_GID_ONE: pAccessData->mCheckMask |= CALLER_CHECKMASK_GID; pAccessData->mCallerGid.mCheckMask |= CALLER_CHECKMASK_GID_ONE; pAccessData->mCallerGid.mGid = pCaller->mData.mGidOne.mGid; size = sizeof(struct Header) + sizeof(pCaller->mData.mGidOne.mGid); break; case POLICY_CALLER_TYPE_GID_LESS: pAccessData->mCheckMask |= CALLER_CHECKMASK_GID; pAccessData->mCallerGid.mCheckMask |= CALLER_CHECKMASK_GID_LESS; pAccessData->mCallerGid.mGid_Less = pCaller->mData.mGidLess.mGid; size = sizeof(struct Header) + sizeof(pCaller->mData.mGidLess.mGid); break; case POLICY_CALLER_TYPE_GID_MORE: pAccessData->mCheckMask |= CALLER_CHECKMASK_GID; pAccessData->mCallerGid.mCheckMask |= CALLER_CHECKMASK_GID_MORE; pAccessData->mCallerGid.mGid_More = pCaller->mData.mGidMore.mGid; size = sizeof(struct Header) + sizeof(pCaller->mData.mGidMore.mGid); break; case POLICY_CALLER_TYPE_PID_ONE: pAccessData->mCheckMask |= CALLER_CHECKMASK_PID; pAccessData->mCallerPid.mCheckMask |= CALLER_CHECKMASK_PID_ONE; pAccessData->mCallerPid.mPid = pCaller->mData.mPidOne.mPid; size = sizeof(struct Header) + sizeof(pCaller->mData.mPidOne.mPid); break; case POLICY_CALLER_TYPE_PID_LESS: pAccessData->mCheckMask |= CALLER_CHECKMASK_PID; pAccessData->mCallerPid.mCheckMask |= CALLER_CHECKMASK_PID_LESS; pAccessData->mCallerPid.mPid_Less = pCaller->mData.mPidLess.mPid; size = sizeof(struct Header) + sizeof(pCaller->mData.mPidLess.mPid); break; case POLICY_CALLER_TYPE_PID_MORE: pAccessData->mCheckMask |= CALLER_CHECKMASK_PID; pAccessData->mCallerPid.mCheckMask |= CALLER_CHECKMASK_PID_MORE; pAccessData->mCallerPid.mPid_More = pCaller->mData.mPidMore.mPid; size = sizeof(struct Header) + sizeof(pCaller->mData.mPidMore.mPid); break; case POLICY_CALLER_TYPE_ALL_DENIAL: pAccessData->mCheckMask |= CALLER_CHECKMASK_ALL_DENIAL; size = sizeof(struct Header); break; default: SECERROR("Unknown Type=%08X", pCaller->mHeader.mType); break; } return size; }