Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package libpulp for openSUSE:Factory checked in at 2023-10-23 23:41:34 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libpulp (Old) and /work/SRC/openSUSE:Factory/.libpulp.new.1945 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libpulp" Mon Oct 23 23:41:34 2023 rev:2 rq:1119704 version:0.3.1 Changes: -------- --- /work/SRC/openSUSE:Factory/libpulp/libpulp.changes 2023-10-19 22:52:34.673875220 +0200 +++ /work/SRC/openSUSE:Factory/.libpulp.new.1945/libpulp.changes 2023-10-23 23:41:39.769049129 +0200 @@ -1,0 +2,6 @@ +Mon Oct 23 16:17:27 UTC 2023 - Giuliano Belinassi <gbelina...@suse.de> + +- Update package with libpulp-0.3.1: + * Add timestamp information on `ulp patches`. + +------------------------------------------------------------------- Old: ---- libpulp-0.3.0.tar.gz New: ---- libpulp-0.3.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libpulp.spec ++++++ --- /var/tmp/diff_new_pack.upOsCd/_old 2023-10-23 23:41:40.361070620 +0200 +++ /var/tmp/diff_new_pack.upOsCd/_new 2023-10-23 23:41:40.365070766 +0200 @@ -17,7 +17,7 @@ Name: libpulp -Version: 0.3.0 +Version: 0.3.1 Release: 0 Summary: Userspace live patching library and tools License: LGPL-2.1-only ++++++ libpulp-0.3.0.tar.gz -> libpulp-0.3.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libpulp-0.3.0/common/common.c new/libpulp-0.3.1/common/common.c --- old/libpulp-0.3.0/common/common.c 2023-04-18 16:11:07.000000000 +0200 +++ new/libpulp-0.3.1/common/common.c 2023-10-20 20:43:59.000000000 +0200 @@ -576,3 +576,40 @@ return info.st_uid; } + +ulp_version_t +ulp_version_from_string(char *str) +{ + ulp_version_t ver[3]; + char *number; + + for (int i = 0; i < 3; i++) { + number = strtok(str, "."); + str = NULL; + if (!isnumber(number)) { + /* Not a number?? */ + return 0; + } + + ver[i] = atoi(number); + if (ver[i] > 0xFFFF) { + /* Out of bound. */ + return 0; + } + } + + return ULP_VERSION_TRIPLET(ver[0], ver[1], ver[2]); +} + +const char * +ulp_version_as_string(ulp_version_t ver) +{ + static char str[18]; // 65535.65535.65535\0 has 18 bytes; + uint16_t a, b, c; + a = (ver & 0x0000FFFF00000000) >> 32; + b = (ver & 0x00000000FFFF0000) >> 16; + c = (ver & 0x000000000000FFFF); + + sprintf(str, "%hu.%hu.%hu", a, b, c); + return str; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libpulp-0.3.0/configure new/libpulp-0.3.1/configure --- old/libpulp-0.3.0/configure 2023-06-27 16:17:43.000000000 +0200 +++ new/libpulp-0.3.1/configure 2023-10-20 23:50:28.000000000 +0200 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.71 for libpulp 0.3.0. +# Generated by GNU Autoconf 2.71 for libpulp 0.3.1. # # Report bugs to <nore...@suse.com>. # @@ -621,8 +621,8 @@ # Identity of this package. PACKAGE_NAME='libpulp' PACKAGE_TARNAME='libpulp' -PACKAGE_VERSION='0.3.0' -PACKAGE_STRING='libpulp 0.3.0' +PACKAGE_VERSION='0.3.1' +PACKAGE_STRING='libpulp 0.3.1' PACKAGE_BUGREPORT='nore...@suse.com' PACKAGE_URL='' @@ -1419,7 +1419,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures libpulp 0.3.0 to adapt to many kinds of systems. +\`configure' configures libpulp 0.3.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1490,7 +1490,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of libpulp 0.3.0:";; + short | recursive ) echo "Configuration of libpulp 0.3.1:";; esac cat <<\_ACEOF @@ -1626,7 +1626,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -libpulp configure 0.3.0 +libpulp configure 0.3.1 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. @@ -1968,7 +1968,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by libpulp $as_me 0.3.0, which was +It was created by libpulp $as_me 0.3.1, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw @@ -3487,7 +3487,7 @@ # Define the identity of the package. PACKAGE='libpulp' - VERSION='0.3.0' + VERSION='0.3.1' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h @@ -19605,7 +19605,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by libpulp $as_me 0.3.0, which was +This file was extended by libpulp $as_me 0.3.1, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -19673,7 +19673,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -libpulp config.status 0.3.0 +libpulp config.status 0.3.1 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libpulp-0.3.0/configure.ac new/libpulp-0.3.1/configure.ac --- old/libpulp-0.3.0/configure.ac 2023-06-27 14:30:32.000000000 +0200 +++ new/libpulp-0.3.1/configure.ac 2023-10-20 23:50:18.000000000 +0200 @@ -17,7 +17,7 @@ # You should have received a copy of the GNU General Public License # along with libpulp. If not, see <http://www.gnu.org/licenses/>. -AC_INIT([libpulp],[0.3.0],[nore...@suse.com]) +AC_INIT([libpulp],[0.3.1],[nore...@suse.com]) # Keep most generated files under the config directory. AC_CONFIG_AUX_DIR([config]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libpulp-0.3.0/include/ulp_common.h new/libpulp-0.3.1/include/ulp_common.h --- old/libpulp-0.3.0/include/ulp_common.h 2023-04-18 16:11:07.000000000 +0200 +++ new/libpulp-0.3.1/include/ulp_common.h 2023-10-20 20:38:50.000000000 +0200 @@ -26,6 +26,7 @@ #include <stdbool.h> #include <stddef.h> #include <stdint.h> +#include <time.h> #define OUT_PATCH_NAME "metadata.ulp" #define OUT_REVERSE_NAME "reverse.ulp" @@ -201,6 +202,9 @@ /** Patch dependency. Not used but kept for backwards compatibility. */ struct ulp_dependency *deps; + + /** Timestamp of when patch was loaded. */ + time_t timestamp; }; struct ulp_applied_unit @@ -222,6 +226,20 @@ struct ulp_applied_unit *next; }; +/** Libpulp version type. The tripplet is incoded here, with a maximum value + of 65535.65535.65535. */ +typedef uint64_t ulp_version_t; + +/** @brief Construct ulp_version object from string. Modifies the string + content. */ +ulp_version_t ulp_version_from_string(char *str); + +/** Build ulp_version_t from three shorts. */ +#define ULP_VERSION_TRIPLET(a, b, c) ((c) + ((b) << 16) + ((a) << 32)) + +/** @brief Construct string from ulp_version object. */ +const char *ulp_version_as_string(ulp_version_t ver); + /* Functions present in libcommon, linked agaist both libpulp.so and tools. */ const char *get_basename(const char *); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libpulp-0.3.0/lib/libpulp.versions new/libpulp-0.3.1/lib/libpulp.versions --- old/libpulp-0.3.0/lib/libpulp.versions 2023-06-26 15:56:35.000000000 +0200 +++ new/libpulp-0.3.1/lib/libpulp.versions 2023-10-19 19:40:02.000000000 +0200 @@ -27,6 +27,7 @@ __ulp_error_state; __ulp_enable_or_disable_patching; __ulp_insn_queue; + __ulp_version; local: *; }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libpulp-0.3.0/lib/ulp.c new/libpulp-0.3.1/lib/ulp.c --- old/libpulp-0.3.0/lib/ulp.c 2023-06-26 15:56:35.000000000 +0200 +++ new/libpulp-0.3.1/lib/ulp.c 2023-10-20 23:36:20.000000000 +0200 @@ -47,6 +47,9 @@ struct ulp_metadata *__ulp_metadata_ref = NULL; struct ulp_detour_root *__ulp_root = NULL; +/* current libpulp version. */ +const char __ulp_version[] = VERSION; + /* clang-format off */ /** Intel endbr64 instruction optcode. */ @@ -828,6 +831,11 @@ unit = unit->next; } + /* Insert timestamp. */ + struct timespec t; + clock_gettime(CLOCK_REALTIME, &t); + a_patch->timestamp = t.tv_sec; + /* leave last on top of list to optmize revert */ prev_patch = __ulp_state.patches; __ulp_state.patches = a_patch; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libpulp-0.3.0/tests/patches.py new/libpulp-0.3.1/tests/patches.py --- old/libpulp-0.3.0/tests/patches.py 2023-06-21 02:17:23.000000000 +0200 +++ new/libpulp-0.3.1/tests/patches.py 2023-10-23 17:37:25.000000000 +0200 @@ -33,7 +33,9 @@ except: exit(1) -if tool.returncode != 0: +# It should actually return an error because we explicitly trieed to retrieve +# information of a non-running process. +if tool.returncode == 0: exit(1) exit(0) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libpulp-0.3.0/tools/arguments.h new/libpulp-0.3.1/tools/arguments.h --- old/libpulp-0.3.0/tools/arguments.h 2023-06-10 00:50:06.000000000 +0200 +++ new/libpulp-0.3.1/tools/arguments.h 2023-10-21 00:21:37.000000000 +0200 @@ -59,6 +59,7 @@ int disable_threads; int recursive; int no_summarization; + int only_livepatched; #if defined ENABLE_STACK_CHECK && ENABLE_STACK_CHECK int check_stack; #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libpulp-0.3.0/tools/introspection.c new/libpulp-0.3.1/tools/introspection.c --- old/libpulp-0.3.0/tools/introspection.c 2023-06-28 22:04:47.000000000 +0200 +++ new/libpulp-0.3.1/tools/introspection.c 2023-10-23 17:10:41.000000000 +0200 @@ -189,12 +189,8 @@ for (; obj != NULL; obj = nexto) { nexto = obj->next; - - if (obj->filename) { - free(obj->filename); - } - if (obj->thread_states) - free(obj->thread_states); + FREE_AND_NULLIFY(obj->filename); + FREE_AND_NULLIFY(obj->thread_states); free(obj); } } @@ -848,16 +844,21 @@ obj->enable_disable_patching = ehdr_addr + sym.st_value; bitfield |= (1 << 8); } - else if (!strcmp(remote_name, "_insn_queue")) { obj->insn_queue = ehdr_addr + sym.st_value; bitfield |= (1 << 9); } + else if (!strcmp(remote_name, "_version")) { + char str[32]; + read_string_allocated(str, sizeof(str), pid, ehdr_addr + sym.st_value); + obj->libpulp_version = ulp_version_from_string(str); + bitfield |= (1 << 10); + } } dynsym_addr += sizeof(sym); - if (bitfield == 0x3FF) + if (bitfield == 0x7FF) break; } @@ -1249,29 +1250,22 @@ ulp_error_t ret = 0; if (!process) - return 1; + return EINVAL; DEBUG("getting in-memory information about process %d.", process->pid); if (attach(process->pid)) { - DEBUG("Unable to attach to %d to read data.\n", process->pid); - ret = 1; + ret = ETARGETHOOK; goto detach_process; } ret = parse_main_dynobj(process); if (ret) { - WARN("unable to get in-memory information about the main executable: %s\n", - libpulp_strerror(ret)); - ret = 1; goto detach_process; } ret = parse_libs_dynobj(process); if (ret) { - WARN("unable to get in-memory information about shared libraries: %s\n", - libpulp_strerror(ret)); - ret = 1; goto detach_process; } @@ -1280,7 +1274,7 @@ if (read_memory((char *)&ulp_state, sizeof(ulp_state), process->pid, process->dynobj_libpulp->state) || ulp_state.load_state == 0) { - WARN("libpulp not ready (constructors not yet run). Try again later."); + DEBUG("libpulp not ready (constructors not yet run). Try again later."); ret = EAGAIN; goto detach_process; } @@ -2432,7 +2426,7 @@ * @return A `ulp_applied_patch` linked list. */ static struct ulp_applied_patch * -read_ulp_applied_patch(Elf64_Addr addr, pid_t pid) +read_ulp_applied_patch(Elf64_Addr addr, pid_t pid, ulp_version_t version) { struct ulp_applied_patch *a_state; @@ -2445,7 +2439,14 @@ return NULL; } - if (read_memory((char *)a_state, sizeof(*a_state), pid, addr)) { + size_t a_patch_size = sizeof(*a_state); + + /* In pre 0.3.1 versions of libpulp, there was no timestamp. */ + if (version < ULP_VERSION_TRIPLET(0ULL, 3ULL, 1ULL)) { + a_patch_size -= sizeof(a_state->timestamp); + } + + if (read_memory((char *)a_state, a_patch_size, pid, addr)) { WARN("error reading patch state."); free(a_state); return NULL; @@ -2461,13 +2462,14 @@ (Elf64_Addr)a_state->container_name); } + /* ulp_applied_unit and ulp_applied_patch is not used, so don't read it. But set it to NULL to avoid dangling pointers. */ a_state->units = NULL; a_state->deps = NULL; - a_state->next = read_ulp_applied_patch((Elf64_Addr)a_state->next, pid); + a_state->next = read_ulp_applied_patch((Elf64_Addr)a_state->next, pid, version); return a_state; } @@ -2527,7 +2529,8 @@ goto detach_process; } - ret = read_ulp_applied_patch((Elf64_Addr)state.patches, pid); + ret = read_ulp_applied_patch((Elf64_Addr)state.patches, pid, + process->dynobj_libpulp->libpulp_version); detach_process: if (detach(process->pid)) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libpulp-0.3.0/tools/introspection.h new/libpulp-0.3.1/tools/introspection.h --- old/libpulp-0.3.0/tools/introspection.h 2023-06-27 14:20:44.000000000 +0200 +++ new/libpulp-0.3.1/tools/introspection.h 2023-10-20 19:55:24.000000000 +0200 @@ -116,6 +116,9 @@ Elf64_Addr enable_disable_patching; Elf64_Addr insn_queue; + /* Version of the libpulp tool running on the target process. */ + ulp_version_t libpulp_version; + /* Version of the insn_queue on target process. */ int insn_queue_version; /* end FIXME. */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libpulp-0.3.0/tools/patches.c new/libpulp-0.3.1/tools/patches.c --- old/libpulp-0.3.0/tools/patches.c 2023-06-26 15:56:35.000000000 +0200 +++ new/libpulp-0.3.1/tools/patches.c 2023-10-23 17:42:24.000000000 +0200 @@ -45,7 +45,7 @@ bool enable_threading = false; static bool original_enable_threading; -void insert_target_process(int pid, struct ulp_process **list); +static int insert_target_process(int pid, struct ulp_process **list); static void * generate_ulp_list_thread(void *args) @@ -131,6 +131,10 @@ symbols. */ static pthread_t process_list_thread; +/** In case of `ulp patches -p <pid>`, we want to return an error for the + caller if something went wrong. */ +static error_t any_error = ENONE; + struct ulp_process * process_list_begin(struct ulp_process_iterator *it, const char *procname_wildcard, const char *user_wildcard) @@ -147,7 +151,7 @@ if (isnumber(procname_wildcard)) { /* If wildcard is actually a number, then treat it as a PID. */ pid = atoi(procname_wildcard); - insert_target_process(pid, &it->last); + any_error = insert_target_process(pid, &it->last); it->now = it->last; /* Disable threading in this case. */ @@ -378,7 +382,11 @@ while (patch) { if (!strcmp(libname, patch->lib_name)) { - printf(" livepatch: %s\n", get_basename(patch->container_name)); + struct tm *timeinfo = localtime(&patch->timestamp); + printf(" livepatch: %s", get_basename(patch->container_name)); + if (patch->timestamp != 0) { + printf(" loaded on %s", asctime(timeinfo)); + } print_relevant_labels(patch->container_name); } patch = patch->next; @@ -547,12 +555,19 @@ change_color(TERM_COLOR_RESET); } -void -print_process(struct ulp_process *process, int print_buildid) +static void +print_process(struct ulp_process *process, int print_buildid, + bool only_livepatched) { struct ulp_dynobj *object_item; pid_t pid = process->pid; struct ulp_applied_patch *patch = ulp_read_state(process); + + /* In case the flag `only_patched` is NULL, then skip process. */ + if (only_livepatched && patch == NULL) { + return; + } + printf("PID: %d, name: %s\n", pid, get_process_name(process)); print_remote_err_status(process); printf(" Livepatchable libraries:\n"); @@ -564,6 +579,11 @@ printf(" in %s", object_item->filename); if (print_buildid) printf(" (%s)", buildid_to_string(object_item->build_id)); + if (object_item->libpulp_version) { + const char *version = + ulp_version_as_string(object_item->libpulp_version); + printf(" (version %s)", version); + } printf(":\n"); print_lib_patches(patch, object_item->filename); @@ -604,7 +624,7 @@ /* Inserts a new process structure into LIST if the process identified * by PID is live-patchable. */ -void +static int insert_target_process(int pid, struct ulp_process **list) { struct ulp_process *new = NULL; @@ -615,14 +635,16 @@ new->pid = pid; ret = initialize_data_structures(new); if (ret) { - WARN("error gathering target process information."); + WARN("error gathering target process information: %s", + libpulp_strerror(ret)); release_ulp_process(new); - return; + return ret; } else { new->next = *list; *list = new; } + return 0; } /** @brief Prints all the info collected about the processes in `process_list`. @@ -637,7 +659,7 @@ process_item = process_list; while (process_item) { - print_process(process_item, print_buildid); + print_process(process_item, print_buildid, false); process_item = process_item->next; } } @@ -646,6 +668,7 @@ run_patches(struct arguments *arguments) { bool print_build_id = arguments->buildid; + bool only_livepatched = arguments->only_livepatched; ulp_quiet = arguments->quiet; ulp_verbose = arguments->verbose; enable_threading = !arguments->disable_threads; @@ -653,11 +676,12 @@ const char *user_wildcard = arguments->user_wildcard; struct ulp_process *p; + any_error = ENONE; FOR_EACH_ULP_PROCESS_FROM_USER_WILDCARD(p, process_wildcard, user_wildcard) { - print_process(p, print_build_id); + print_process(p, print_build_id, only_livepatched); } - return 0; + return any_error == 0 ? 0 : 1; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libpulp-0.3.0/tools/ulp.c new/libpulp-0.3.1/tools/ulp.c --- old/libpulp-0.3.0/tools/ulp.c 2023-06-10 00:50:06.000000000 +0200 +++ new/libpulp-0.3.1/tools/ulp.c 2023-10-21 00:21:16.000000000 +0200 @@ -130,6 +130,7 @@ #define ULP_OP_DISABLE_THREADING 260 #define ULP_OP_RECURSIVE 261 #define ULP_OP_DISABLE_SUMMARIZATION 262 +#define ULP_OP_ONLY_LIVEPATCHED 263 static struct argp_option options[] = { { 0, 0, 0, 0, "Options:", 0 }, @@ -142,6 +143,7 @@ "Do not launch additional threads", 0 }, { 0, 0, 0, 0, "dump & patches command only:", 0 }, { "buildid", 'b', 0, 0, "Print the build id", 0 }, + { "only-livepatched", ULP_OP_ONLY_LIVEPATCHED, 0, 0, "Print only processes that were livepatched", 0 }, { 0, 0, 0, 0, "trigger command only:", 0 }, { "revert-all", ULP_OP_REVERT_ALL, "LIB", 0, "Revert all patches from LIB. If LIB=target, then all patches from the " @@ -360,6 +362,10 @@ arguments->no_summarization = 1; break; + case ULP_OP_ONLY_LIVEPATCHED: + arguments->only_livepatched = 1; + break; + case 'u': arguments->user_wildcard = arg; break;