Add audit-trail rule verification tool 44/177144/12
authoryeji01.kim <yeji01.kim@samsung.com>
Thu, 26 Apr 2018 00:28:51 +0000 (09:28 +0900)
committerSungbae Yoo <sungbae.yoo@samsung.com>
Wed, 9 May 2018 11:33:57 +0000 (11:33 +0000)
Change-Id: Ic637e71f53629273fd440afcdd6a78dccfd89995
Signed-off-by: yeji01.kim <yeji01.kim@samsung.com>
14 files changed:
packaging/audit-trail.spec
tools/tests/CMakeLists.txt
tools/tests/data/test_module.ko [new file with mode: 0644]
tools/tests/groups/account.cpp [new file with mode: 0644]
tools/tests/groups/audit.cpp [new file with mode: 0644]
tools/tests/groups/file.cpp [new file with mode: 0644]
tools/tests/groups/group.cpp [new file with mode: 0644]
tools/tests/groups/group.h [new file with mode: 0644]
tools/tests/groups/ipc.cpp [new file with mode: 0644]
tools/tests/groups/mac.cpp [new file with mode: 0644]
tools/tests/groups/network.cpp [new file with mode: 0644]
tools/tests/groups/system.cpp [new file with mode: 0644]
tools/tests/groups/time.cpp [new file with mode: 0644]
tools/tests/rule_verification.cpp [new file with mode: 0644]

index 5e0f677eca6283a5cb89108c04e096d2fc609d53..80c6a03d12c4a59020f141f63bb6f19dfddbc3c9 100755 (executable)
@@ -144,3 +144,5 @@ The audit-trail-tests package contains the testcases needed to test audit functi
 %defattr(644,root,root,755)
 %attr(700,root,root) %{_sbindir}/audit-trail-send-test
 %attr(700,root,root) %{_sbindir}/audit-trail-speed-test
+%attr(700,root,root) %{_sbindir}/audit-trail-rules-test
+%{audit_base_dir}/test_module.ko
\ No newline at end of file
index 004797fd70a6042f44c458408c90c1785e903ab5..d442f6ab03ebfc4a6143f9463924f1e9ff8e081d 100644 (file)
 
 FILE(GLOB SEND_SRCS            send.cpp)
 FILE(GLOB SPEED_SRCS   speed.cpp)
+SET(RULES_SRCS                 rule_verification.cpp
+                                               groups/group.cpp
+                                               groups/audit.cpp
+                                               groups/file.cpp
+                                               groups/mac.cpp
+                                               groups/ipc.cpp
+                                               groups/system.cpp
+                                               groups/time.cpp
+                                               groups/account.cpp
+                                               groups/network.cpp
+)
 
 SET(SEND_NAME ${PROJECT_NAME}-send-test)
 SET(SPEED_NAME ${PROJECT_NAME}-speed-test)
+SET(RULES_NAME ${PROJECT_NAME}-rules-test)
 
 ADD_EXECUTABLE(${SEND_NAME} ${SEND_SRCS})
 ADD_EXECUTABLE(${SPEED_NAME} ${SPEED_SRCS})
