From a96aed192a3bf52576d45fe16c565ef75ec05944 Mon Sep 17 00:00:00 2001 From: Kichan Kwon Date: Mon, 26 Oct 2020 11:16:55 +0900 Subject: [PATCH] Introduce verity-handler - It launches verityctl and updates progress - If dm-verity is enabled, initrd-fota will launch it Change-Id: Ibb82ac06e4c628bbb7c0428ed5c1eefccb9ef041 Signed-off-by: Kichan Kwon --- CMakeLists.txt | 1 + dmverity/CMakeLists.txt | 46 ++++++++++ dmverity/verity_handler.c | 219 +++++++++++++++++++++++++++++++++++++++++++++ dmverity/verity_handler.h | 38 ++++++++ packaging/tota-ua.spec | 7 ++ scripts/40-tota-ua.list.in | 1 + 6 files changed, 312 insertions(+) create mode 100755 dmverity/CMakeLists.txt create mode 100755 dmverity/verity_handler.c create mode 100755 dmverity/verity_handler.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 27aa88b..4e3de87 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 index 0000000..379f9d7 --- /dev/null +++ b/dmverity/CMakeLists.txt @@ -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 index 0000000..1deceda --- /dev/null +++ b/dmverity/verity_handler.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 index 0000000..9c6162b --- /dev/null +++ b/dmverity/verity_handler.h @@ -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__ */ diff --git a/packaging/tota-ua.spec b/packaging/tota-ua.spec index 1cd057c..7112df2 100755 --- a/packaging/tota-ua.spec +++ b/packaging/tota-ua.spec @@ -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 diff --git a/scripts/40-tota-ua.list.in b/scripts/40-tota-ua.list.in index bb72ea8..5326f72 100755 --- a/scripts/40-tota-ua.list.in +++ b/scripts/40-tota-ua.list.in @@ -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 " -- 2.7.4