{"id":22914095,"url":"https://github.com/suse/libpulp","last_synced_at":"2025-04-09T07:09:46.719Z","repository":{"id":38856488,"uuid":"157335393","full_name":"SUSE/libpulp","owner":"SUSE","description":"libpulp enables live patching in user space applications.","archived":false,"fork":false,"pushed_at":"2025-02-25T00:45:55.000Z","size":1256,"stargazers_count":59,"open_issues_count":18,"forks_count":13,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-04-02T05:07:04.208Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-2.1","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SUSE.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-11-13T07:03:05.000Z","updated_at":"2025-03-06T17:50:53.000Z","dependencies_parsed_at":"2023-02-14T11:15:26.525Z","dependency_job_id":"97a36c78-ad6b-4b79-8138-4181e7e562af","html_url":"https://github.com/SUSE/libpulp","commit_stats":{"total_commits":464,"total_committers":14,"mean_commits":"33.142857142857146","dds":0.6185344827586207,"last_synced_commit":"e7cfd714e0b7c849022000d8810ab1f825a620b8"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SUSE%2Flibpulp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SUSE%2Flibpulp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SUSE%2Flibpulp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SUSE%2Flibpulp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SUSE","download_url":"https://codeload.github.com/SUSE/libpulp/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247994122,"owners_count":21030050,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-14T05:13:19.494Z","updated_at":"2025-04-09T07:09:46.698Z","avatar_url":"https://github.com/SUSE.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Libpulp\n\n[![status](https://github.com/SUSE/libpulp/actions/workflows/test-suite.yml/badge.svg)](https://github.com/SUSE/libpulp/actions/workflows/test-suite.yml)\n\n# Table of contents\n\n1. [Introduction](#introduction)\n    1. [Getting started](#getting-started)\n    1. [License](#license)\n    1. [Known issues](#known-issues)\n1. [Contributing](#contributing)\n    1. [Coding style](#coding-style)\n    1. [Project structure](#project-structure)\n1. [Consistency](#consistency)\n1. [The patching process](#the-patching-process)\n1. [Description file syntax](#description-file-syntax)\n\n# Introduction\n\nLibpulp is a framework that enables userspace live patching. It is composed of a\nlibrary per se and a collection of tools used in the preparation of\nlive-patchable libraries and in the application of live patches to running\nprocesses. In order to be live-patchable, a library must be compiled with\npatchable function entries\u003csup\u003e1\u003c/sup\u003e, but no changes to the library\nsource-code are needed. Apart from that, processes must preload \u003csup\u003e2\u003c/sup\u003e\n_libpulp.so_ in order to be live-patchable.\n\n\u003csup\u003e1\u003c/sup\u003e _GCC provides the -fpatchable-function-entry option, which adds nop\ninstructions to the prologue of functions. These nops are used by Libpulp to\ndivert the execution flow when live patches are applied._\n\n\u003csup\u003e2\u003c/sup\u003e _Live-patchable libraries do not explicitly require libpulp to be\nloaded at process initialization, instead, system administrators must start\nprocesses with LD_PRELOAD=libpulp.so, when they want to be able to live patch\nthem._\n\n## Getting started\n\nBuilding and running the test suite is probably the fastest way to get started\nwith Libpulp. The build system is based on GNU autotools, so, from a fresh\ncheckout of the repository, the typical build commands are enough:\n\n```\n./bootstrap\n./configure\nmake\nmake check\n```\n\nThe test suite, apart from avoiding unintentional regressions during\ndevelopment, provides several examples on how to use Libpulp. The oldest of the\ntest cases, _numserv.py_, is also one of the easiest to understand: it starts\nthe _numserv_ application, which loads two live-patchable libraries, then\ninteracts with it, applying live patches and checking the results. It is a good\nplace to get started. Likewise, the _parameters.py_ test case is also simple and\na good starting point.\n\n## License\n\nLibpulp is free software; you can redistribute it and/or modify it under the\nterms of the GNU Lesser General Public License as published by the Free Software\nFoundation; either version 2.1 of the License, or (at your option) any later\nversion.\n\n# Contributing\n\nContributions are welcome! You are welcome to open bug reports at the git\nhosting platform, submit patches through merge requests, or email any of them to\nour mailing list (https://lists.opensuse.org/ulp-devel).\n\n## Coding Style\n\nThe easiest way to adhere to the coding style is to use the following command,\nwhich will read the contents of the .clang-format file and apply the rules\ndescribed in it to _filename_. However, notice that using this only makes sense\nwith .c and .h files.\n\n```\nclang-format -style=file _filename_\n```\n\nThe style is the same that is used in the GNU project, except that:\n\n  1. Eight spaces DO NOT become a TAB character; TABs are avoided;\n  2. Opening curly braces in control statements (if, while, switch, etc) remain\n     on the same line; only curly braces on the first column, such as for\n     function and struct definitions, need a newline;\n  3. Opening parentheses are only preceded by a space in controls statements\n     (if, while, switch, etc); not in function or macro calls;\n  4. Cases in switch statements add one indentation level;\n  5. Backslashes at the end of lines need not be aligned;\n  6. Breaking lines either before or after operators are allowed.\n\n## Project structure\n\nThe directory hierarchy is divided into the following major components:\n\n#### lib\n\nThis directory mostly contains the files that make-up _libpulp.so_, the library\nthat programs must preload to become live-patchable processes. This library is\nbuilt from just a few files: _ulp.c_, which contains the bulk of the live\npatching routines; _ulp_prologue.S_, which contains a routine that live patched\nfunctions call to save and restore registers; and _ulp_interface.S_, which\ncontains the entry-point functions that the _Trigger_ and _Check_ tools use to\napply and check live patches.\n\n#### tools\n\nThe following tools comprise the tool set of Libpulp:\n\n * _Post_: This tool converts sequences of one-byte nops at the entry of\n   patchable functions into multi-byte nops.\n\n * _Packer_: This tool integrates the live patch metadata out of a description file\n   into a livepatch container (.so file). The description file syntax is described in\n   its own [section](#description-file-syntax).\n\n * _Trigger_: This tool is used to apply or revert a livepatch, or a series of\n   livepatches.\n\n * _Check_: This tool introspects into a target process and verifies if a given\n   patch was applied.\n\n * _Dump_: This tool parses and dumps the contents of a live patch container.\n\n * _Patches_: This tool checks which processes has livepatching capabilities\n   loaded, as well as showing which livepatches are applied.\n\n * _Messages_: This tool retrieves the libpulp.so internal messages.\n\n#### tests\n\nThis directory contains everything related to the test suite, which can be\nexecute with 'make check'. Python files are scripts that start the to-be-patched\nprocesses (preloading _libpulp.so_), apply live patches, and poke them to verify\nthat their outputs changed accordingly. Files with the _\\_livepatch_ suffix are\nbuilt into the live patches per se. Everything else is test libraries and\napplications.\n\n# The patching process\n\nA live patch is built on top of existing libraries. The Libpulp framework\nprovides the tools to create the patches. Once the patch is created, it is\napplied through a ptrace-based tool, that will: attach to the target process;\ncheck if it is compliant with live patching; verify that the target library\nis properly loaded into its address space; through control-flow redirection, use\nroutines from Libpulp to make the process load the new version of the functions\nto its address space; then, through adding detours to the old function\nprologues, ensure that only the new version of the functions are invoked.\n\nThe detours are not patched directly on top of previously existing functions.\nInstead, every function must be emitted by gcc with an area of padding nops\nwhich is then overwritten. Once overwritten, the new instructions transfer\ncontrol to a selection routine, which has access to all live patches and\nre-transfers control to the currently active version of the target function\n(functions can be live patched multiple times, and live patches can be\ndeactivated, which causes the previous version (or the baseline) to become\nactive again).\n\n# Description file syntax\n\nThe live patching metadata is built from a description file which should be\nwritten with the following syntax:\n\n```\n1: \u003cabsolute path of .so with patching functions\u003e\n2: @\u003cabsolute path of the targeted library\u003e\n3: \u003cold_fname_1\u003e:\u003cnew_fname_1\u003e\n4: \u003cold_fname_2\u003e:\u003cnew_fname_2\u003e\n5: #\u003cvar1\u003e:\u003cvar1ref\u003e:\u003cvar1_offset\u003e:\u003cvar1ref_offset\u003e\n6: #\u003cvar2\u003e:\u003cvar2ref\u003e:\u003cvar2_offset\u003e:\u003cvar2ref_offset\u003e\n6: #%\u003ctlsvar1\u003e:\u003ctlsvar1ref\u003e:\u003ctlsvar1_offset\u003e:\u003ctlsvar1ref_offset\u003e\n...\n```\n\nLine 1 provides the absolute path of a .so file that contains all the functions\nwhich will be used to replace functions in the running process. Line 2 provides\nthe absolute path for the library that will be patched; it must be preceded by\n'@'. Lines 3 and 4 specify pairs of replaced and replacing functions (there\ncould be more lines if more functions need replacing). Lines 5 and 6 specify\nthe offsets that local (not-exported) variables in the target library have from\nthe beginning of the library load location, as well as the offsets of\nreferences to those variables in the live patch object. If the local variable\nline contains a %, it indicates that it is a Thread Local Storage (TLS) variable.\nThese offsets are used by Libpulp to enable access to local variables from the\nlive patch.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsuse%2Flibpulp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsuse%2Flibpulp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsuse%2Flibpulp/lists"}