Add support for processes running from the ISU packages 64/315964/1 accepted/tizen/8.0/unified/20241210.170133
authorMateusz Moscicki <m.moscicki2@partner.samsung.com>
Tue, 10 Oct 2023 11:59:28 +0000 (13:59 +0200)
committerMateusz Moscicki <m.moscicki2@partner.samsung.com>
Fri, 6 Dec 2024 15:13:31 +0000 (16:13 +0100)
If the executable file or library loaded by the process is from ISU
package, the last column of the *.so_info file will record the name and
version of the package.

Change-Id: I83a5ab4f34183959264d688154de46c95e242e93

packaging/crash-worker.spec
src/crash-manager/CMakeLists.txt
src/crash-manager/crash-manager.c
src/crash-manager/so-info.c
src/crash-manager/so-info.h

index f30372d0925aed6815bcae5148447ad77348aad5..e82e0bb56c3d441960d4b80ea566114c15301e90 100644 (file)
@@ -16,7 +16,7 @@
 
 Name:           crash-worker
 Summary:        Coredump handler and report generator for Tizen
-Version:        8.0.6
+Version:        8.0.7
 Release:        1
 Group:          Framework/system
 License:        MIT
@@ -37,6 +37,8 @@ BuildRequires:  pkgconfig(json-c)
 BuildRequires:  pkgconfig(openssl3)
 BuildRequires:  pkgconfig(diagnostics)
 BuildRequires:  pkgconfig(bugreport)
+BuildRequires:  pkgconfig(libisu)
+BuildRequires:  pkgconfig(libarchive)
 %if %{with dumpsystemstateservice}
 BuildRequires:  pkgconfig(dumpsys-system)
 %endif
@@ -112,6 +114,7 @@ Requires:       %{name}-dumpsystemstate-util = %{version}-%{release}
 Requires:       zip
 # Ensure crash_worker user is available (created by security-config, package provides crash_worker-owned files)
 Requires:       security-config
+Requires:       libisu
 %description    support-common
 
 %package -n     libcrash-manager-devel
index 9cccbf8f7e3eb8fcae286cb2f4e91d0c377ad763..03f106121585669e78823b0eca538a5f1916e430 100644 (file)
@@ -27,6 +27,7 @@ pkg_check_modules(crash-manager_pkgs REQUIRED
        rpm
        libcrypto3
        diagnostics
+       libisu
        )
 
 pkg_check_modules(helper_pkgs REQUIRED
@@ -44,10 +45,10 @@ ADD_LIBRARY(libcrash-manager SHARED ${LIB_CRASH_MANAGER_SRCS})
 SET_TARGET_PROPERTIES(libcrash-manager PROPERTIES SOVERSION 1)
 SET_TARGET_PROPERTIES(libcrash-manager PROPERTIES PUBLIC_HEADER crash-manager.h)
 SET_TARGET_PROPERTIES(libcrash-manager PROPERTIES OUTPUT_NAME crash-manager)
-TARGET_LINK_LIBRARIES(libcrash-manager ${crash-manager_pkgs_LDFLAGS})
+TARGET_LINK_LIBRARIES(libcrash-manager ${crash-manager_pkgs_LDFLAGS} -larchive)
 
 ADD_EXECUTABLE(${PROJECT_NAME} ${CRASH_MANAGER_SRCS})
-TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${crash-manager_pkgs_LDFLAGS} -pie -lcap -lrt libcrash-manager -ldiagnostics)
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${crash-manager_pkgs_LDFLAGS} -pie -lcap -lrt libcrash-manager -ldiagnostics -larchive)
 
 set(CRASH_POPUP crash-popup-launch)
 ADD_EXECUTABLE(${CRASH_POPUP} ${CRASH_POPUP}.c)
index e12e5b83a86cf8d925329def8a4a9da1096ec7b2..54e85cc104e70f6b7a33dd1e491811fd206795cf 100644 (file)
@@ -541,7 +541,7 @@ static void save_so_info(const struct crash_info *cinfo)
        snprintf(so_info_path, sizeof(so_info_path),
                         "%s/%s.%s", cinfo->pfx, cinfo->name, "so_info");
 
