Introduce verity-handler 46/246146/4
authorKichan Kwon <k_c.kwon@samsung.com>
Mon, 26 Oct 2020 02:16:55 +0000 (11:16 +0900)
committerKichan Kwon <k_c.kwon@samsung.com>
Wed, 28 Oct 2020 07:13:44 +0000 (16:13 +0900)
- It launches verityctl and updates progress
- If dm-verity is enabled, initrd-fota will launch it

Change-Id: Ibb82ac06e4c628bbb7c0428ed5c1eefccb9ef041
Signed-off-by: Kichan Kwon <k_c.kwon@samsung.com>
CMakeLists.txt
dmverity/CMakeLists.txt [new file with mode: 0755]
dmverity/verity_handler.c [new file with mode: 0755]
dmverity/verity_handler.h [new file with mode: 0755]
packaging/tota-ua.spec
scripts/40-tota-ua.list.in

index 27aa88b..4e3de87 100755 (executable)
@@ -66,4 +66,5 @@ TARGET_LINK_LIBRARIES(${EXECNAME} ${pkgs_LDFLAGS})
 
 INSTALL(TARGETS ${EXECNAME} DESTINATION ${BINDIR})
 
+ADD_SUBDIRECTORY(dmverity)
 ADD_SUBDIRECTORY(img-verifier)