+ADD_EXECUTABLE(${RULES_NAME} ${RULES_SRCS})
 
 
 SET_TARGET_PROPERTIES(${SEND_NAME} PROPERTIES PREFIX ""
@@ -38,8 +51,10 @@ PKG_CHECK_MODULES(CLI_DEPS   REQUIRED
                                                        glib-2.0
 )
 
-INCLUDE_DIRECTORIES(SYSTEM ${CLI_DEPS_INCLUDE_DIRS} ${AUDIT_TRAIL_LIB})
+INCLUDE_DIRECTORIES(SYSTEM ${CLI_DEPS_INCLUDE_DIRS} ${AUDIT_TRAIL_LIB} groups)
 TARGET_LINK_LIBRARIES(${SPEED_NAME} ${CLI_DEPS_LIBRARIES} ${PROJECT_NAME} audit-trail)
 
 INSTALL(TARGETS ${SEND_NAME} DESTINATION sbin)
 INSTALL(TARGETS ${SPEED_NAME} DESTINATION sbin)
+INSTALL(TARGETS ${RULES_NAME} DESTINATION sbin)
+INSTALL(FILES data/test_module.ko DESTINATION ${DATA_INSTALL_DIR})
diff --git a/tools/tests/data/test_module.ko b/tools/tests/data/test_module.ko
new file mode 100644 (file)
index 0000000..5c846f9
Binary files /dev/null and b/tools/tests/data/test_module.ko differ
diff --git a/tools/tests/groups/account.cpp b/tools/tests/groups/account.cpp
new file mode 100644 (file)
index 0000000..ce0f834
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "group.h"
+
+class AccountGroup : public AbstractGroup {
+public:
+       AccountGroup(const std::string& name) :
+               AbstractGroup(name)
+       {
+       }
+
+       void run()
+       {
+               Display::printResult(Display::NONE, "Account group test start");
+               loginAccounts();
+               createDestroyAccounts();
+               useSetuid();
+       }
+
+       virtual ~AccountGroup()
+       {
+       }
+
+       void loginAccounts() {
+               std::vector<std::string> testfiles;
+
+               testfiles.emplace_back("/var/run/utmp");
+               testfiles.emplace_back("/var/log/btmp");
+               testfiles.emplace_back("/var/log/wtmp");
+
+               for (auto entry : testfiles) {
+                       struct stat st;
+                       std::string logStr(entry + " change");
+                       lstat(entry.c_str(), &st);
+                       chmod(entry.c_str(), st.st_mode);
+                       Display::printResult(Display::SUCCESS, logStr);
+               }
+       }
+
+       void createDestroyAccounts() {
+               std::vector<std::string> commands;
+
+               commands.emplace_back("groupadd audit-test -g 7777");
+               commands.emplace_back("groupdel audit-test");
+
+               for (auto entry : commands) {
+                       if (system(entry.c_str()) == -1) {
+                               Display::printError();
+                               Display::printResult(Display::FAIL, entry);
+                       } else {
+                               Display::printResult(Display::SUCCESS, entry);
+                       }
+               }
+       }
+
+       void useSetuid() {
+               int ret;
+               //setuid(23) system call positive
+               {
+                       uid_t originUid = getuid();
+
+                       if (setuid(originUid) == -1) {
+                               Display::printError();
+                               ret = Display::FAIL;
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "setuid(23) positive");
+               }
+
+               //setresuid(164) system call positive
+               {
+                       uid_t ruid, euid, suid;
+
+                       if (getresuid(&ruid, &euid, &suid) == -1) {
+                               Display::printError();
+                               ret = Display::FAIL;
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+
+                       if (setresuid(ruid, euid, suid) == -1) {
+                               Display::printError();
+                               ret = Display::FAIL;
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "setresuid(164) positive");
+               }
+       }
+};
+
+GroupBuilder<AccountGroup> accountGroup("Account");
diff --git a/tools/tests/groups/audit.cpp b/tools/tests/groups/audit.cpp
new file mode 100644 (file)
index 0000000..3210cdc
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "group.h"
+
+class AuditGroup : public AbstractGroup {
+public:
+       AuditGroup(const std::string& name) :
+               AbstractGroup(name)
+       {
+       }
+
+       void run()
+       {
+               Display::printResult(Display::NONE, "Audit group test start");
+               accessAuditSocketFile();
+       }
+
+       virtual ~AuditGroup()
+       {
+       }
+
+       void accessAuditSocketFile() {
+               int fd = -1;
+               std::string auditSocketPath("/tmp/.audit-trail.sock");
+               fd = open(auditSocketPath.c_str(), O_RDWR);
+               if (fd > 0)
+                       close(fd);
+
+               Display::printResult(Display::SUCCESS, "accessAuditSocketFile");
+       }
+};
+
+GroupBuilder<AuditGroup> auditGroup("Audit");
diff --git a/tools/tests/groups/file.cpp b/tools/tests/groups/file.cpp
new file mode 100644 (file)
index 0000000..492e9f7
--- /dev/null
@@ -0,0 +1,629 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/xattr.h>
+
+#include "group.h"
+
+class FileGroup : public AbstractGroup {
+public:
+       FileGroup(const std::string& name) :
+               AbstractGroup(name)
+       {
+       }
+
+       void run()
+       {
+               Display::printResult(Display::NONE, "File group test start");
+               accessFiles();
+               destroyFile();
+               createLink();
+               changeFileConfDAC();
+               changeFileConfMAC();
+       }
+
+       virtual ~FileGroup()
+       {
+       }
+
+       void accessFiles() {
+               int fd, ret;
+               std::string fileName("/tmp/audit-test");
+
+               //open(5) system call positive
+               {
+                       if ((fd = open(fileName.c_str(), O_CREAT|O_RDONLY, 0644)) < 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               close(fd);
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "open(5) positive");
+               }
+
+               //openat(322) system call positive
+               {
+                       int pathFd;
+                       if ((pathFd = open("/tmp", O_PATH)) < 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                               goto openat_result;
+                       }
+
+                       if ((fd = openat(pathFd, "audit-test", O_CREAT|O_RDONLY, 0644)) < 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               close(fd);
+                               ret = Display::SUCCESS;
+                       }
+                       close(pathFd);
+
+               openat_result:
+                       Display::printResult(ret, "openat(322) positive");
+               }
+
+               //creat(8) system call positive
+               {
+                       if ((fd = creat(fileName.c_str(), 0644)) < 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               close(fd);
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "creat(8) positive");
+               }
+
+               //open_by_handle_at(371) system call positive
+               {
+                       struct file_handle *handle = NULL;
+                       int mntId;
+                       int mountFd = -1;
+
+                       handle = (struct file_handle *)malloc(sizeof(struct file_handle));
+                       if (handle == NULL) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                               goto open_by_handle_at_result;
+                       }
+
+                       handle->handle_bytes = 0;
+                       if (name_to_handle_at(AT_FDCWD, fileName.c_str(), handle, &mntId, 0) != -1 || errno != EOVERFLOW) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                               goto open_by_handle_at_result;
+                       }
+
+                       handle = (struct file_handle *)realloc(handle, (sizeof(struct file_handle) + handle->handle_bytes));
+                       if (handle == NULL) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                               goto open_by_handle_at_result;
+                       }
+
+                       if (name_to_handle_at(AT_FDCWD, fileName.c_str(), handle, &mntId, 0) == -1) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                               goto open_by_handle_at_result;
+                       }
+                       if ((mountFd = open("/tmp", O_RDONLY)) < 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                               goto open_by_handle_at_result;
+                       }
+
+                       if ((fd = open_by_handle_at(mountFd, handle, O_RDONLY)) < 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                               close(fd);
+                       }
+
+               open_by_handle_at_result:
+                       if (handle)
+                               free(handle);
+                       if (mountFd > 0)
+                               close(mountFd);
+                       Display::printResult(ret, "open_by_handle_at(371) positive");
+               }
+
+               //truncate(92) system call positive
+               {
+                       if (truncate(fileName.c_str(), 10) < 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "truncate(92) positive");
+               }
+
+               //ftruncate(93) system call positive
+               {
+                       if ((fd = open(fileName.c_str(), O_WRONLY, 0644)) < 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                               goto ftruncate_result;
+                       }
+
+                       if (ftruncate(fd, 20) != 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       close(fd);
+
+               ftruncate_result:
+                       Display::printResult(ret, "ftruncate(93) positive");
+               }
+
+               //fallocate(352) system call positive
+               {
+                       if ((fd = open(fileName.c_str(), O_WRONLY, 0644)) < 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                               goto fallocate_result;
+                       }
+
+                       if (fallocate(fd, 0, 0, 30) < 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       close(fd);
+
+               fallocate_result:
+                       Display::printResult(ret, "fallocate(352) positive");
+               }
+
+               //restore
+               {
+                       struct stat st;
+                       if ((lstat(fileName.c_str(), &st) == 0) && (unlink(fileName.c_str()) != 0)) {
+                               Display::printError();
+                               Display::printResult(Display::FAIL, "accessFile restore");
+                       }
+               }
+       }
+
+       void destroyFile() {
+               //prepare
+               std::string fileName("/tmp/audit-test");
+               int ret;
+               int fd = creat(fileName.c_str(), 0644);
+               if (fd < 0) {
+                       Display::printResult(Display::FAIL, "destroyFile prepare");
+                       return;
+               }
+               close(fd);
+
+               //rename(38), renameat(329) system call positive
+               {
+                       std::string newName("/tmp/audit-test2");
+                       if (rename(fileName.c_str(), newName.c_str()) != 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "rename(38) positive");
+
+                       if (renameat(AT_FDCWD, newName.c_str(), AT_FDCWD, fileName.c_str()) != 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "renameat(329) positive");
+               }
+
+               //unlink(10) system call positive
+               {
+                       if (unlink(fileName.c_str()) != 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                               fd = -1;
+                       }
+                       Display::printResult(ret, "unlink(10) positive");
+               }
+
+               //unlinkat(328) system call positive
+               {
+                       if (fd < 0) {
+                               if ((fd = creat(fileName.c_str(), 0644)) < 0) {
+                                       ret = Display::FAIL;
+                                       Display::printError();
+                                       goto unlinkat_result;
+                               }
+                               close(fd);
+                       }
+
+                       if (unlinkat(AT_FDCWD, fileName.c_str(), 0) < 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+               unlinkat_result:
+                       Display::printResult(ret, "unlinkat(328) positive");
+               }
+
+               //restore
+               {
+                       struct stat st;
+                       if ((lstat(fileName.c_str(), &st) == 0) && (unlink(fileName.c_str()) != 0)) {
+                               Display::printError();
+                               Display::printResult(Display::FAIL, "destroyFile restore");
+                       }
+               }
+       }
+       void createLink() {
+               // prepare
+               std::string fileName("/tmp/audit-test");
+               int ret;
+               int fd = creat(fileName.c_str(), 0644);
+               if (fd < 0) {
+                       Display::printError();
+                       Display::printResult(Display::FAIL, "destroyFile prepare");
+                       return;
+               }
+
+               //link(9) system call positive
+               {
+                       std::string newPath("/tmp/audit-test-link");
+                       if (link(fileName.c_str(), newPath.c_str()) != 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "link(9) positive");
+
+                       if (unlink(newPath.c_str()) != 0)
+                               Display::printResult(Display::FAIL, "link positive restore");
+               }
+
+               //linkat(330) system call positive
+               {
+                       std::string newPath("/tmp/audit-test-linkat");
+                       if (linkat(AT_FDCWD, fileName.c_str(), AT_FDCWD, newPath.c_str(), 0) != 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "linkat(330) positive");
+
+                       if (unlink(newPath.c_str()) != 0)
+                               Display::printResult(Display::FAIL, "linkat positive restore");
+               }
+
+               //symlink(83) system call positive
+               {
+                       std::string linkPath("/tmp/audit-test-symlink");
+                       if (symlink(fileName.c_str(), linkPath.c_str()) != 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "symlink(83) positive");
+
+                       if (unlink(linkPath.c_str()) != 0)
+                               Display::printResult(Display::FAIL, "symlink positive restore");
+               }
+
+               //symlinkat(331) system call positive
+               {
+                       std::string linkPath("/tmp/audit-test-symlinkat");
+                       if (symlinkat(fileName.c_str(), AT_FDCWD, linkPath.c_str()) != 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "symlinkat(331) positive");
+
+                       if (unlink(linkPath.c_str()) != 0)
+                               Display::printResult(Display::FAIL, "symlinkat positive restore");
+               }
+
+               //mknod(14) system call positive
+               {
+                       std::string pathName("/tmp/audit-test-mknod");
+                       if (mknod(pathName.c_str(), 0664 | S_IFREG, 0) != 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "mknod(14) positive");
+
+                       if (unlink(pathName.c_str()) != 0)
+                               Display::printResult(Display::FAIL, "mknod positive restore");
+               }
+
+               //mknodat(324) system call positive
+               {
+                       std::string pathName("/tmp/audit-test-mknodat");
+                       if (mknodat(AT_FDCWD, pathName.c_str(), 0644|S_IFREG, 0) != 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "mknodat(324) positive");
+
+                       if (unlink(pathName.c_str()) != 0)
+                               Display::printResult(Display::FAIL, "mknodat positive restore");
+               }
+
+               //restore
+               {
+                       struct stat st;
+                       if (fd > 0)
+                               close(fd);
+                       if ((lstat(fileName.c_str(), &st) == 0) && (unlink(fileName.c_str()) != 0)) {
+                               Display::printError();
+                               Display::printResult(Display::FAIL, "createLink restore");\r
+                       }
+               }
+       }
+
+       void modifyDirectories() {
+               std::string mkdirPath("/tmp/audit-test-mkdir");
+               std::string mkdiratPath("/tmp/audit-test-mkdirat");
+               int ret;
+
+               //mkdir(39) system call positive
+               {
+                       if (mkdir(mkdirPath.c_str(), 0644) != 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "mkdir(39) positive");
+               }
+
+               //mkdirat(323) system call positive
+               {
+                       if (mkdirat(AT_FDCWD, mkdiratPath.c_str(), 0644) != 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "mkdirat(323) positive");
+               }
+
+               //rmdir(40) system call positive
+               {
+                       if (rmdir(mkdirPath.c_str()) != 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+
+                       if (rmdir(mkdiratPath.c_str()) != 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "rmdir(40) positive");
+               }
+       }
+
+       void changeFileConfDAC() {
+               //prepare
+               std::string fileName("/tmp/audit-test");
+               int ret;
+               int fd = creat(fileName.c_str(), 0644);
+               if (fd < 0) {
+                       Display::printResult(Display::FAIL, "changeFileConf prepare failed");
+                       return;
+               }
+               close(fd);
+
+               //chown(182) system call positive
+               {
+                       if (chown(fileName.c_str(), getuid(), getgid()) != 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "chown(182) positive");
+               }
+
+               //fchown(95) system call positive
+               {
+                       int fd = -1;
+                       fd = open(fileName.c_str(), O_RDONLY);
+                       if (fd < 0) {
+                               ret = Display::FAIL;
+                               goto fchown_result;
+                       }
+
+                       if (fchown(fd, getuid(), getgid()) != 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+
+                       close(fd);
+               fchown_result:
+                       Display::printResult(ret, "fchown(95) positive");
+               }
+
+               //fchownat(325) system call positive
+               {
+                       if (fchownat(AT_FDCWD, fileName.c_str(), getuid(), getgid(), 0) != 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "fchownat(325) positive");
+               }
+
+               //lchown(16) system call positive
+               {
+                       if (lchown(fileName.c_str(), getuid(), getgid()) != 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "lchown(16) positive");
+               }
+
+               //restore
+               {
+                       struct stat st;
+                       if ((lstat(fileName.c_str(), &st) == 0) && (unlink(fileName.c_str()) != 0)) {
+                               Display::printError();
+                               Display::printResult(Display::FAIL, "changeFileConf restore");
+                       }
+               }
+       }
+
+       void changeFileConfMAC() {
+               //prepare
+               std::string fileName("/opt/audit-test");
+               std::string testsetxattr("user.testsetxattr");
+               std::string testlsetxattr("user.testlsetxattr");
+               std::string testfsetxattr("user.testfsetxattr");
+
+               int ret;
+               int fd = creat(fileName.c_str(), 0644);
+               if (fd < 0) {
+                       Display::printResult(Display::FAIL, "changeFileConf prepare");
+                       return;
+               }
+               close(fd);
+
+               //setxattr(226), removexattr(235) system call positive
+               {
+                       std::string value("test setxattr");
+                       if (setxattr(fileName.c_str(), testsetxattr.c_str(), value.c_str(), value.size(), 0) != 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "setxattr(226) positive");
+
+                       if (removexattr(fileName.c_str(), testsetxattr.c_str()) != 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "removexattr(235) positive");
+               }
+
+               //lsetxattr(227), lremovexattr(236) system call positive
+               {
+                       std::string value("test lsetxattr");
+                       if (lsetxattr(fileName.c_str(), testlsetxattr.c_str(), value.c_str(), value.size(), 0) != 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "lsetxattr(227) positive");
+
+                       if (lremovexattr(fileName.c_str(), testlsetxattr.c_str()) != 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "lremovexattr(235) positive");
+               }
+
+               //fsetxattr(228) system call positive
+               {
+                       std::string value("test fsetxattr");
+                       int fd;
+                       fd = open(fileName.c_str(), O_RDONLY);
+                       if (fd < 0) {
+                               Display::printError();
+                               ret = Display::FAIL;
+                               goto fsetxattr_result;
+                       }
+                       if (fsetxattr(fd, testfsetxattr.c_str(), value.c_str(), value.size(), 0) != 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       close(fd);
+               fsetxattr_result:
+                       Display::printResult(ret, "fsetxattr(228) positive");
+               }
+
+               //fremovexattr(237) system call positive
+               {
+                       std::string value("test fsetxattr");
+                       int fd;
+                       fd = open(fileName.c_str(), O_RDONLY);
+                       if (fd < 0) {
+                               Display::printError();
+                               ret = Display::FAIL;
+                               goto fremovexattr_result;
+                       }
+                       if (fremovexattr(fd, testfsetxattr.c_str()) != 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       close(fd);
+               fremovexattr_result:
+                       Display::printResult(ret, "fremovexattr(237) positive");
+               }
+
+               //restore
+               {
+                       struct stat st;
+                       if ((lstat(fileName.c_str(), &st) == 0) && (unlink(fileName.c_str()) != 0)) {
+                               Display::printError();
+                               Display::printResult(Display::FAIL, "changeFileConfMAC restore");
+                       }
+               }
+       }
+};
+
+GroupBuilder<FileGroup> fileGroup("File");
diff --git a/tools/tests/groups/group.cpp b/tools/tests/groups/group.cpp
new file mode 100644 (file)
index 0000000..aa8bef0
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "group.h"
+
+std::vector<AbstractGroup *> managedGroup;
\ No newline at end of file
diff --git a/tools/tests/groups/group.h b/tools/tests/groups/group.h
new file mode 100644 (file)
index 0000000..2d5ad20
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __ABSTRACT_GROUP_H__
+#define __ABSTRACT_GROUP_H__
+
+#include <string.h>
+#include <errno.h>
+
+#include <vector>
+#include <iostream>
+#include <iomanip>
+
+class AbstractGroup {
+public:
+       virtual ~AbstractGroup() {}
+       virtual void run() = 0;
+protected:
+       AbstractGroup(const std::string& groupName) : name(groupName) { }
+
+public:
+       std::string name;
+};
+
+class Display {
+public:
+       enum Type {
+               NONE,
+               SUCCESS,
+               FAIL
+       };
+
+       static void printResult(int flag, const std::string& message) {
+               switch(flag) {
+               case NONE:
+                       std::cout << "\x1B[33m" << std::setw(9) << message;
+                       break;
+               case SUCCESS:
+                       std::cout << "\x1B[32m[" << std::setw(9) << "SUCCESS] " << message;
+                       break;
+               case FAIL:
+                       std::cout << "\x1B[31m[" << std::setw(9) << "FAIL] " << message;
+                       break;
+               default:
+                       return;
+               }
+               std::cout << "\x1B[0m" << std::endl;
+       }
+
+       static int returnErrorCode() {
+               return errno;
+       }
+
+       static void printError(int errNum) {
+               char errmsg[256];
+               std::cout << "\x1B[33m" << strerror_r(errNum, errmsg, sizeof(errmsg)) << std::endl;
+       }
+       static void printError() {
+               printError(returnErrorCode());
+       }
+};
+
+extern std::vector<AbstractGroup *> managedGroup;
+
+template<typename T>
+class GroupBuilder {
+public:
+       GroupBuilder(const std::string& name) {
+               managedGroup.emplace_back(new T(name));
+       }
+};
+
+class GroupCleaner {
+public:
+       static void deleteGroups() {
+               std::vector<AbstractGroup *>::iterator iter;
+               for (iter = managedGroup.begin(); iter != managedGroup.end(); ++iter) {
+                       delete(*iter);
+               }
+               managedGroup.clear();
+       }
+};
+#endif /* __ABSTRACT_GROUP_H__ */
diff --git a/tools/tests/groups/ipc.cpp b/tools/tests/groups/ipc.cpp
new file mode 100644 (file)
index 0000000..8c3882f
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+#include <sys/stat.h>
+#include <sys/sem.h>
+#include <sys/shm.h>
+
+#include "group.h"
+
+class IpcGroup : public AbstractGroup {
+public:
+       IpcGroup(const std::string& name) :
+               AbstractGroup(name)
+       {
+       }
+
+       void run()
+       {
+               Display::printResult(Display::NONE, "Ipc group test start");
+               useIpc();
+       }
+
+       virtual ~IpcGroup()
+       {
+       }
+
+       void useIpc() {
+               //msgctl(303), msgget(304) system call positive
+               {
+                       std::string msgKeyPath("/tmp/msg_key");
+                       int ret;
+                       int msgKey, qid;
+
+                       if (mkdir(msgKeyPath.c_str(), 0644) != 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                               Display::printResult(Display::FAIL, "msgget(304) positive");
+                               goto msgctl_result;
+                       }
+
+                       if ((msgKey = ftok(msgKeyPath.c_str(), 'M')) == -1) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                               goto msgctl_result;
+                       }
+
+                       if ((qid = msgget(msgKey, IPC_CREAT|0666)) == -1) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                               Display::printResult(Display::FAIL, "msgget(304) positive");
+                               goto msgctl_result;
+                       } else {
+                               Display::printResult(Display::SUCCESS, "msgget(304) positive");
+                       }
+
+                       if (msgctl(qid, IPC_RMID, NULL) == -1) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+
+               msgctl_result:
+                       struct stat st;
+                       if (lstat(msgKeyPath.c_str(), &st) == 0)
+                               rmdir(msgKeyPath.c_str());
+                       Display::printResult(ret, "msgctl(303) positive");
+               }
+
+               //semctl(300), semget(299), semop(298), semtimedop(312) system call positive
+               {
+                       int ret;
+                       int semId;
+                       struct sembuf buf;
+                       struct timespec timeout;
+
+                       if ((semId = semget(IPC_PRIVATE, 1, IPC_CREAT|IPC_EXCL|0666)) == -1) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                               Display::printResult(Display::FAIL, "semget(299) positive");
+                               goto semctl_result;
+                       } else {
+                               Display::printResult(Display::SUCCESS, "semget(299) positive");
+                       }
+
+                       buf.sem_num = 0;
+                       buf.sem_op = 1;
+                       buf.sem_flg = SEM_UNDO;
+                       if (semop(semId, &buf, 1) == -1) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "semop(298) positive");
+
+                       timeout.tv_sec = 1;
+                       timeout.tv_nsec = 0;
+                       if (semtimedop(semId, &buf, 1, &timeout) == -1) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "semtimedop(312) positive");
+
+                       if (semctl(semId, 0, IPC_RMID, 0) == -1) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+
+               semctl_result:
+                       Display::printResult(ret, "semctl(300) positive");
+               }
+
+               //shmctl(308), shmget(307) system call positive
+               {
+                       int shmId;
+                       int ret;
+
+                       const int keyNum = 8427;
+                       const int memSize = 1024;
+
+                       if ((shmId = shmget(keyNum, memSize, IPC_CREAT|IPC_EXCL|0666)) == -1) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "shmget(307) positive");
+
+                       if (shmctl(shmId, IPC_RMID, 0) == -1) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "shmctl(308) positive");
+               }
+       }
+};
+
+GroupBuilder<IpcGroup> ipcGroup("Ipc");
diff --git a/tools/tests/groups/mac.cpp b/tools/tests/groups/mac.cpp
new file mode 100644 (file)
index 0000000..ac0c9f4
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "group.h"
+
+#define _unused(x) ((void)(x))
+
+class MacGroup : public AbstractGroup {
+public:
+       MacGroup(const std::string& name) :
+               AbstractGroup(name)
+       {
+       }
+
+       void run()
+       {
+               Display::printResult(Display::NONE, "MAC group test start");
+               changeMacPolicy();
+       }
+
+       virtual ~MacGroup()
+       {
+       }
+
+       void changeMacPolicy() {
+               std::string smackPath("/etc/smack/test");
+               std::string smackfsPath("/sys/fs/smackfs/test");
+               std::string cynaraPath("/etc/cynara/test");
+               std::string netherPath("/etc/nether/test");
+               std::string writeString("changeMacPolicy test");
+               int writeRet;
+
+               //samck path access
+               {
+                       int fd = -1;
+                       fd = creat(smackPath.c_str(), 0644);
+                       if (fd > 0) {
+                               writeRet = write(fd, writeString.c_str(), writeString.size());
+                               _unused(writeRet);
+                               close(fd);
+                               unlink(smackPath.c_str());
+                       }
+                       Display::printResult(Display::SUCCESS, "/etc/smack access");
+               }
+
+               //smackfs path access
+               {
+                       int fd = -1;
+                       fd = creat(smackfsPath.c_str(), 0644);
+                       if (fd > 0) {
+                               writeRet = write(fd, writeString.c_str(), writeString.size());
+                               _unused(writeRet);
+                               close(fd);
+                               unlink(smackfsPath.c_str());
+                       }
+                       Display::printResult(Display::SUCCESS, "/sys/fs/smackfs access");
+               }
+
+               //cynara path access
+               {
+                       int fd = -1;
+                       fd = creat(cynaraPath.c_str(), 0644);
+                       if (fd > 0) {
+                               writeRet = write(fd, writeString.c_str(), writeString.size());
+                               _unused(writeRet);
+                               close(fd);
+                               unlink(cynaraPath.c_str());
+                       }
+                       Display::printResult(Display::SUCCESS, "/etc/cynara access");
+               }
+
+               //nether path access
+               {
+                       int fd = -1;
+                       fd = creat(netherPath.c_str(), 0644);
+                       if (fd > 0) {
+                               writeRet = write(fd, writeString.c_str(), writeString.size());
+                               _unused(writeRet);
+                               close(fd);
+                               unlink(netherPath.c_str());
+                       }
+                       Display::printResult(Display::SUCCESS, "/etc/nether access");
+               }
+       }
+};
+
+GroupBuilder<MacGroup> macGroup("Mac");
diff --git a/tools/tests/groups/network.cpp b/tools/tests/groups/network.cpp
new file mode 100644 (file)
index 0000000..dbebca6
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "group.h"
+
+class NetworkGroup : public AbstractGroup {
+public:
+       NetworkGroup(const std::string& name) :
+               AbstractGroup(name)
+       {
+       }
+
+       void run()
+       {
+               Display::printResult(Display::NONE, "Network group test start");
+               changeNetConfig();
+       }
+
+       virtual ~NetworkGroup()
+       {
+       }
+
+       void changeNetConfig() {
+               int ret;
+               {
+                       std::vector<std::string> paths;
+                       std::string testfile("/tmp/audit-test/testing");
+
+                       paths.emplace_back("/etc/hosts");
+                       paths.emplace_back("/etc/sysconfig/network");
+                       paths.emplace_back("/etc/system-release");
+                       paths.emplace_back("/etc/sysconfig/network-scripts");
+                       paths.emplace_back("/etc/wpa_supplicant");
+                       paths.emplace_back("/etc/wifi-direct");
+
+                       for (auto entry : paths) {
+                               struct stat st;
+                               std::string logStr(entry + " change");
+                               lstat(entry.c_str(), &st);
+                               chmod(entry.c_str(), st.st_mode);
+                               Display::printResult(Display::SUCCESS, logStr);
+                       }
+               }
+
+               //sethostname(74) system call positive
+               {
+                       std::string hostname("localhost");
+
+                       if (sethostname(hostname.c_str(), hostname.size()) == -1) {
+                               Display::printError();
+                               ret = Display::FAIL;
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "sethostname(74) positive");
+               }
+
+               //setdomainname(121) system call positive
+               {
+                       std::string domain("(none)");
+
+                       if (setdomainname(domain.c_str(), domain.size()) == -1) {
+                               Display::printError();
+                               ret = Display::FAIL;
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "setdomainname(121) positive");
+               }
+       }
+};
+
+GroupBuilder<NetworkGroup> networkGroup("Network");
diff --git a/tools/tests/groups/system.cpp b/tools/tests/groups/system.cpp
new file mode 100644 (file)
index 0000000..93ba23e
--- /dev/null
@@ -0,0 +1,336 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <sched.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/mount.h>
+#include <sys/syscall.h>
+#include <sys/ptrace.h>
+#include <sys/wait.h>
+
+#include "group.h"
+
+#define _unused(x) ((void)(x))
+
+class SystemGroup : public AbstractGroup {
+public:
+       SystemGroup(const std::string& name) :
+               AbstractGroup(name)
+       {
+       }
+
+       void run()
+       {
+               Display::printResult(Display::NONE, "System group test start");
+               changeConfigStartup();
+               mountDevices();
+               createNewProcessFork();
+               createNewProcessVfork();
+               createNewProcessClone();
+               changeUmaskSettings();
+               changeConfigLibs();
+               changeKernelModule();
+               useKernelModule();
+               changeAliasePostfix();
+               debugging();
+               container();
+               executeCommands();
+       }
+
+       virtual ~SystemGroup()
+       {
+       }
+
+       void changeConfigStartup() {
+               std::vector<std::string> testPath;
+
+               testPath.emplace_back("/etc/rc.d");
+               testPath.emplace_back("/etc/init.d");
+               testPath.emplace_back("/etc/systemd");
+               testPath.emplace_back("/usr/lib/systemd/system");
+               testPath.emplace_back("/usr/lib/systemd/user");
+               testPath.emplace_back("/usr/lib/systemd/network");
+
+               for (auto entry : testPath) {
+                       struct stat st;
+                       std::string logStr(entry + " access");
+                       lstat(entry.c_str(), &st);
+                       chmod(entry.c_str(), st.st_mode);
+                       Display::printResult(Display::SUCCESS, logStr);
+               }
+       }
+
+       void mountDevices() {
+               std::vector<std::string> mountPath;
+               int ret;
+
+               mountPath.emplace_back("/tmp/audit-test-source");
+               mountPath.emplace_back("/tmp/audit-test-target-1");
+               mountPath.emplace_back("/tmp/audit-test-target-2");
+
+               for (std::string entry : mountPath) {
+                       if (mkdir(entry.c_str(), 0644) != 0) {
+                               Display::printError();
+                               Display::printResult(Display::FAIL, "mountDevices prepare");
+                               for (std::string iter : mountPath) {
+                                       struct stat st;
+                                       if (lstat(iter.c_str(), &st) == 0) {
+                                               rmdir(iter.c_str());
+                                       }
+                               }
+                               return;
+                       }
+               }
+
+               //mount(21) system call positive
+               {
+                       for (int i = 1; i <= 2; i++) {
+                               if (mount(mountPath[0].c_str(), mountPath[i].c_str(), "ext4", MS_BIND, NULL) != 0) {
+                                       ret = Display::FAIL;
+                                       Display::printError();
+                               } else {
+                                       ret = Display::SUCCESS;
+                               }
+                       }
+
+                       Display::printResult(ret, "mount(21) positive");
+               }
+
+               //umount(22) system call positive
+               {
+                       if (umount(mountPath[1].c_str()) != 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "umount(22) positive");
+               }
+
+               //umount2(52) system call positive
+               {
+                       if (umount2(mountPath[2].c_str(), 0) != 0) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "umount2(52) positive");
+               }
+
+               for (std::string entry : mountPath) {
+                       struct stat st;
+                       if ((lstat(entry.c_str(), &st) == 0) && (rmdir(entry.c_str()) != 0))
+                               Display::printError();
+               }
+       }
+
+       static int childFn(void *arg) {
+               return 0;
+       }
+
+       void createNewProcessClone() {
+               //clone(120) system call positive
+               pid_t pid;
+               const int stacksize = 1024 * 1024;
+               void *childStack = malloc(stacksize);
+               if (childStack == NULL) {
+                       Display::printError();
+                       Display::printResult(Display::FAIL, "clone(120) positive");
+                       return;
+               }
+
+               if ((pid = clone(childFn, (void *)((char *)childStack+ stacksize), SIGCHLD, NULL))< 0) {
+                       Display::printError();
+                       Display::printResult(Display::FAIL, "clone(120) positive");
+                       free(childStack);
+                       return;
+               }
+
+               wait(NULL);
+               free(childStack);
+               Display::printResult(Display::SUCCESS, "clone(120) positive");
+       }
+
+       void createNewProcessFork() {
+               //fork(2) system call positive
+               pid_t pid;
+
+               pid = fork();
+               if (pid == -1) {
+                       Display::printResult(Display::FAIL, "fork(2) positive");
+                       return;
+               }
+
+               if (pid == 0) {
+                       exit(0);
+               } else {
+                       wait(NULL);
+                       Display::printResult(Display::SUCCESS, "fork(2) positive");
+               }
+       }
+
+       void createNewProcessVfork() {
+               //vfork(190) system call positive
+               pid_t pid;
+
+               pid = vfork();
+               if (pid == -1) {
+                       Display::printError();
+                       Display::printResult(Display::FAIL, "vfork(190) positive");
+                       return;
+               } else if (pid == 0) {
+                       _exit(0);
+               } else {
+                       wait(NULL);
+                       Display::printResult(Display::SUCCESS, "vfork(190) positive");
+               }
+       }
+
+       void changeUmaskSettings() {
+               //umask(60) system call positive
+               mode_t origin = umask(022);
+               umask(origin);
+               Display::printResult(Display::SUCCESS, "umask(60) positive");
+       }
+
+       void changeConfigLibs() {
+               //path: /etc/ld.so.conf
+               std::string testPath("/etc/ld.so.conf");
+               struct stat st;
+
+               lstat(testPath.c_str(), &st);
+               chmod(testPath.c_str(), st.st_mode);
+               Display::printResult(Display::SUCCESS, "change /etc/ld.so.conf");
+       }
+
+       void changeKernelModule() {
+               //path: /etc/modules-load.d
+               std::string testPath("/etc/modules-load.d");
+               struct stat st;
+
+               lstat(testPath.c_str(), &st);
+               chmod(testPath.c_str(), st.st_mode);
+               Display::printResult(Display::SUCCESS, "change /etc/modules-load.d");
+       }
+
+       void useKernelModule() {
+               std::vector<std::string> commands;
+
+               commands.emplace_back("insmod /opt/data/audit-trail/test_module.ko");
+               commands.emplace_back("rmmod test_module");
+               commands.emplace_back("modprobe -c");
+
+               for (auto entry : commands) {
+                       if (system(entry.c_str()) == -1) {
+                               Display::printError();
+                               Display::printResult(Display::FAIL, entry);
+                       } else {
+                               Display::printResult(Display::SUCCESS, entry);
+                       }
+               }
+       }
+
+       void changeAliasePostfix() {
+               std::vector<std::string> testPath;
+               struct stat st;
+
+               testPath.emplace_back("/etc/aliases");
+               testPath.emplace_back("/etc/postfix");
+
+               for (auto entry : testPath) {
+                       std::string logStr(entry + " access");
+                       lstat(entry.c_str(), &st);
+                       chmod(entry.c_str(), st.st_mode);
+                       Display::printResult(Display::SUCCESS, logStr);
+               }
+       }
+
+       void debugging() {
+               //ptrace(26) system call positive
+               pid_t pid;
+
+               pid = syscall(__NR_fork);
+               if (pid == -1) {
+                       Display::printResult(Display::FAIL, "ptrace(26) positive");
+                       return;
+               }
+
+               if (pid == 0) {
+                       ptrace(PTRACE_TRACEME, 0, NULL, NULL);
+                       exit(0);
+               } else {
+                       wait(NULL);
+                       Display::printResult(Display::SUCCESS, "ptrace(26) positive");
+               }
+       }
+
+       void container() {
+               int ret;
+
+               //unshare(337) system call positive
+               {
+                       if (unshare(0) == -1) {
+                               Display::printError();
+                               ret = Display::FAIL;
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "unshare(337) positive");
+               }
+
+               //setns(375) system call positive
+               {
+                       std::string testFile = "/proc/" + std::to_string(getpid()) + "/ns/uts";
+                       int fd;
+                       if ((fd = open(testFile.c_str(), O_RDONLY)) == -1) {
+                               Display::printResult(Display::FAIL, "setns(375) positive");
+                               return;
+                       }
+
+                       if (setns(fd, 0) == -1) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+
+                       Display::printResult(ret, "setns(375) positive");
+
+                       close(fd);
+               }
+       }
+
+       void executeCommands() {
+               std::string command("/sbin/findfs");
+               int ret = Display::FAIL;
+
+               if (system(command.c_str()) == -1)
+                       Display::printError();
+               else
+                       ret = Display::SUCCESS;
+
+               Display::printResult(ret, "execute /sbin/findfs");
+       }
+};
+
+GroupBuilder<SystemGroup> systemGroup("System");
diff --git a/tools/tests/groups/time.cpp b/tools/tests/groups/time.cpp
new file mode 100644 (file)
index 0000000..225f002
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <unistd.h>
+#include <time.h>
+#include <stdlib.h>
+#include <sys/timex.h>
+
+#include "group.h"
+
+class TimeGroup : public AbstractGroup {
+public:
+       TimeGroup(const std::string& name) :
+               AbstractGroup(name)
+       {
+       }
+
+       void run()
+       {
+               Display::printResult(Display::NONE, "Time group test start");
+               changeCurrentTime();
+       }
+
+       virtual ~TimeGroup()
+       {
+       }
+
+       void changeCurrentTime() {
+               int ret;
+               //adjtimex(124), clock_adjtime(372) system call positive
+               {
+                       struct timex time;
+
+                       time.modes = ADJ_OFFSET;
+                       time.offset = 0;
+
+                       if (adjtimex(&time) == -1) {
+                               Display::printError();
+                               ret = Display::FAIL;
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "adjtimex(124) positive");
+
+                       if (clock_adjtime(CLOCK_REALTIME, &time) == -1) {
+                               Display::printError();
+                               ret = Display::FAIL;
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "clock_adjtime(372) positive");
+               }
+
+               //settimeofday(79) system call positive
+               {
+                       struct timeval time;
+                       gettimeofday(&time, NULL);
+
+                       if (settimeofday(&time, NULL) == -1) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "settimeofday(79) positive");
+               }
+
+               //stime(25) system call positive
+               {
+                       time_t currentTime;
+
+                       time(&currentTime);
+
+                       if (stime(&currentTime) == -1) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "stime(25) positive");
+               }
+
+               //clock_settime(262) system call positive
+               {
+                       struct timespec time;
+                       clock_gettime(CLOCK_REALTIME, &time);
+
+                       if (clock_settime(CLOCK_REALTIME, &time) == -1) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "clock_settime(262) positive");
+               }
+
+               //time config file access
+               {
+                       std::string command("touch /etc/localtime");
+                       if (system(command.c_str()) == -1) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "/etc/localtime access");
+               }
+
+               //time config file access
+               {
+                       std::string command("touch /etc/sysconfig/clock");
+                       if (system(command.c_str()) == -1) {
+                               ret = Display::FAIL;
+                               Display::printError();
+                       } else {
+                               ret = Display::SUCCESS;
+                       }
+                       Display::printResult(ret, "/etc/sysconfig/clock access");
+               }
+       }
+};
+
+GroupBuilder<TimeGroup> timeGroup("Time");
diff --git a/tools/tests/rule_verification.cpp b/tools/tests/rule_verification.cpp
new file mode 100644 (file)
index 0000000..706500a
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/**
+ * @file
+ * @brief   CLI tool to test a audit rule verification
+ */
+
+#include <iostream>
+#include <sstream>
+#include <string>
+
+#include "groups/group.h"
+
+int selectGroups()
+{
+       int groupIdx = 0;
+       std::string selectedGroups;
+       std::stringstream ss;
+       int n;
+
+       std::cout << "===========================================" << std::endl;
+       std::cout << "<< Rule Verification Test Tool >>" << std::endl;
+       std::cout << "===========================================" << std::endl;
+
+       std::cout << "[0] All" << std::endl;
+       for (AbstractGroup *entry : managedGroup) {
+               std::cout << "[" << ++groupIdx << "] " << entry->name << std::endl;
+       }
+
+       std::cout << "---------------------------------------" << std::endl;
+       std::cout << "-1 : exit" << std::endl;
+       std::cout << "split by space ex) > 1 3 5 (enter)" << std::endl;
+       std::cout << "---------------------------------------" << std::endl;
+       std::cout << "> Enter group ID : ";
+
+       std::getline(std::cin, selectedGroups);
+       ss.str(selectedGroups);
+
+       while(!ss.eof()) {
+               ss >> n;
+
+               if (n == -1) {
+                       std::cout << "Exit test" << std::endl;
+                       return 1;
+               }
+
+               if (n > (int)managedGroup.size() || n < 0) {
+                       std::cout << "Wrong option" << std::endl;
+                       return 0;
+               }
+
+               if (n == 0) {
+                       for(AbstractGroup *selected : managedGroup) {
+                               selected->run();
+                       }
+
+                       return 1;
+               }
+
+               managedGroup[n - 1]->run();
+       }
+
+       return 1;
+}
+
+ int main(int argc, char* argv[])
+ {
+       bool done = false;
+
+       while(!done) {
+               if (selectGroups()) {
+                       done = true;
+               }
+       }
+
+       GroupCleaner::deleteGroups();
+
+       return 0;
+ }