-       get_and_save_so_info(maps_path, so_info_path);
+       get_and_save_so_info(maps_path, so_info_path, cinfo->pid_info);
 }
 
 /* remove a file whose name begins with 'beggining_of_name'. This is needed
index af0c07342808358dc1700371f82e61e2b3fafe3a..d624d30c1d521a0718834403ee8159e57b8371c7 100644 (file)
 #include <tzplatform_config.h>
 #include <openssl/sha.h>
 #include <openssl/evp.h>
+#include <libmount/libmount.h>
+#include <libisu-internal.h>
 
 #define BID_SNAME ".note.gnu.build-id"
+#define ISU_BUFF_LEN 1024
 
 struct rpm_info {
        char *file_path;
@@ -218,6 +221,33 @@ static int get_build_id(char *filename, char **build_id)
        return ret;
 }
 
+static char *get_isu_pkg_name_from_path(const char *path)
+{
+       char *p = strstr(path, ISU_RUN_PATH);
+       if (p == NULL) {
+               // File is not under /run/isu
+               return NULL;
+       }
+       p += strlen(ISU_RUN_PATH);
+       if (*p == '/')
+               p++;
+
+       char *c = strchr(p, '/');
+       if (c == NULL) {
+               return strdup(p);
+       } else {
+               size_t len = c - p + 1;
+               char *result = (char*)malloc(len);
+               if (result == NULL) {
+                       _E("Memory allocation error: %d %m", errno);
+                       return NULL;
+               }
+               strncpy(result, p, len-1);
+               result[len-1] = '\0';
+               return result;
+       }
+}
+
 enum Perms {
        PERM_READ = 1,
        PERM_WRITE = 2,
@@ -530,7 +560,56 @@ bool correct_file_path(const char *file_path, char *buff, size_t len)
        return result;
 }
 
-void get_and_save_so_info(char *map_path, char *out_path)
+static char* get_isu_info(const char *path, pid_t pid)
+{
+       char *source_path = NULL;
+       int res = is_isu_file(path, pid, &source_path);
+       if (res == ISU_FILE_RES_NOT_SUPPORTED || res == ISU_FILE_RES_IS_NORMAL_FILE) {
+               return NULL;
+       }
+       if (res == ISU_FILE_RES_ERROR) {
+               return strdup("libisu error");
+       }
+
+
+       char *isu_info = NULL;
+
+       isu_pkg_list list = isu_list_init();
+       if (list == NULL) {
+               return strdup("get ISU package info error");
+       }
+
+       char *pkg_name = get_isu_pkg_name_from_path(source_path);
+       free(source_path);
+
+       if (pkg_name == NULL) {
+               return strdup("get ISU package name error");
+       }
+
+       isu_pkg_info info = NULL;
+       while ((info = isu_list_next(list)) != NULL) {
+               char name[ISU_BUFF_LEN];
+               isu_pkg_get_name(info, name, sizeof(name));
+               if (strncmp(name, pkg_name, strlen(pkg_name)) == 0) {
+                       char version[ISU_BUFF_LEN];
+                       isu_pkg_get_version(info, version, sizeof(version));
+                       isu_pkg_info_free(info);
+                       if (asprintf(&isu_info, "%s;%s", pkg_name, version) == -1) {
+                               _E("Memory allocation error");
+                               isu_info = NULL;
+                               goto exit;
+                       }
+                       break;
+               }
+               isu_pkg_info_free(info);
+       }
+exit:
+       free(pkg_name);
+       isu_list_free(list);
+       return isu_info;
+}
+
+void get_and_save_so_info(char *map_path, char *out_path, pid_t pid)
 {
        FILE *f = fopen(out_path, "w");
        if (f == NULL) {
@@ -540,6 +619,8 @@ void get_and_save_so_info(char *map_path, char *out_path)
 
        GSList *file_list = get_filepaths(map_path);
        GSList *pkgs_not_found = NULL;
+       char relative_root[PATH_MAX];
+       snprintf(relative_root, sizeof(relative_root), "/proc/%d/root/", pid);
 
        rpmts ts = init_rpm();
 
@@ -548,11 +629,13 @@ void get_and_save_so_info(char *map_path, char *out_path)
                char modified_file_path[PATH_MAX];
                char *build_id = NULL;
 
+               char proc_root_file_path[PATH_MAX+1];
+               snprintf(proc_root_file_path, sizeof(proc_root_file_path), "%s/%s", relative_root, file_path);
                if (is_dotnet_file(file_path)) {
                        build_id = strdup("");
                        if (correct_file_path(file_path, modified_file_path, sizeof(modified_file_path)))
                                file_path = modified_file_path;
-               } else if (get_build_id(file_path, &build_id) <= 0 || build_id == NULL) {
+               } else if (get_build_id(proc_root_file_path, &build_id) <= 0 || build_id == NULL) {
                        continue;
                }
 
@@ -584,10 +667,20 @@ void get_and_save_so_info(char *map_path, char *out_path)
                } else {
                        char hash_sum[2*SHA_DIGEST_LENGTH + 1];
 
-                       if (!sha1sum(file_path, hash_sum))
+                       if (!sha1sum(proc_root_file_path, hash_sum))
                                snprintf(hash_sum, sizeof(hash_sum), "hash-error");
 
-                       int fret = fprintf(f, "%s %s %s %s\n", file_path, build_id, rpm_info, hash_sum);
+                       int fret = fprintf(f, "%s %s %s %s", file_path, build_id, rpm_info, hash_sum);
+
+                       if (fret) {
+                               char *isu_info = get_isu_info(file_path, pid);
+                               if (isu_info) {
+                                       fret = fprintf(f, " ISU:%s", isu_info);
+                                       free(isu_info);
+                               }
+                               fprintf(f, "\n");
+                       }
+
                        free(rpm_info);
                        free(build_id);
 
index e13d420231dea4782be630df577665bd689651bc..9c677c6e0f23aafdbb8f3c684cf80d692adc475d 100644 (file)
@@ -5,5 +5,5 @@
  */
 #pragma once
 
-void get_and_save_so_info(char *map_filename, char *out_file);
+void get_and_save_so_info(char *map_filename, char *out_file, pid_t pid);
 GHashTable *get_app_name_from_map(char *map_path);