diff --git a/dmverity/CMakeLists.txt b/dmverity/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..379f9d7
--- /dev/null
@@ -0,0 +1,46 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(BINDIR "${PREFIX}/bin")
+SET(VERITY_HANDLER "verity_handler")
+SET(DMVERITY_DIR ${CMAKE_CURRENT_SOURCE_DIR})
+
+SET(DMVERITY_SRCS
+       ${DMVERITY_DIR}/verity_handler.c
+)
+
+STRING(FIND ${CMAKE_C_FLAGS} "mfloat-abi=hard" IFFOUND1)
+STRING(FIND ${CMAKE_C_FLAGS} "mhard-float" IFFOUND2)
+
+INCLUDE_DIRECTORIES(${DMVERITY_DIR})
+
+IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+       SET(CMAKE_BUILD_TYPE "Release")
+ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+MESSAGE("Build type: ${CMAKE_BUILD_TYPE}")
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(dmverity_pkgs REQUIRED
+)
+
+FOREACH(flag ${dmverity_pkgs_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIE")
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+SET(CMAKE_C_FLAGS_RELEASE "-O2")
+
+FIND_PROGRAM(UNAME NAMES uname)
+EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH")
+IF("${ARCH}" STREQUAL "arm")
+       ADD_DEFINITIONS("-DTARGET")
+       MESSAGE("add -DTARGET")
+ENDIF("${ARCH}" STREQUAL "arm")
+
+SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed -pie")
+
+ADD_EXECUTABLE(${VERITY_HANDLER} ${DMVERITY_SRCS})
+TARGET_LINK_LIBRARIES(${VERITY_HANDLER} ${dmverity_pkgs_LDFLAGS} ${LIBS} -lpthread)
+
+INSTALL(TARGETS ${VERITY_HANDLER} DESTINATION ${BINDIR})
diff --git a/dmverity/verity_handler.c b/dmverity/verity_handler.c
new file mode 100755 (executable)
index 0000000..1deceda
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * PROPRIETARY/CONFIDENTIAL
+ *
+ * This software is the confidential and proprietary information of
+ * SAMSUNG ELECTRONICS ("Confidential Information").
+ *
+ * You agree and acknowledge that this software is owned by Samsung and you
+ * shall not disclose such Confidential Information and shall use it only
+ * in accordance with the terms of the license agreement you entered into with
+ * SAMSUNG ELECTRONICS.
+ *
+ * SAMSUNG make no representations or warranties about the suitability
+ * of the software, either express or implied, including but not limited to
+ * the implied warranties of merchantability, fitness for a particular purpose,
+ * or non-infringement.
+ *
+ * SAMSUNG shall not be liable for any damages suffered by licensee arising
+ * out of or related to this software.
+ */
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <pthread.h>
+#include <unistd.h>
+
+#include "verity_handler.h"
+
+#define TMP_DIR "/tmp/upgrade"
+#define PROGRESS_FILE TMP_DIR "/ro_progress"
+
+/*-----------------------------------------------------------------------------
+  _system_cmd_wait
+ ----------------------------------------------------------------------------*/
+static int _system_cmd_wait(const char *command)
+{
+       int pid = 0;
+       int status = 0;
+       char* const environ[2] = { "DISPLAY=:0", NULL };
+
+       if (command == NULL)
+               return -1;
+
+       pid = fork();
+
+       if (pid == -1)
+               return -1;
+
+       if (pid == 0) {
+               char *argv[4];
+               argv[0] = "sh";
+               argv[1] = "-c";
+               argv[2] = (char*)command;
+               argv[3] = 0;
+               execve("/bin/sh", argv, environ);
+               exit(127);
+       }
+
+       do {
+               if (waitpid(pid, &status, 0) == -1) {
+                       if (errno != EINTR)
+                               return -1;
+               } else {
+                       return status;
+               }
+       } while(1);
+}
+
+/*-----------------------------------------------------------------------------
+  fota_gui_update_progress
+ ----------------------------------------------------------------------------*/
+void fota_gui_update_progress(int percent)
+{
+       int ret;
+       int fd;
+       struct stat s;
+
+       // Check directory
+       ret = stat(TMP_DIR, &s);
+       if (ret == 0) {
+               // TMP_DIR exists but it is not directory
+               if (!S_ISDIR(s.st_mode))
+                       goto remove_file;
+               else
+                       goto update_progress;
+       } else if (errno == ENOENT)     // TMP_DIR not exists
+               goto make_directory;
+       else {
+               LOG("stat failed : %m\n");
+               return;
+       }
+
+remove_file:
+       ret = remove(TMP_DIR);
+       if (ret != 0) {
+               LOG("remove failed : %m\n");
+               return;
+       }
+
+make_directory:
+       ret = mkdir(TMP_DIR, 0755);
+       if (ret != 0) {
+               LOG("mkdir failed : %m\n");
+               return;
+       }
+
+update_progress:
+       fd = creat(PROGRESS_FILE, 0644);
+       if (fd < 0) {
+               LOG("creat failed : %m\n");
+               return;
+       }
+
+       ret = dprintf(fd, "%d\n", percent);
+       if (close(fd) != 0) {
+               LOG("close failed : %m\n");
+               return;
+       }
+       if (ret < 2) {
+               LOG("write failed (%d) : %m\n", ret);
+               return;
+       }
+
+       LOG("Succeed to write\n");
+}
+
+/*-----------------------------------------------------------------------------
+  __thread_make_hash
+ ----------------------------------------------------------------------------*/
+static void *__thread_make_hash(void *arg)
+{
+       int ret;
+       char cmd[1024];
+
+       snprintf(cmd, sizeof(cmd)-1, "/usr/bin/verityctl format %s", (char*)arg);
+       LOG("cmd = %s\n", cmd);
+       ret = _system_cmd_wait(cmd);
+       LOG("ret = %d, exit status = %d\n", ret, WEXITSTATUS(ret));
+
+       return NULL;
+}
+
+/*-----------------------------------------------------------------------------
+  __thread_draw_progress
+ ----------------------------------------------------------------------------*/
+static void *__thread_draw_progress(void *arg)
+{
+       int expected_duration = 45000*1000;     /* usec */
+       int count = 20;
+       int loop_duration = (expected_duration / count);
+       int init_progress = (80 + 2);
+       int exit_progress = (100 - 2);
+       float progress = (float)init_progress;
+       float prog_step = (float)(((float)exit_progress - (float)init_progress) / (float)count);
+
+       while (count > 0) {
+               usleep(loop_duration);
+               fota_gui_update_progress((int)progress);
+               progress += prog_step;
+               count --;
+       }
+
+       return NULL;
+}
+
+
+/*-----------------------------------------------------------------------------
+  main
+ ----------------------------------------------------------------------------*/
+int main(int argc, char **argv)
+{
+       int error = 0;
+       pthread_t th_id_hash;
+       pthread_t th_id_progress;
+
+       /* check argument */
+       if ((argc != 2) || (argv[1] == NULL) || (strlen(argv[1]) == 0)) {
+               return -1;
+       }
+
+       /* argv[1] is a path of block device whose hash will be made */
+       error = pthread_create(&th_id_hash, NULL, __thread_make_hash, argv[1]);
+       if (error != 0) {
+               LOG("pthread_create(th_id_hash) failed (err = %d)\n", error);
+               return -1;
+       }
+
+       error = pthread_create(&th_id_progress, NULL, __thread_draw_progress, NULL);
+       if (error != 0) {
+               LOG("pthread_create(th_id_progress) failed (err = %d)\n", error);
+               return -1;
+       }
+
+       error = pthread_join(th_id_hash, NULL);
+       if (error != 0) {
+               LOG("pthread_join(th_id_hash) failed (err = %d)\n", error);
+               return -1;
+       } else
+               LOG("pthread_join(th_id_hash) succeeded \n");
+
+       error = pthread_join(th_id_progress, NULL);
+       if (error != 0) {
+               LOG("pthread_join(th_id_progress) failed (err = %d)\n", error);
+               return -1;
+       } else
+               LOG("pthread_join(th_id_hash) succeeded \n");
+
+       fota_gui_update_progress(100);
+
+       return 0;
+}
diff --git a/dmverity/verity_handler.h b/dmverity/verity_handler.h
new file mode 100755 (executable)
index 0000000..9c6162b
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * PROPRIETARY/CONFIDENTIAL
+ *
+ * This software is the confidential and proprietary information of
+ * SAMSUNG ELECTRONICS ("Confidential Information").
+ *
+ * You agree and acknowledge that this software is owned by Samsung and you
+ * shall not disclose such Confidential Information and shall use it only
+ * in accordance with the terms of the license agreement you entered into with
+ * SAMSUNG ELECTRONICS.
+ *
+ * SAMSUNG make no representations or warranties about the suitability
+ * of the software, either express or implied, including but not limited to
+ * the implied warranties of merchantability, fitness for a particular purpose,
+ * or non-infringement.
+ *
+ * SAMSUNG shall not be liable for any damages suffered by licensee arising
+ * out of or related to this software.
+ */
+
+#ifndef __VERITY_HANDLER_H__
+#define __VERITY_HANDLER_H__
+
+#define DEBUG_STDOUT
+//#define DEBUG_FILE
+
+#define LOG_PRFIX      "VERITY_HANDLER"
+
+#ifdef DEBUG_STDOUT
+#define LOGE(s, args...) printf(LOG_PRFIX "/ERROR(%s)  " s, __func__, ##args) // Error log
+#define LOGL(s, args...) do{   printf(LOG_PRFIX "/(%s): " s,__func__, ##args);}while(0)
+#define LOG(s, args...) LOGL(s, ##args)
+#endif
+
+
+#endif /* __VERITY_HANDLER_H__ */
index 1cd057c..7112df2 100755 (executable)
@@ -61,10 +61,17 @@ mkdir -p %{buildroot}%{img_verifier_root_ca_dir}
 %license LICENSE
 %manifest tota-ua.manifest
 %doc README
+
+# Engine
 %attr(775, root, system_fw) %{fota_dir}
 %defattr(-,root,root,-)
 %{_bindir}/delta.ua
 %{_bindir}/upgrade-trigger.sh
 %attr(700,-,-) %{tota_ua_list_dir}/40-tota-ua.list
+
+# Image verifier
 %{_sbindir}/img-verifier
 %attr(755,root,root) %{img_verifier_root_ca_dir}
+
+# DM verity handler
+%{_bindir}/verity_handler
index bb72ea8..5326f72 100755 (executable)
@@ -3,6 +3,7 @@ WITHLIBS="
 @TOTA_UA_LIB_DIR@/libcrypto.so.1.1
 @TOTA_UA_LIB_DIR@/libtota.so.1.0.0
 /usr/bin/delta.ua
+/usr/bin/verity_handler
 /usr/sbin/img-verifier
 "