├── .clang-format
├── .github
└── workflows
│ ├── coding-style.yml
│ └── test-suite.yml
├── .gitignore
├── LICENSE
├── Makefile.am
├── Makefile.common
├── README.md
├── bootstrap
├── common
├── Makefile.am
├── common.c
└── insn_queue.c
├── config
└── .gitignore
├── configure.ac
├── docs
├── Doxyfile.in
└── Makefile.am
├── examples
├── README.md
└── cplusplus
│ ├── 1-class
│ ├── Makefile
│ ├── README.md
│ ├── a_livepatch1.cpp
│ ├── a_livepatch1.dsc
│ └── class.cpp
│ ├── 2-private_class
│ ├── Makefile
│ ├── README.md
│ ├── a_livepatch1.cpp
│ ├── a_livepatch1.dsc
│ └── class.cpp
│ ├── 3-indirect_call
│ ├── Makefile
│ ├── README.md
│ ├── a_livepatch1.cpp
│ ├── a_livepatch1.dsc
│ └── class.cpp
│ ├── 4-global_var
│ ├── Makefile
│ ├── README.md
│ ├── a_livepatch1.cpp
│ ├── a_livepatch1.dsc
│ └── test.cpp
│ └── 5-queue
│ ├── Makefile
│ ├── README.md
│ ├── a_livepatch1.cpp
│ ├── a_livepatch1.dsc
│ └── class.cpp
├── include
├── .gitignore
├── Makefile.am
├── arch
│ ├── powerpc64le
│ │ └── arch_common.h
│ └── x86_64
│ │ └── arch_common.h
├── error.h
├── error_common.h
├── insn_queue.h
├── insn_queue_lib.h
├── interpose.h
├── ld_rtld.h
├── minielf.h
├── msg_queue.h
├── terminal_colors.h
├── ulp.h
└── ulp_common.h
├── lib
├── Makefile.am
├── arch
│ ├── powerpc64le
│ │ ├── patch.c
│ │ ├── ulp_interface.S
│ │ └── ulp_prologue.S
│ └── x86_64
│ │ ├── patch.c
│ │ └── ulp_interface.S
├── error.c
├── gdb_interface.c
├── insn_queue.c
├── interpose.c
├── libpulp.versions
├── minielf.c
├── msg_queue.c
└── ulp.c
├── man
├── Makefile.am
├── libpulp.7
└── ulp.1
├── patches
└── gcc
│ └── fix-pfe-section-flags.diff
├── scripts
├── Makefile.am
├── collect.sh
├── common_lib.sh
├── dispatcher.lua
├── extract_function.sh
├── glibc.sh
├── setup_package.sh
└── ulp_apply.sh
├── tests
├── Makefile.am
├── README.Makefile.am
├── access.c
├── access.py
├── access2.c
├── access2.py
├── asunsafe_conversion.c
├── asunsafe_conversion.py
├── block_mprotect.c
├── blocked.c
├── blocked.py
├── buildid.c
├── buildid.py
├── cancel.c
├── cancel.py
├── chroot.c
├── chroot.py
├── comments.c
├── comments.py
├── constructor-template.c
├── constructor.c
├── constructor.py
├── contract.c
├── contract.py
├── deadlock.c
├── deadlock.py
├── dlsym.c
├── dlsym_lock.py
├── dozens.c
├── dozens.h
├── endbr64.c
├── endbr64.py
├── exception_handling.cc
├── exception_handling.py
├── fuz
│ ├── 1
│ ├── 2
│ ├── 3
│ ├── 4
│ ├── 5
│ ├── 6
│ ├── 7
│ └── README.md
├── glibc_private.py
├── group_disable.py
├── hidden.py
├── hundreds.c
├── hundreds.h
├── insn_queue.c
├── insn_queue.py
├── libaccess.c
├── libaccess.h
├── libaccess_livepatch1.c
├── libaccess_livepatch1.in
├── libaccess_livepatch2.c
├── libaccess_livepatch2.in
├── libaddress.c
├── libaddress.h
├── libaddress_livepatch1.c
├── libaddress_livepatch1.in
├── libblocked.c
├── libblocked.h
├── libblocked_livepatch1.c
├── libblocked_livepatch1.in
├── libbuildid.c
├── libbuildid_livepatch1.c
├── libbuildid_livepatch1.in
├── libcomments_livepatch1.c
├── libcomments_livepatch1.in
├── libconstructor.c
├── libconstructor.h
├── libcontract.c
├── libcontract.h
├── libcontract_livepatch1.c
├── libcontract_livepatch1.in
├── libdozens_bsymbolic_livepatch1.in
├── libdozens_livepatch1.c
├── libdozens_livepatch1.in
├── libdozens_livepatch99.c
├── libdozens_livepatch99.in
├── libendbr64.c
├── libendbr64_livepatch1.in
├── libexception.cc
├── libexception.h
├── libhundreds_bsymbolic_livepatch1.in
├── libhundreds_livepatch1.c
├── libhundreds_livepatch1.in
├── libhundreds_livepatch2.c
├── libhundreds_livepatch2.in
├── libhundreds_livepatch3.c
├── libhundreds_livepatch3.in
├── libmanyprocesses.c
├── libmanyprocesses_livepatch1.c
├── libmanyprocesses_livepatch1.in
├── libnotes_livepatch1.c
├── libnotes_livepatch1.in
├── libpagecross.c
├── libpagecross_livepatch1.c
├── libpagecross_livepatch1.in
├── libpagecross_padding.S
├── libparameters.c
├── libparameters.h
├── libparameters_livepatch1.c
├── libparameters_livepatch1.in
├── libparameters_livepatch2.c
├── libparameters_livepatch2.in
├── libparameters_livepatch3.c
├── libparameters_livepatch3.in
├── libprefix.c
├── libprefix_livepatch1.in
├── libprocess_access_livepatch1.in
├── libprocess_livepatch1.c
├── libprocess_livepatch1.in
├── libpulp_messages.py
├── librecursion.c
├── librecursion.h
├── librecursion2.c
├── librecursion2.h
├── librecursion2_livepatch1.c
├── librecursion2_livepatch1.in
├── librecursion_livepatch1.c
├── librecursion_livepatch1.in
├── libsecdis_livepatch1.c
├── libsecdis_livepatch1.in
├── libstress.c
├── libstress_livepatch1.c
├── libstress_livepatch1.in
├── libtls.c
├── libtls_livepatch1.c
├── libtls_livepatch1.in
├── libvisibility.c
├── libvisibility_livepatch1.c
├── libvisibility_livepatch1.in
├── libvisibility_livepatch2.c
├── libvisibility_livepatch2.in
├── livepatchable.py
├── loop.c
├── manyprocesses.c
├── manyprocesses.py
├── memory_protection.c
├── memory_protection.py
├── missing_function.py
├── mprotect_patch.py
├── nolibpulp.py
├── notes.c
├── notes.ld
├── notes.py
├── numserv.c
├── numserv.py
├── numserv_bsymbolic.py
├── offsets.py
├── pagecross.c
├── pagecross.py
├── parameters.c
├── parameters.py
├── patches.py
├── path_disable.py
├── pcqueue.c
├── pcqueue.py
├── prefix.c
├── prefix.py
├── process.c
├── process.py
├── process_access.c
├── process_access.py
├── process_access_livepatch1.c
├── process_revert.py
├── recursion.c
├── recursion.py
├── recursion2.c
├── recursion2.py
├── redzone.c
├── redzone.py
├── relative_path.py
├── revert.py
├── revert_all.py
├── revert_all_target1.py
├── revert_all_target2.py
├── revert_and_patch.py
├── revert_with_invalid.py
├── run_libc.py
├── seccomp_disable.py
├── set_patchable.py
├── stress.c
├── stress.py
├── syscall_restart.c
├── syscall_restart.py
├── tempfiles.py
├── terminal.c
├── terminal.py
├── testsuite.py
├── textrel.py
├── tls.c
├── tls.py
├── user_disable.py
├── visibility.c
└── visibility.py
└── tools
├── Makefile.am
├── arch
├── powerpc64le
│ └── post-arch.c
└── x86_64
│ └── post-arch.c
├── arguments.h
├── check.c
├── check.h
├── dump.c
├── dump.h
├── elf-extra.c
├── elf-extra.h
├── extract.c
├── extract.h
├── insn_queue.c
├── insn_queue_tools.h
├── introspection.c
├── introspection.h
├── livepatchable.c
├── livepatchable.h
├── md4.c
├── md4.h
├── messages.c
├── messages.h
├── packer.c
├── packer.h
├── patches.c
├── patches.h
├── pcqueue.c
├── pcqueue.h
├── post.c
├── post.h
├── ptrace.c
├── ptrace.h
├── set_patchable.c
├── set_patchable.h
├── trigger.c
├── trigger.h
└── ulp.c
/.github/workflows/coding-style.yml:
--------------------------------------------------------------------------------
1 | name: Coding Style
2 |
3 | on:
4 | push:
5 | branches: [ master ]
6 | pull_request:
7 | branches: [ master ]
8 |
9 | jobs:
10 | clang-format:
11 | runs-on: ubuntu-latest
12 |
13 | container:
14 | image: opensuse/tumbleweed
15 |
16 | steps:
17 | - name: dependencies
18 | run: zypper -n install clang git findutils file
19 | - uses: actions/checkout@v2
20 | - name: format
21 | run: find -type f \( -name "*.[c|h]" -or -name "*.cc" \) -exec clang-format -style=file -i {} \;
22 | - name: verify
23 | run: /bin/bash -c "git status --short | file - | grep empty"
24 | id: verify
25 | - name: diagnostics
26 | if: failure() && steps.verify.outcome == 'failure'
27 | run: git diff
28 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.tar.*
2 | Makefile.in
3 | configure
4 | aclocal.m4
5 | autom4te.cache
6 | *~
7 | *.swp
8 | dev/
9 |
--------------------------------------------------------------------------------
/Makefile.am:
--------------------------------------------------------------------------------
1 | # libpulp - User-space Livepatching Library
2 | #
3 | # Copyright (C) 2020-2021 SUSE Software Solutions GmbH
4 | #
5 | # This file is part of libpulp.
6 | #
7 | # libpulp is free software; you can redistribute it and/or
8 | # modify it under the terms of the GNU Lesser General Public
9 | # License as published by the Free Software Foundation; either
10 | # version 2.1 of the License, or (at your option) any later version.
11 | #
12 | # libpulp is distributed in the hope that it will be useful,
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | # Lesser General Public License for more details.
16 | #
17 | # You should have received a copy of the GNU General Public License
18 | # along with libpulp. If not, see .
19 |
20 | ACLOCAL_AMFLAGS = -I config
21 |
22 | SUBDIRS = include common lib man tools tests docs scripts
23 |
24 | EXTRA_DIST = LICENSE README.md
25 |
--------------------------------------------------------------------------------
/bootstrap:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | #Colors for colored print messages.
4 | RED='\033[0;31m'
5 | RESET='\033[0m'
6 |
7 |
8 | # Abort program with message.
9 | abort()
10 | {
11 | echo -e "${RED}ERROR: $@${RESET}"
12 | exit 1
13 | }
14 |
15 |
16 | # Check the folowing commands is available to this shell.
17 | check_existence()
18 | {
19 | local tool_available
20 | local tools='libtoolize aclocal autoheader automake autoconf'
21 |
22 | for tool in $tools; do
23 | $tool --version > /dev/null
24 | tool_available=$?
25 |
26 | if [ $tool_available -ne 0 ]; then
27 | abort "$tool not found, but is required by bootstrap"
28 | fi
29 | done
30 | }
31 |
32 | # Check existence of commands. On failure, user must install the missing
33 | # packages.
34 | check_existence
35 |
36 | # Run the bootstrap process
37 | libtoolize -c
38 | aclocal
39 | autoheader
40 | automake --add-missing -c
41 | autoconf
42 |
--------------------------------------------------------------------------------
/common/Makefile.am:
--------------------------------------------------------------------------------
1 | # libpulp - User-space Livepatching Library
2 | #
3 | # Copyright (C) 2020-2021 SUSE Software Solutions GmbH
4 | #
5 | # This file is part of libpulp.
6 | #
7 | # libpulp is free software; you can redistribute it and/or
8 | # modify it under the terms of the GNU Lesser General Public
9 | # License as published by the Free Software Foundation; either
10 | # version 2.1 of the License, or (at your option) any later version.
11 | #
12 | # libpulp is distributed in the hope that it will be useful,
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | # Lesser General Public License for more details.
16 | #
17 | # You should have received a copy of the GNU General Public License
18 | # along with libpulp. If not, see .
19 |
20 | # Static library shared among the tools.
21 | noinst_LTLIBRARIES = libcommon.la
22 |
23 | # Ensure access to the include directory
24 | AM_CFLAGS += -I$(abs_top_srcdir)/include
25 |
26 | # Add -fno-strict-alias to the insn_queue code.
27 | insn_queue.lo : CFLAGS += -fno-strict-aliasing
28 |
29 | libcommon_la_SOURCES = common.c insn_queue.c
30 |
--------------------------------------------------------------------------------
/config/.gitignore:
--------------------------------------------------------------------------------
1 | compile
2 | config.guess
3 | config.sub
4 | depcomp
5 | install-sh
6 | libtool.m4
7 | ltmain.sh
8 | lt~obsolete.m4
9 | ltoptions.m4
10 | ltsugar.m4
11 | ltversion.m4
12 | missing
13 | test-driver
14 |
--------------------------------------------------------------------------------
/docs/Makefile.am:
--------------------------------------------------------------------------------
1 | if HAVE_DOXYGEN
2 | directory = $(top_srcdir)/docs/man/man3
3 |
4 | man_MANS = $(directory)
5 |
6 | $(directory): doxyfile.stamp
7 |
8 | doxyfile.stamp: Doxyfile
9 | $(DOXYGEN) $^
10 | if HAVE_PDFLATEX
11 | cd latex && $(MAKE)
12 | endif
13 | echo Timestamp > $@
14 |
15 | CLEANFILES = doxyfile.stamp
16 |
17 | all-local: doxyfile.stamp
18 | clean-local:
19 | rm -rf $(top_builddir)/docs/man
20 |
21 | endif
22 |
--------------------------------------------------------------------------------
/examples/README.md:
--------------------------------------------------------------------------------
1 | # Userspace Livepatch Examples.
2 |
3 | This folder contain livepatching examples. Once you compile the example hitting
4 | `make`, it will generate two files:
5 |
6 | 1. `test`
7 | 2. `a_livepatch1.so`
8 |
9 | The first file is a binary and should be run with `libpulp.so` loaded. Assuming
10 | libpulp is installed in `/usr/local/lib64/libpulp.so.0`, that is:
11 | ```
12 | $ LD_PRELOAD=/usr/local/lib64/libpulp.so.0 ./test
13 | ```
14 |
15 | The second file is the livepatch and should be applied with the `ulp` tool by
16 | running:
17 | ```
18 | $ ulp trigger a_livepatch.so
19 | ```
20 |
21 | Have fun and happy livepatching!
22 |
--------------------------------------------------------------------------------
/examples/cplusplus/1-class/Makefile:
--------------------------------------------------------------------------------
1 | CXX=g++
2 | CXXFLAGS=-O2 -fpatchable-function-entry=16,14 -fPIC -g3
3 | ULP=$(shell which ulp 2>/dev/null)
4 | LDFLAGS=
5 |
6 | ifeq ($(ULP),)
7 | $(error Not found ulp, please make install first)
8 | endif
9 |
10 | all: test a_livepatch1.so
11 |
12 | test: class.o
13 | $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)
14 |
15 | %.so: %.o %.dsc
16 | $(CXX) $(CXXFLAGS) -shared -o $@ $<
17 | $(ULP) packer $(word 2, $^)
18 |
19 | %.o: %.cpp
20 | $(CXX) $(CXXFLAGS) -c $^ -o $@
21 |
22 | clean:
23 | rm -f test *.o *.so
24 |
25 | clena: clean
26 |
--------------------------------------------------------------------------------
/examples/cplusplus/1-class/README.md:
--------------------------------------------------------------------------------
1 | # Example: Live Patching a C++ ordinary class
2 | ## About
3 | In this test we have two files: `class.cpp` and `a_livepatch1.cpp`. The first
4 | one contain code in C++ for a test program which print the contents of a
5 | `point` class, where the second one contains a livepatch that modifies the
6 | `Print` method so it prints content differently.
7 |
8 | ## Live Patching C++ methods
9 | C++ methods can be live patched the same way as C functions. However, for
10 | libpulp to find the symbols in the original target binary, you should write
11 | the mangled name instead of the C++ original name of the method.
12 |
13 | So instead of writing `Point3D::Print`, one should write `_ZN7Point3D5PrintEv`.
14 | The original declaration of the class should be copied as well (see
15 | `a_livepatch1.cpp` and `a_livepatch1.dsc`).
16 |
--------------------------------------------------------------------------------
/examples/cplusplus/1-class/a_livepatch1.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | class Point
4 | {
5 | protected:
6 | int x, y;
7 |
8 | public:
9 | Point(int x, int y);
10 |
11 | int Get_X(void) const;
12 | int Get_Y(void) const;
13 |
14 | void Print_LP(void);
15 | };
16 |
17 | class Point3D : public Point
18 | {
19 | protected:
20 | int z;
21 |
22 | public:
23 | Point3D(int x, int y, int z);
24 |
25 | int Get_Z(void) const;
26 |
27 | void Print_LP(void);
28 | };
29 |
30 | void Point::Print_LP(void)
31 | {
32 | std::cout << x + 1 << ' ' << y + 1 << '\n';
33 | }
34 |
35 | void Point3D::Print_LP(void)
36 | {
37 | std::cout << x + 1 << ' ' << y + 1 << ' ' << z << '\n';
38 | }
39 |
--------------------------------------------------------------------------------
/examples/cplusplus/1-class/a_livepatch1.dsc:
--------------------------------------------------------------------------------
1 | a_livepatch1.so
2 | @./test
3 | _ZN7Point3D5PrintEv:_ZN7Point3D8Print_LPEv
4 |
--------------------------------------------------------------------------------
/examples/cplusplus/1-class/class.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | class Point
5 | {
6 | protected:
7 | int x, y;
8 |
9 | public:
10 | Point(int x, int y);
11 |
12 | int Get_X(void) const;
13 | int Get_Y(void) const;
14 |
15 | void Print(void);
16 | };
17 |
18 | class Point3D : public Point
19 | {
20 | protected:
21 | int z;
22 |
23 | public:
24 | Point3D(int x, int y, int z);
25 |
26 | int Get_Z(void) const;
27 |
28 | void Print(void);
29 | };
30 |
31 | int Point::Get_X(void) const
32 | {
33 | return x;
34 | }
35 |
36 | int Point::Get_Y(void) const
37 | {
38 | return y;
39 | }
40 |
41 | // Will be livepatched
42 | void Point::Print(void)
43 | {
44 | std::cout << Get_X() << ' ' << Get_Y() << '\n';
45 | }
46 |
47 | Point::Point(int x, int y)
48 | {
49 | this->x = x;
50 | this->y = y;
51 | }
52 |
53 | Point3D::Point3D(int x, int y, int z) : Point(x, y)
54 | {
55 | this->z = z;
56 | }
57 |
58 | int Point3D::Get_Z(void) const
59 | {
60 | return z;
61 | }
62 |
63 | // Will be livepatched
64 | void Point3D::Print(void)
65 | {
66 | std::cout << Get_X() << ' ' << Get_Y() << ' ' << Get_Z() << '\n';
67 | }
68 |
69 | int main(void)
70 | {
71 | Point3D p(3, 4, 5);
72 | while (1) {
73 | p.Print();
74 | sleep(1);
75 | }
76 |
77 | return 0;
78 | }
79 |
--------------------------------------------------------------------------------
/examples/cplusplus/2-private_class/Makefile:
--------------------------------------------------------------------------------
1 | CXX=g++
2 | CXXFLAGS=-O2 -fpatchable-function-entry=16,14 -fdump-ipa-clones -fPIC -g3
3 | ULP=$(shell which ulp 2>/dev/null)
4 | LDFLAGS=
5 |
6 | ifeq ($(ULP),)
7 | $(error Not found ulp, please make install first)
8 | endif
9 |
10 | all: test a_livepatch1.so
11 |
12 | test: class.o
13 | $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)
14 |
15 | %.so: %.o %.dsc
16 | $(CXX) $(CXXFLAGS) -shared -o $@ $<
17 | $(ULP) packer $(word 2, $^)
18 |
19 | %.o: %.cpp
20 | $(CXX) $(CXXFLAGS) -c $^ -o $@
21 |
22 | clean:
23 | rm -f test *.o *.so *.ipa-clones
24 |
25 | clena: clean
26 |
--------------------------------------------------------------------------------
/examples/cplusplus/2-private_class/a_livepatch1.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | typedef double vec3_t[3];
4 |
5 | double norm3_lp(vec3_t v)
6 | {
7 | return cbrt(v[0]*v[0]*v[0] + v[1]*v[1]*v[1] + v[2]*v[2]*v[2]);
8 | }
9 |
--------------------------------------------------------------------------------
/examples/cplusplus/2-private_class/a_livepatch1.dsc:
--------------------------------------------------------------------------------
1 | a_livepatch1.so
2 | @./test
3 | _ZL4normPd:_Z8norm3_lpPd:40122e
4 |
--------------------------------------------------------------------------------
/examples/cplusplus/2-private_class/class.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | typedef double vec3_t[3];
6 | #define noinline __attribute__((noinline))
7 |
8 | static double dot(vec3_t u, vec3_t v)
9 | {
10 | return u[0]*v[0] + u[1]*v[1] + u[2]*v[2];
11 | }
12 |
13 | // Will be livepatched.
14 | static noinline double norm(vec3_t v)
15 | {
16 | return sqrt(dot(v, v));
17 | }
18 |
19 | class Point
20 | {
21 | protected:
22 | double x, y;
23 |
24 | public:
25 | Point(double x, double y);
26 |
27 | double Get_X(void) const;
28 | double Get_Y(void) const;
29 | };
30 |
31 | class Point3D : public Point
32 | {
33 | protected:
34 | double z;
35 |
36 | public:
37 | Point3D(double x, double y, double z);
38 | double Norm(void);
39 |
40 | double Get_Z(void) const;
41 |
42 | };
43 |
44 | double Point::Get_X(void) const
45 | {
46 | return x;
47 | }
48 |
49 | double Point::Get_Y(void) const
50 | {
51 | return y;
52 | }
53 |
54 | Point::Point(double x, double y)
55 | {
56 | this->x = x;
57 | this->y = y;
58 | }
59 |
60 | Point3D::Point3D(double x, double y, double z) : Point(x, y)
61 | {
62 | this->z = z;
63 | }
64 |
65 | double Point3D::Get_Z(void) const
66 | {
67 | return z;
68 | }
69 |
70 | double Point3D::Norm(void)
71 | {
72 | vec3_t v = {x, y, z};
73 | return norm(v);
74 | }
75 |
76 | extern "C" double some_function(vec3_t v)
77 | {
78 | return norm(v) * norm(v);
79 | }
80 |
81 | int main(void)
82 | {
83 | Point3D p(3, 4, 5);
84 | while (1) {
85 | std::cout << p.Norm() << '\n';
86 | sleep(1);
87 | }
88 |
89 | return 0;
90 | }
91 |
--------------------------------------------------------------------------------
/examples/cplusplus/3-indirect_call/Makefile:
--------------------------------------------------------------------------------
1 | CXX=g++
2 | CXXFLAGS=-O2 -fpatchable-function-entry=16,14 -fdump-ipa-clones -fPIC -g3
3 | ULP=$(shell which ulp 2>/dev/null)
4 | LDFLAGS=
5 |
6 | ifeq ($(ULP),)
7 | $(error Not found ulp, please make install first)
8 | endif
9 |
10 | all: test a_livepatch1.so
11 |
12 | test: class.o
13 | $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)
14 |
15 | %.so: %.o %.dsc
16 | $(CXX) $(CXXFLAGS) -shared -o $@ $<
17 | $(ULP) packer $(word 2, $^)
18 |
19 | %.o: %.cpp
20 | $(CXX) $(CXXFLAGS) -c $^ -o $@
21 |
22 | clean:
23 | rm -f test *.o *.so *.ipa-clones
24 |
25 | clena: clean
26 |
--------------------------------------------------------------------------------
/examples/cplusplus/3-indirect_call/README.md:
--------------------------------------------------------------------------------
1 | # Example: Calling private non-inlined non-externalized function available in original binary
2 | ## About
3 | This example illustrates how we can use code that is already available in the
4 | original library. For this to work correctly, the function or method should not
5 | have been inlined, so it is callable.
6 |
7 | ## The example
8 |
9 | In this example we have two files: `class.cpp` and `a_livepatch1.cpp`. The
10 | first file contains code to calculate the norm of a 2D point and print its
11 | results. In the second file it contains a livepatch to replace the 2-norm
12 | with a 3-Norm. The print call goes untouched, and since it is not inlined,
13 | the original method can be called without problems.
14 |
15 | ## Live Patching
16 |
17 | This example is crafted so that the method `Print` is not inlined into `Norm`,
18 | as can be seen by the `noinline` declaration of it.
19 |
20 | ### Reference to non-externalized symbol
21 |
22 | Since the symbol is not externalized, we have to get the reference to the
23 | target function manually instead of relying on `ld` to find it to us.
24 |
25 | For us to be able to call this method, we must declare a pointer to a method
26 | and call it. This pointer will be filled by libpulp with the address of the
27 | desired method we want to call.
28 |
29 | In `a_livepatch.cpp`:
30 | ```
31 | extern "C" {
32 | double (Point::*Print_LP)(double) = nullptr;
33 | }
34 | ```
35 |
36 | Then on `a_livepatch.dsc`:
37 | ```
38 | #_ZN5Point5PrintEd:Print_LP
39 | ```
40 |
41 | The `#` token will describe that `Print_LP` should be initialized with the
42 | *address* of Point::Print. In case the debug symbols are not available in
43 | the binary, the offset of the symbol can be specified as:
44 | ```
45 | #_ZN5Point5PrintEd:Print_LP:4011fe
46 | ```
47 |
--------------------------------------------------------------------------------
/examples/cplusplus/3-indirect_call/a_livepatch1.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | class Point
4 | {
5 | private:
6 | void Print(double n);
7 |
8 | protected:
9 | double x, y;
10 |
11 | public:
12 | Point(double x, double y);
13 | double Norm_LP(void);
14 | };
15 |
16 | /** This global variable will contain the address of Point::Print once the
17 | livepatch is installed. */
18 | extern "C" {
19 | double (Point::*Print_LP)(double) = nullptr;
20 | }
21 |
22 |
23 | double Point::Norm_LP(void)
24 | {
25 | double n = cbrt(x*x*x + y*y*y);
26 |
27 | /** Since we declare it as a function, we must explicitely pass the 'this'
28 | pointer. */
29 | (this->*Print_LP)(n);
30 | return n;
31 | }
32 |
--------------------------------------------------------------------------------
/examples/cplusplus/3-indirect_call/a_livepatch1.dsc:
--------------------------------------------------------------------------------
1 | a_livepatch1.so
2 | @./test
3 | _ZN5Point4NormEv:_ZN5Point7Norm_LPEv
4 | #_ZN5Point5PrintEd:Print_LP
5 |
--------------------------------------------------------------------------------
/examples/cplusplus/3-indirect_call/class.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | #define noinline __attribute__((noinline))
6 |
7 | class Point
8 | {
9 | private:
10 | void noinline Print(double n);
11 |
12 | protected:
13 | double x, y;
14 |
15 | public:
16 | Point(double x, double y);
17 | double Norm(void);
18 | };
19 |
20 | Point::Point(double x, double y)
21 | {
22 | this->x = x;
23 | this->y = y;
24 | }
25 |
26 | // Will be livepatched;
27 | double Point::Norm(void)
28 | {
29 | double n = sqrt(x*x + y*y);
30 | Print(n);
31 | return n;
32 | }
33 |
34 | void noinline Point::Print(double n)
35 | {
36 | std::cout << "Point: " << x << ' ' << y << ' ' << "Have norm2 = " << n <<'\n';
37 | }
38 |
39 | int main(void)
40 | {
41 | Point p(3, 4);
42 | while (1) {
43 | p.Norm();
44 | sleep(1);
45 | }
46 |
47 | return 0;
48 | }
49 |
--------------------------------------------------------------------------------
/examples/cplusplus/4-global_var/Makefile:
--------------------------------------------------------------------------------
1 | CXX=g++
2 | CXXFLAGS=-O2 -fpatchable-function-entry=16,14 -fdump-ipa-clones -fPIC -g3
3 | ULP=$(shell which ulp 2>/dev/null)
4 | LDFLAGS=
5 |
6 | ifeq ($(ULP),)
7 | $(error Not found ulp, please make install first)
8 | endif
9 |
10 | all: test a_livepatch1.so
11 |
12 | test: test.o
13 | $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)
14 |
15 | %.so: %.o %.dsc
16 | $(CXX) $(CXXFLAGS) -shared -o $@ $<
17 | $(ULP) packer $(word 2, $^)
18 |
19 | %.o: %.cpp
20 | $(CXX) $(CXXFLAGS) -c $^ -o $@
21 |
22 | clean:
23 | rm -f test *.o *.so *.ipa-clones
24 |
25 | clena: clean
26 |
--------------------------------------------------------------------------------
/examples/cplusplus/4-global_var/README.md:
--------------------------------------------------------------------------------
1 | # Example: Calling private non-inlined non-externalized function available in original binary
2 | ## About
3 |
4 | This example illustrates how we can access global variables -- private or
5 | public -- as it may be necessary to create a livepatch. One case where such cases
6 | may happen is to access global locks, as shown in this example.
7 |
8 | In `test.cpp`, there is an accumulator that is protected by a mutex lock. A
9 | livepatch that touches this critical section will have to lock it before doing
10 | any modifications to the `sum` variable.
11 |
12 | ## The example
13 |
14 | In this example we have two files: `test.cpp` and `a_livepatch1.cpp`. The
15 | first file contains code to accumulate into a variable using multiple
16 | threads. The second file contains a patch that set that variable to 0.
17 |
18 | ## Live Patching
19 |
20 | In order to create this livepatch, we have to setup references to the global
21 | variables that needs to be modified. On `a_livepatch.cpp`:
22 | ```
23 | volatile long *sum_ptr = NULL;
24 | pthread_mutex_t *sum_lock_ptr = NULL;
25 | ```
26 | Then on .dsc:
27 | ```
28 | #sum:sum_ptr
29 | #sum_lock:sum_lock_ptr
30 | ```
31 |
32 | with this, the pointers `sum_ptr` and `sum_lock_ptr` will be initialized with
33 | the address of `sum` and `sum_lock`.
34 |
--------------------------------------------------------------------------------
/examples/cplusplus/4-global_var/a_livepatch1.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | /* Pointer to the original sum variable. This will be initialized with the
8 | address of `sum` when the patch is loaded in the program, as described in
9 | the .dsc file. */
10 | volatile long *sum_ptr = NULL;
11 |
12 | /* Pointer to the original lock. */
13 | pthread_mutex_t *sum_lock_ptr = NULL;
14 |
15 | void accumulate_2(long x __attribute__((unused)))
16 | {
17 | assert(sum_ptr && sum_lock_ptr);
18 |
19 | if (pthread_mutex_lock(sum_lock_ptr) != 0) {
20 | abort();
21 | }
22 |
23 | *sum_ptr = 0;
24 |
25 | if (pthread_mutex_unlock(sum_lock_ptr) != 0) {
26 | abort();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/examples/cplusplus/4-global_var/a_livepatch1.dsc:
--------------------------------------------------------------------------------
1 | a_livepatch1.so
2 | @./test
3 | _Z10accumulatel:_Z12accumulate_2l
4 | #sum:sum_ptr
5 | #sum_lock:sum_lock_ptr
6 |
--------------------------------------------------------------------------------
/examples/cplusplus/4-global_var/test.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | #define noinline __attribute__((noinline))
6 | #define NUM_ACCUMULATORS 4
7 |
8 | volatile long sum;
9 | pthread_mutex_t sum_lock = PTHREAD_MUTEX_INITIALIZER;
10 |
11 | /* Accumulate into a global variable. */
12 | // Will be livepatched;
13 | void noinline accumulate(long x)
14 | {
15 | if (pthread_mutex_lock(&sum_lock) != 0) {
16 | abort();
17 | }
18 |
19 | sum += x;
20 |
21 | if (pthread_mutex_unlock(&sum_lock) != 0) {
22 | abort();
23 | }
24 | }
25 |
26 | void *accumulator(void* x)
27 | {
28 | for (long i = 0; i < 100000000L; i++) {
29 | accumulate(i);
30 | }
31 |
32 | return NULL;
33 | }
34 |
35 | int main(void)
36 | {
37 | pthread_t threads[NUM_ACCUMULATORS];
38 |
39 | for (int i = 0; i < NUM_ACCUMULATORS; i++) {
40 | if (pthread_create(&threads[i], NULL, accumulator, NULL) != 0) {
41 | abort();
42 | }
43 | }
44 |
45 | for (int i = 0; i < NUM_ACCUMULATORS; i++) {
46 | if (pthread_join(threads[i], NULL) != 0) {
47 | abort();
48 | }
49 | }
50 |
51 | printf("sum = %ld\n", sum);
52 |
53 | return 0;
54 | }
55 |
--------------------------------------------------------------------------------
/examples/cplusplus/5-queue/Makefile:
--------------------------------------------------------------------------------
1 | CXX=g++
2 | CXXFLAGS=-fpatchable-function-entry=16,14 -fdump-ipa-clones -fPIC -g3 -Wno-terminate -O2
3 | ULP=$(shell which ulp 2>/dev/null)
4 | LDFLAGS=
5 |
6 | ifeq ($(ULP),)
7 | $(error Not found ulp, please make install first)
8 | endif
9 |
10 | all: test a_livepatch1.so
11 |
12 | test: class.o
13 | $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)
14 |
15 | %.so: %.o %.dsc
16 | $(CXX) $(CXXFLAGS) -shared -o $@ $<
17 | $(ULP) packer $(word 2, $^)
18 |
19 | %.o: %.cpp
20 | $(CXX) $(CXXFLAGS) -c $^ -o $@
21 |
22 | clean:
23 | rm -f test *.o *.so *.ipa-clones
24 |
25 | clena: clean
26 |
--------------------------------------------------------------------------------
/examples/cplusplus/5-queue/README.md:
--------------------------------------------------------------------------------
1 | # Example: Live patching template methods
2 | ## About
3 |
4 | This example illustrates how we can livepatch template methods in C++.
5 |
6 | ### C++ templates
7 |
8 | C++ has the ability to generate code according to given parameters by using
9 | `templates`. This is more powerful than C macros and it is very useful to
10 | generate classes or functions for multiple types or multiple predetermined
11 | bounds.
12 |
13 | ## The example
14 |
15 | In this example we have two files: `class.cpp` and `a_livepatch1.cpp`. The
16 | first file contains a template class `Queue` which generates code for each
17 | type and maximum bound. Here we only use the case where MAX = 32 and types
18 | as `long` and `double`. In the second file we have a livepatch which modifies
19 | the code of `Push` to print a message for each type it runs.
20 |
21 | Since the `Queue` is used with two types (`long` and `double`), we have to
22 | generate two functions in the livepatch library. This is shown by the
23 | declarations:
24 | ```
25 | /* Output the modified functions for all types generated. */
26 | template void Queue::Push_LP(long x);
27 | template void Queue::Push_LP(double x);
28 | ```
29 |
30 | which will generate two functions `_ZN5QueueILi32ElE7Push_LPEl` and
31 | `_ZN5QueueILi32EdE7Push_LPEd`.
32 |
33 | ## Live Patching
34 |
35 | Unfortunately since C++ `template` functions are generating according to each
36 | one of the template parameters that are given, you must generate one function
37 | for each one parameter that are used in the program. On our example it is easy,
38 | as the project has one file, the template is expanded to only two types, and
39 | functions are not inlined.
40 |
--------------------------------------------------------------------------------
/examples/cplusplus/5-queue/a_livepatch1.dsc:
--------------------------------------------------------------------------------
1 | a_livepatch1.so
2 | @./test
3 | _ZN5QueueILi32ElE4PushEl:_ZN5QueueILi32ElE7Push_LPEl
4 | _ZN5QueueILi32EdE4PushEd:_ZN5QueueILi32EdE7Push_LPEd
5 |
--------------------------------------------------------------------------------
/include/.gitignore:
--------------------------------------------------------------------------------
1 | config.h.in
2 |
--------------------------------------------------------------------------------
/include/Makefile.am:
--------------------------------------------------------------------------------
1 | # libpulp - User-space Livepatching Library
2 | #
3 | # Copyright (C) 2020-2021 SUSE Software Solutions GmbH
4 | #
5 | # This file is part of libpulp.
6 | #
7 | # libpulp is free software; you can redistribute it and/or
8 | # modify it under the terms of the GNU Lesser General Public
9 | # License as published by the Free Software Foundation; either
10 | # version 2.1 of the License, or (at your option) any later version.
11 | #
12 | # libpulp is distributed in the hope that it will be useful,
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | # Lesser General Public License for more details.
16 | #
17 | # You should have received a copy of the GNU General Public License
18 | # along with libpulp. If not, see .
19 |
20 | noinst_HEADERS = \
21 | ulp.h \
22 | ulp_common.h \
23 | interpose.h \
24 | msg_queue.h \
25 | error.h \
26 | error_common.h \
27 | terminal_colors.h \
28 | ld_rtld.h \
29 | insn_queue.h \
30 | insn_queue_lib.h \
31 | minielf.h
32 |
33 | # Workaround a bug in Autoconf 2.69
34 | if CPU_X86_64
35 | noinst_HEADERS += \
36 | arch/x86_64/arch_common.h
37 | endif
38 |
39 | if CPU_PPC64LE
40 | noinst_HEADERS += \
41 | arch/powerpc64le/arch_common.h
42 | endif
43 |
--------------------------------------------------------------------------------
/include/arch/x86_64/arch_common.h:
--------------------------------------------------------------------------------
1 | #ifndef _ARCH_X86_64_H
2 | #define _ARCH_X86_64_H
3 |
4 | /** Intel endbr64 instruction optcode. */
5 | #define INSN_ENDBR64 0xf3, 0x0f, 0x1e, 0xfa
6 |
7 | /** Offset of TLS pointer. */
8 | #define TLS_DTV_OFFSET 0
9 |
10 | /** Struct used to store the registers in memory. */
11 | typedef struct user_regs_struct registers_t;
12 |
13 | /** Register in which the function stores the return value. */
14 | #define FUNCTION_RETURN_REG(reg) ((reg).rax)
15 |
16 | /** Register which acts as a program counter. */
17 | #define PROGRAM_COUNTER_REG(reg) ((reg).rip)
18 |
19 | /** Register which acts as top of stack. */
20 | #define STACK_TOP_REG(reg) ((reg).rsp)
21 |
22 | /** Set the GLOBAL ENTRYPOINT REGISTER, which in x86_64 doesn't exist. */
23 | #define SET_GLOBAL_ENTRYPOINT_REG(reg, val)
24 |
25 | /** The red zone. */
26 | #define RED_ZONE_LEN 128
27 |
28 | /**
29 | * Number of bytes that the kernel subtracts from the program counter,
30 | * when an ongoing syscall gets interrupted and must be restarted.
31 | */
32 | #define RESTART_SYSCALL_SIZE 2
33 |
34 | #endif
35 |
--------------------------------------------------------------------------------
/include/insn_queue_lib.h:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2023 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #ifndef INSNQ_TOOL_H
23 | #define INSNQ_TOOL_H
24 |
25 | #include "insn_queue.h"
26 |
27 | void *insnq_get_writable_area(insn_queue_t *, size_t insn_size);
28 |
29 | ulp_error_t insnq_insert_print(const char *string);
30 |
31 | ulp_error_t insnq_insert_write(void *addr, int n, const void *bytes);
32 |
33 | int insnq_ensure_emptiness(void);
34 |
35 | /* Not necessary if compiling without gdb interface. */
36 | #ifdef ENABLE_GDB_INTERFACE
37 |
38 | /** Interpret the global instruction queue from process side. */
39 | int insnq_interpret_from_lib(void);
40 |
41 | #endif //ENABLE_GDB_INTERFACE
42 |
43 | #endif
44 |
--------------------------------------------------------------------------------
/include/interpose.h:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | int __ulp_asunsafe_trylock(void);
23 | int __ulp_asunsafe_unlock(void);
24 |
25 | void *get_loaded_symbol_addr(const char *, const char *, void *);
26 |
27 | void *get_loaded_library_base_addr(const char *);
28 |
29 | int get_loaded_library_tls_index(const char *);
30 |
--------------------------------------------------------------------------------
/include/terminal_colors.h:
--------------------------------------------------------------------------------
1 | #ifndef _TERMINAL_COLORS_H
2 | #define _TERMINAL_COLORS_H
3 |
4 | #define TERM_COLOR_RED "\x1b[31;1m"
5 | #define TERM_COLOR_GREEN "\x1b[32;1m"
6 | #define TERM_COLOR_YELLOW "\x1b[33;1m"
7 | #define TERM_COLOR_BLUE "\x1b[34;1m"
8 | #define TERM_COLOR_MAGENTA "\x1b[35;1m"
9 | #define TERM_COLOR_CYAN "\x1b[36;1m"
10 | #define TERM_COLOR_WHITE "\x1b[37;1m"
11 | #define TERM_COLOR_BOLD "\x1b[;1m"
12 | #define TERM_COLOR_RESET "\x1b[0m"
13 |
14 | void change_color(const char *ansi_escape);
15 |
16 | #endif //_TERMINAL_COLORS_H
17 |
--------------------------------------------------------------------------------
/lib/libpulp.versions:
--------------------------------------------------------------------------------
1 | {
2 | global:
3 | /* Interposed from libc and libdl. */
4 | free;
5 | malloc;
6 | calloc;
7 | realloc;
8 | reallocarray;
9 | valloc;
10 | pvalloc;
11 | memalign;
12 | aligned_alloc;
13 | posix_memalign;
14 | dlopen;
15 | dlmopen;
16 | dlclose;
17 | dladdr;
18 | dladdr1;
19 | dlinfo;
20 | __ulp_revert_all;
21 | __ulp_trigger;
22 | __ulp_check_patched;
23 | __ulp_state;
24 | __ulp_get_global_universe;
25 | __ulp_msg_queue;
26 | __ulp_metadata_buffer;
27 | __ulp_error_state;
28 | __ulp_enable_or_disable_patching;
29 | __ulp_insn_queue;
30 | __ulp_version;
31 | gdb_ulp_apply;
32 | gdb_ulp_revert;
33 | local:
34 | *;
35 | };
36 |
--------------------------------------------------------------------------------
/man/Makefile.am:
--------------------------------------------------------------------------------
1 | dist_man1_MANS = \
2 | ulp.1
3 |
4 | dist_man7_MANS = \
5 | libpulp.7
6 |
--------------------------------------------------------------------------------
/patches/gcc/fix-pfe-section-flags.diff:
--------------------------------------------------------------------------------
1 | commit 33011f30120f958b14d8036a38ca27c7456b8244
2 | Author: Joao Moreira
3 | Date: Fri Apr 5 00:47:26 2019 -0300
4 |
5 | Fix gcc section _fpatchable_function_entry flags
6 |
7 | diff --git a/libpulp-0.1/gcc/gcc/targhooks.c b/libpulp-0.1/gcc/gcc/targhooks.c
8 | index 138f8d7..9fbaa25 100644
9 | --- a/libpulp-0.1/gcc/gcc/targhooks.c
10 | +++ b/libpulp-0.1/gcc/gcc/targhooks.c
11 | @@ -1814,7 +1814,7 @@ default_print_patchable_function_entry (FILE *file,
12 | ASM_GENERATE_INTERNAL_LABEL (buf, "LPFE", patch_area_number);
13 |
14 | switch_to_section (get_section ("__patchable_function_entries",
15 | - SECTION_RELRO , NULL));
16 | + SECTION_WRITE | SECTION_RELRO , NULL));
17 | fputs (asm_op, file);
18 | assemble_name_raw (file, buf);
19 | fputc ('\n', file);
20 |
--------------------------------------------------------------------------------
/scripts/Makefile.am:
--------------------------------------------------------------------------------
1 | # libpulp - User-space Livepatching Library
2 | #
3 | # Copyright (C) 2020-2023 SUSE Software Solutions GmbH
4 | #
5 | # This file is part of libpulp.
6 | #
7 | # libpulp is free software; you can redistribute it and/or
8 | # modify it under the terms of the GNU Lesser General Public
9 | # License as published by the Free Software Foundation; either
10 | # version 2.1 of the License, or (at your option) any later version.
11 | #
12 | # libpulp is distributed in the hope that it will be useful,
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | # Lesser General Public License for more details.
16 | #
17 | # You should have received a copy of the GNU General Public License
18 | # along with libpulp. If not, see .
19 |
20 | dist_bin_SCRIPTS=setup_package.sh
21 |
--------------------------------------------------------------------------------
/scripts/collect.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Look for the number of symbols and how many symbols will need to be read to
4 | # decide if a library is livepatchable or not in /usr/lib64 to collect
5 | # statistics.
6 |
7 | get_first_function_symbol()
8 | {
9 | local realfile=$(readlink -f $1)
10 | local symbol=$(readelf -D -sW $realfile | grep -E "FUNC[ ]*GLOBAL[ ]*DEFAULT[ ]*[0-9]+" | head -n 1 | awk '{ print substr($1, 1, length($1)-1) }')
11 | local num_symbols=$(readelf -D -sW $realfile | tail -n 1 | awk '{ print substr($1, 1, length($1)-1) }')
12 |
13 | echo "Analyzing $realfile"
14 | echo "$realfile, $symbol", $num_symbols >> output.csv
15 | }
16 |
17 | rm -f output.csv
18 | for so in $(find "/usr/lib64/" -name "*.so"); do
19 | get_first_function_symbol $so
20 | done
21 |
22 | sort -u output.csv -o output.csv
23 |
--------------------------------------------------------------------------------
/tests/access.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 | #include
24 | #include
25 |
26 | #include
27 |
28 | int
29 | main(void)
30 | {
31 | char buffer[128];
32 |
33 | /* Original banner. */
34 | printf("Banner addr: 0x%lX\n", (unsigned long)banner_get());
35 | printf("%s\n", banner_get());
36 |
37 | /* Use original banner setting function. */
38 | banner_set(strdup("Banner changed from main"));
39 | printf("%s\n", banner_get());
40 |
41 | /* Wait for input. */
42 | if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
43 | if (errno) {
44 | perror("access");
45 | return 1;
46 | }
47 | }
48 |
49 | /*
50 | * Use banner setting function again, which is supposed to have been
51 | * changed by the test driver. The patched function ignores the
52 | * argument, so 'String from main' should not be in the output.
53 | */
54 | banner_set("String from main");
55 | printf("%s\n", banner_get());
56 |
57 | return 0;
58 | }
59 |
--------------------------------------------------------------------------------
/tests/access.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2021 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import testsuite
23 |
24 | child = testsuite.spawn(testsuite.testname)
25 |
26 | child.expect('Original banner')
27 | child.expect('Banner changed from main')
28 |
29 | child.livepatch('.libs/libaccess_livepatch1.so')
30 |
31 | child.sendline('')
32 | child.expect('String from live patch',
33 | reject=['String from main',
34 | 'Live patch data references not initialized'])
35 |
36 | child.close(force=True)
37 | exit(0)
38 |
--------------------------------------------------------------------------------
/tests/access2.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 | #include
24 | #include
25 |
26 | #include
27 |
28 | int
29 | main(void)
30 | {
31 | char buffer[128];
32 |
33 | /* Original banner. */
34 | printf("Banner addr: 0x%lX\n", (unsigned long)banner_get());
35 | printf("%s\n", banner_get());
36 |
37 | /* Use original banner setting function. */
38 | banner_set(strdup("Banner changed from main"));
39 | printf("%s\n", banner_get());
40 |
41 | /* Wait for input. */
42 | if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
43 | if (errno) {
44 | perror("access");
45 | return 1;
46 | }
47 | }
48 |
49 | /*
50 | * Use banner setting function again, which is supposed to have been
51 | * changed by the test driver. The patched function ignores the
52 | * argument, so 'String from main' should not be in the output.
53 | */
54 | banner_set("String from main");
55 | printf("%s\n", banner_get());
56 |
57 | return 0;
58 | }
59 |
--------------------------------------------------------------------------------
/tests/access2.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2021 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import testsuite
23 |
24 | child = testsuite.spawn('access')
25 |
26 | child.expect('Original banner')
27 | child.expect('Banner changed from main')
28 |
29 | child.livepatch('.libs/libaccess_livepatch2.so')
30 |
31 | child.sendline('')
32 | child.expect('String from live patch',
33 | reject=['String from main',
34 | 'Live patch data references not initialized'])
35 |
36 | child.close(force=True)
37 | exit(0)
38 |
--------------------------------------------------------------------------------
/tests/blocked.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2020-2021 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import signal
23 |
24 | import testsuite
25 |
26 | child = testsuite.spawn('blocked')
27 |
28 | # Wait for both threads to be ready (the order does not matter)
29 | child.expect('Waiting for signals.')
30 | child.expect('Waiting for signals.')
31 |
32 | # At program start, two threads are put into loops waiting for signals,
33 | # thread1 waits for SIGUSR1 and thread2 waits for SIGUSR2.
34 | child.kill(signal.SIGUSR1)
35 | child.expect('hello')
36 | child.kill(signal.SIGUSR2)
37 | child.expect('hello')
38 |
39 | # After the live patching, thread1, which is looping outside the
40 | # library, should produce a different output, whereas thread2, which
41 | # never leaves the library, should display the old behavior.
42 | child.livepatch('.libs/libblocked_livepatch1.so')
43 |
44 | child.kill(signal.SIGUSR1)
45 | child.expect('olleh', reject='hello')
46 | child.kill(signal.SIGUSR2)
47 | child.expect('hello', reject='olleh')
48 |
49 | child.close(force=True)
50 | exit(0)
51 |
--------------------------------------------------------------------------------
/tests/buildid.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | /* From libbuildid.c. */
4 | int retval(void);
5 |
6 | int
7 | main()
8 | {
9 | while (1) {
10 | int ret;
11 |
12 | printf("Waiting for input.\n");
13 | getchar();
14 |
15 | ret = retval();
16 | printf("%d\n", ret);
17 | }
18 |
19 | return 0;
20 | }
21 |
--------------------------------------------------------------------------------
/tests/buildid.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2020-2021 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | # Check the comments of `libbuildid_livepatch1.ulp` Makefile rule in
23 | # Makefile.am on this folder.
24 | #
25 | # This test should fail because of buildid mismatch.
26 |
27 | import testsuite
28 | import subprocess
29 |
30 | errorcode = 1
31 |
32 | child = testsuite.spawn('buildid')
33 | child.expect('Waiting for input.')
34 |
35 | child.sendline('')
36 | child.expect('1338');
37 |
38 | out = child.livepatch('.libs/libbuildid_livepatch1.so', capture_tool_output=True)
39 | if out.find("buildid mismatch") == -1:
40 | errorcode = 1
41 | else:
42 | errorcode = 0
43 |
44 | child.close(force=True)
45 | exit(errorcode)
46 |
--------------------------------------------------------------------------------
/tests/cancel.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2021 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import testsuite
23 |
24 | child = testsuite.spawn('cancel')
25 |
26 | child.expect('OK')
27 |
28 | child.close(force=True)
29 | exit(0)
30 |
--------------------------------------------------------------------------------
/tests/chroot.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | #include "libparameters.h"
6 |
7 | int
8 | main(void)
9 | {
10 | char buffer[128];
11 |
12 | if (chroot("/proc")) {
13 | /* Permission error, skip the test. */
14 | printf("chroot error\n");
15 | return 77;
16 | }
17 |
18 | /* Loop waiting for any input. */
19 | printf("Waiting for input.\n");
20 | while (1) {
21 | if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
22 | if (errno) {
23 | perror("chroot");
24 | return 1;
25 | }
26 | printf("Reached the end of file; quitting.\n");
27 | return 0;
28 | }
29 | int_params(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
30 | float_params(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
31 | }
32 |
33 | return 1;
34 | }
35 |
--------------------------------------------------------------------------------
/tests/chroot.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2020-2023 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import testsuite
23 | import sys
24 | import os
25 |
26 | if os.geteuid() != 0:
27 | print("Test not running as root.", file=sys.stdout)
28 | exit(77) # Skip test
29 |
30 | child = testsuite.spawn('chroot')
31 | child.expect('Waiting for input.')
32 |
33 | child.sendline('')
34 | child.expect('1-2-3-4-5-6-7-8-9-10');
35 | child.expect('1.0-2.0-3.0-4.0-5.0-6.0-7.0-8.0-9.0-10.0');
36 |
37 | child.livepatch('.libs/libparameters_livepatch1.so')
38 |
39 | child.sendline('')
40 | child.expect('10-9-8-7-6-5-4-3-2-1', reject='1-2-3-4-5-6-7-8-9-10');
41 | child.expect('10.0-9.0-8.0-7.0-6.0-5.0-4.0-3.0-2.0-1.0',
42 | reject='1.0-2.0-3.0-4.0-5.0-6.0-7.0-8.0-9.0-10.0');
43 |
44 | child.close(force=True)
45 | exit(0)
46 |
--------------------------------------------------------------------------------
/tests/comments.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #define NOINLINE __attribute__((noinline))
5 |
6 | int NOINLINE
7 | value()
8 | {
9 | /* Avoid interprocedural const-propagation on clang. */
10 | volatile int x = 0;
11 | return x;
12 | }
13 |
14 | int
15 | main()
16 | {
17 | puts("Ready.");
18 |
19 | while (value() == 0)
20 | usleep(100);
21 |
22 | puts("Livepatched");
23 |
24 | while (1)
25 | usleep(100);
26 |
27 | return 0;
28 | }
29 |
--------------------------------------------------------------------------------
/tests/comments.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2020-2022 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import testsuite
23 |
24 | error = 1
25 |
26 | child = testsuite.spawn('comments', script=False)
27 |
28 | child.expect('Ready.')
29 | child.livepatch('.libs/libcomments_livepatch1.so')
30 | child.expect('Livepatched');
31 |
32 | try:
33 | msgs = child.get_patches()
34 | if msgs.find('bsc#1200316') != -1 and msgs.find('jsc#SLE-20049') != -1 and msgs.find('CVE-2021-3449') != -1:
35 | error = 0
36 | except:
37 | print("Bug labels not found.")
38 | error = 1
39 |
40 | child.close(force=True)
41 | exit(error)
42 |
--------------------------------------------------------------------------------
/tests/constructor.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 |
24 | #include
25 |
26 | #include "constructor-template.c"
27 |
28 | int
29 | main(void)
30 | {
31 | void *data;
32 |
33 | data = malloc_wrapper(1);
34 | if (data == NULL)
35 | return 1;
36 | printf("OK\n");
37 | return 0;
38 | }
39 |
--------------------------------------------------------------------------------
/tests/constructor.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2021 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import testsuite
23 |
24 | child = testsuite.spawn('constructor')
25 |
26 | # Simply check that the test program works correctly with malloc interposition.
27 | # See constructor.c for a lengthier explanation.
28 | child.expect('OK')
29 |
30 | child.close(force=True)
31 | exit(0)
32 |
--------------------------------------------------------------------------------
/tests/contract.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 | #include
24 |
25 | #include
26 |
27 | int
28 | main(void)
29 | {
30 | char buffer[128];
31 |
32 | /* Signal readiness. */
33 | printf("Waiting for input.\n");
34 |
35 | /* Loop waiting for input and calling function(). */
36 | while (1) {
37 | if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
38 | if (errno) {
39 | perror("contract");
40 | return 1;
41 | }
42 | printf("Reached the end of file; quitting.\n");
43 | return 0;
44 | }
45 | fna();
46 | fnb();
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/tests/contract.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2021 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import testsuite
23 |
24 | child = testsuite.spawn('contract')
25 |
26 | child.expect('Waiting for input.')
27 |
28 | errors = 0
29 | child.sendline('')
30 | child.sendline('')
31 | child.expect('TYPE A data 128');
32 | child.sendline('')
33 | child.expect('TYPE B data 256.000000');
34 |
35 | # Send the test program into the library.
36 | child.sendline('')
37 |
38 | # Apply live patch while inside library
39 | child.livepatch('.libs/libcontract_livepatch1.so')
40 |
41 | # Let the process resume and check fna behavior
42 | child.sendline('')
43 | child.expect('TYPE A data 128', reject='Invalid type.')
44 |
45 | # Let the process resume and check fnb behavior
46 | child.sendline('')
47 | child.expect('TYPE B data 1024.000000', reject='Invalid type.')
48 |
49 | child.close(force=True)
50 | exit(errors)
51 |
--------------------------------------------------------------------------------
/tests/dlsym_lock.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2022 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import testsuite
23 |
24 | child = testsuite.spawn("dlsym", timeout=10)
25 |
26 | child.expect('dl lock was acquired: 1',
27 | reject=["dl lock is nonsensical:",
28 | "symbol _rtld_global not found in ld-linux-x86_64.so"])
29 |
30 | child.close(force=True)
31 | exit(0)
32 |
--------------------------------------------------------------------------------
/tests/dozens.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | static int
23 | hidden_dozen(void)
24 | {
25 | /* Clang removes the symbol completely if it sees that it can inline the
26 | function, even with -fno-inline or __attribute__((noinline)). Even with
27 | the volatile, it generates a jump to symbol rather than a function, which
28 | means this function cannot be livepatched. However, the hidden.py test
29 | only check if this symbol is present in .symtab, so this is fine. */
30 | volatile int x = 12;
31 | return x;
32 | }
33 |
34 | int
35 | dozen(void)
36 | {
37 | return hidden_dozen();
38 | }
39 |
--------------------------------------------------------------------------------
/tests/dozens.h:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | int dozen(void);
23 |
--------------------------------------------------------------------------------
/tests/endbr64.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 | #include
24 | #include
25 |
26 | #include
27 | #include
28 |
29 | int
30 | main(void)
31 | {
32 | char input[64];
33 |
34 | printf("Waiting for input.\n");
35 | while (1) {
36 | if (scanf("%s", input) == EOF) {
37 | if (errno) {
38 | perror("numserv");
39 | return 1;
40 | }
41 | printf("Reached the end of file; quitting.\n");
42 | return 0;
43 | }
44 | if (strncmp(input, "dozen", strlen("dozen")) == 0)
45 | printf("%d\n", dozen());
46 | if (strncmp(input, "hundred", strlen("hundred")) == 0)
47 | printf("%d\n", hundred());
48 | if (strncmp(input, "quit", strlen("quit")) == 0) {
49 | printf("Quitting.\n");
50 | return 0;
51 | }
52 | }
53 |
54 | return 1;
55 | }
56 |
--------------------------------------------------------------------------------
/tests/endbr64.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2020-2021 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 | #
22 | # This test asserts that libpulp is capable of patching functions which
23 | # starts with endbr64 instruction on x86_64.
24 |
25 | import testsuite
26 |
27 | child = testsuite.spawn('endbr64')
28 |
29 | child.expect('Waiting for input.')
30 |
31 | child.sendline('hundred')
32 | child.expect('100')
33 |
34 | child.livepatch('.libs/libendbr64_livepatch1.so')
35 |
36 | child.sendline('hundred')
37 | child.expect('200', reject='100')
38 |
39 | child.livepatch('.libs/libendbr64_livepatch1.so', revert=True)
40 |
41 | child.sendline('hundred')
42 | child.expect('100', reject=['200', '300', '400']);
43 |
44 | child.close(force=True)
45 | exit(0)
46 |
--------------------------------------------------------------------------------
/tests/exception_handling.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 | #include
24 |
25 | #include
26 |
27 | int
28 | main(void)
29 | {
30 | try {
31 | outer();
32 | }
33 | catch (std::runtime_error &e) {
34 | std::cout << "caught in main" << std::endl;
35 | }
36 |
37 | return 0;
38 | }
39 |
--------------------------------------------------------------------------------
/tests/exception_handling.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2021 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import testsuite
23 |
24 | child = testsuite.spawn('exception_handling')
25 |
26 | child.expect('caught in lib')
27 | child.expect('caught in main')
28 |
29 | child.close(force=True)
30 | exit(0)
31 |
--------------------------------------------------------------------------------
/tests/fuz/1:
--------------------------------------------------------------------------------
1 | ulp packer -v libdozens_livepatch1.dsc
--------------------------------------------------------------------------------
/tests/fuz/2:
--------------------------------------------------------------------------------
1 | ulp packer
--------------------------------------------------------------------------------
/tests/fuz/3:
--------------------------------------------------------------------------------
1 | ulp trigger -v -r 2 -p numserv .libs/libhundreds_livepatch1.so
--------------------------------------------------------------------------------
/tests/fuz/4:
--------------------------------------------------------------------------------
1 | ulp trigger -v -p numserv .libs/*.so
--------------------------------------------------------------------------------
/tests/fuz/5:
--------------------------------------------------------------------------------
1 | ulp post -v .libs/libdozens_livepatch1.so
--------------------------------------------------------------------------------
/tests/fuz/6:
--------------------------------------------------------------------------------
1 | ulp livepatchable .libs/libdozens_livepatch1.so
--------------------------------------------------------------------------------
/tests/fuz/7:
--------------------------------------------------------------------------------
1 | ulp patches
--------------------------------------------------------------------------------
/tests/fuz/README.md:
--------------------------------------------------------------------------------
1 | This folder contains valid inputs for ulp tools, with PWD in test dir.
2 | Those files are used by AFL, a fuzzer which mutates the arguments input
3 | to the `ulp` program.
4 |
5 | Every parameter should be separated with NUL character in order to AFL
6 | correctly detects as being different arguments for argv.
7 |
--------------------------------------------------------------------------------
/tests/glibc_private.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2020-2025 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import re
23 | import testsuite
24 | import subprocess
25 |
26 | # Make sure libpulp is built without links to GLIBC_PRIVATE symbols.
27 |
28 | command = ['readelf', '-sW', testsuite.libpulp_path]
29 | try:
30 | output = subprocess.check_output(command, timeout=10, stderr=subprocess.STDOUT)
31 | priv = re.search('GLIBC_PRIVATE', output.decode())
32 | if not priv:
33 | exit(0)
34 |
35 | except subprocess.TimeoutExpired:
36 | print('readelf timeout')
37 | exit(77)
38 |
39 | exit(1)
40 |
--------------------------------------------------------------------------------
/tests/group_disable.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2020-2023 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import re
23 | import testsuite
24 | import os
25 |
26 | env = { 'LD_PRELOAD': '../lib/.libs/libpulp.so',
27 | 'LIBPULP_DISABLE_ON_GROUPS': str(os.getgid()) }
28 |
29 | child = testsuite.spawn('numserv', env=env)
30 |
31 | child.expect('Waiting for input.')
32 |
33 | child.sendline('dozen')
34 | child.expect('12');
35 |
36 | child.sendline('hundred')
37 | child.expect('100');
38 |
39 | child.livepatch('.libs/libdozens_livepatch1.so', sanity=False)
40 |
41 | child.sendline('dozen')
42 | child.expect('12', reject='13');
43 |
44 | child.close(force=True)
45 | exit(0)
46 |
--------------------------------------------------------------------------------
/tests/hidden.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2021 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import testsuite
23 |
24 | child = testsuite.spawn('numserv')
25 |
26 | child.expect('Waiting for input.')
27 |
28 | child.sendline('dozen')
29 | child.expect('12');
30 |
31 | child.livepatch('.libs/libdozens_livepatch99.so')
32 |
33 | child.sendline('dozen')
34 | child.expect('13', reject='12');
35 |
36 | child.close(force=True)
37 | exit(0)
38 |
--------------------------------------------------------------------------------
/tests/hundreds.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | int
23 | hundred(void)
24 | {
25 | return 100;
26 | }
27 |
--------------------------------------------------------------------------------
/tests/hundreds.h:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | int hundred(void);
23 |
--------------------------------------------------------------------------------
/tests/insn_queue.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | #
3 | # This file is part of libpulp.
4 | #
5 | # libpulp is free software; you can redistribute it and/or
6 | # modify it under the terms of the GNU Lesser General Public
7 | # License as published by the Free Software Foundation; either
8 | # version 2.1 of the License, or (at your option) any later version.
9 | #
10 | # libpulp is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | # Lesser General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with libpulp. If not, see .
17 |
18 | # This test checks the integrity of the instruction queue between libpulp and
19 | # the ULP tool.
20 |
21 | import sys
22 | import testsuite
23 | import subprocess
24 |
25 | child = testsuite.spawn('insn_queue', timeout = 20)
26 | child.expect("Success")
27 | child.close(force=False)
28 |
--------------------------------------------------------------------------------
/tests/libaccess.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 |
24 | #include
25 |
26 | static char *banner = "Original banner";
27 |
28 | char *
29 | banner_get(void)
30 | {
31 | return banner;
32 | }
33 |
34 | void
35 | banner_set(char *new)
36 | {
37 | banner = new;
38 | }
39 |
--------------------------------------------------------------------------------
/tests/libaccess.h:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | char *banner_get(void);
23 | void banner_set(char *);
24 |
--------------------------------------------------------------------------------
/tests/libaccess_livepatch1.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 | #include
24 |
25 | #include
26 |
27 | static char **ulpr_banner = NULL;
28 | static char *ulpr_string = "String from live patch";
29 |
30 | void
31 | new_banner_set(__attribute__((unused)) char *new)
32 | {
33 | if (ulpr_banner == NULL)
34 | errx(EXIT_FAILURE, "Live patch data references not initialized");
35 |
36 | *ulpr_banner = ulpr_string;
37 | }
38 |
39 | /*
40 | * Touch ulpr_banner so that it does not get optimized away or placed into
41 | * read-only sections.
42 | */
43 | void
44 | banner_disturb(void)
45 | {
46 | ulpr_banner++;
47 | }
48 |
--------------------------------------------------------------------------------
/tests/libaccess_livepatch1.in:
--------------------------------------------------------------------------------
1 | __ABS_BUILDDIR__/.libs/libaccess_livepatch1.so
2 | @__ABS_BUILDDIR__/.libs/libaccess.so.0.json
3 | banner_set:new_banner_set
4 | #banner:ulpr_banner:__TARGET_OFFSET__:__PATCH_OFFSET__
5 |
--------------------------------------------------------------------------------
/tests/libaccess_livepatch2.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 | #include
24 |
25 | #include
26 |
27 | char **ulpr_banner = NULL;
28 | static char *ulpr_string = "String from live patch";
29 |
30 | void
31 | new_banner_set(__attribute__((unused)) char *new)
32 | {
33 | if (ulpr_banner == NULL)
34 | errx(EXIT_FAILURE, "Live patch data references not initialized");
35 |
36 | *ulpr_banner = ulpr_string;
37 | }
38 |
39 | /*
40 | * Touch ulpr_banner so that it does not get optimized away or placed into
41 | * read-only sections.
42 | */
43 | void
44 | banner_disturb(void)
45 | {
46 | ulpr_banner++;
47 | }
48 |
--------------------------------------------------------------------------------
/tests/libaccess_livepatch2.in:
--------------------------------------------------------------------------------
1 | __ABS_BUILDDIR__/.libs/libaccess_livepatch2.so
2 | @__ABS_BUILDDIR__/.libs/libaccess.so.0.json
3 | banner_set:new_banner_set
4 | #banner:ulpr_banner
5 |
--------------------------------------------------------------------------------
/tests/libaddress.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | void *
23 | get_return_address(void)
24 | {
25 | void *result;
26 |
27 | result = __builtin_return_address(0);
28 | result = __builtin_extract_return_addr(result);
29 |
30 | return result;
31 | }
32 |
33 | void *
34 | get_address(void)
35 | {
36 | return get_return_address();
37 | }
38 |
--------------------------------------------------------------------------------
/tests/libaddress.h:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | void *get_address(void);
23 |
--------------------------------------------------------------------------------
/tests/libaddress_livepatch1.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 |
24 | void *
25 | new_get_address(void)
26 | {
27 | return NULL;
28 | }
29 |
--------------------------------------------------------------------------------
/tests/libaddress_livepatch1.in:
--------------------------------------------------------------------------------
1 | __ABS_BUILDDIR__/.libs/libaddress_livepatch1.so
2 | @__ABS_BUILDDIR__/.libs/libaddress.so.0.json
3 | get_address:new_get_address
4 |
--------------------------------------------------------------------------------
/tests/libblocked.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 | #include
24 |
25 | void
26 | hello(void)
27 | {
28 | printf("hello\n");
29 | }
30 |
31 | /* Call hello to print on every interruption. */
32 | void
33 | hello_loop(void)
34 | {
35 | while (1) {
36 | pause();
37 | hello();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/tests/libblocked.h:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | void hello(void);
23 |
24 | void hello_loop(void);
25 |
--------------------------------------------------------------------------------
/tests/libblocked_livepatch1.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 | void
24 | olleh(void)
25 | {
26 | printf("olleh\n");
27 | }
28 |
--------------------------------------------------------------------------------
/tests/libblocked_livepatch1.in:
--------------------------------------------------------------------------------
1 | __ABS_BUILDDIR__/.libs/libblocked_livepatch1.so
2 | @__ABS_BUILDDIR__/.libs/libblocked.so.0.json
3 | hello:olleh
4 |
--------------------------------------------------------------------------------
/tests/libbuildid.c:
--------------------------------------------------------------------------------
1 | #ifndef RETVAL
2 | #define RETVAL 1337
3 | #endif
4 |
5 | int
6 | retval(void)
7 | {
8 | return RETVAL;
9 | }
10 |
--------------------------------------------------------------------------------
/tests/libbuildid_livepatch1.c:
--------------------------------------------------------------------------------
1 | int
2 | new_retval(void)
3 | {
4 | return 42;
5 | }
6 |
--------------------------------------------------------------------------------
/tests/libbuildid_livepatch1.in:
--------------------------------------------------------------------------------
1 | __ABS_BUILDDIR__/.libs/libbuildid_livepatch1.so
2 | @__ABS_BUILDDIR__/.libs/libbuildid.so.0
3 | retval:new_retval
4 |
--------------------------------------------------------------------------------
/tests/libcomments_livepatch1.c:
--------------------------------------------------------------------------------
1 | int
2 | new_value(void)
3 | {
4 | return 1;
5 | }
6 |
--------------------------------------------------------------------------------
/tests/libcomments_livepatch1.in:
--------------------------------------------------------------------------------
1 | ! This livepatch fixes bsc#1200316, jsc#SLE-20049, and CVE-2021-3449.
2 | __ABS_BUILDDIR__/.libs/libcomments_livepatch1.so
3 | @__ABS_BUILDDIR__/comments
4 | value:new_value
5 |
--------------------------------------------------------------------------------
/tests/libconstructor.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 |
24 | #include "constructor-template.c"
25 |
26 | void *
27 | malloc_wrapper(size_t size)
28 | {
29 | return malloc(size);
30 | }
31 |
--------------------------------------------------------------------------------
/tests/libconstructor.h:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | void *malloc_wrapper(size_t size);
23 |
--------------------------------------------------------------------------------
/tests/libcontract.h:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | void fna(void);
23 |
24 | void fnb(void);
25 |
--------------------------------------------------------------------------------
/tests/libcontract_livepatch1.in:
--------------------------------------------------------------------------------
1 | __ABS_BUILDDIR__/.libs/libcontract_livepatch1.so
2 | @__ABS_BUILDDIR__/.libs/libcontract.so.0.json
3 | print:new_print
4 | fna:new_fna
5 | fnb:new_fnb
6 |
--------------------------------------------------------------------------------
/tests/libdozens_bsymbolic_livepatch1.in:
--------------------------------------------------------------------------------
1 | __ABS_BUILDDIR__/.libs/libdozens_bsymbolic_livepatch1.so
2 | @__ABS_BUILDDIR__/.libs/libdozens_bsymbolic.so.0.json
3 | dozen:baker_dozen
4 |
--------------------------------------------------------------------------------
/tests/libdozens_livepatch1.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | int
23 | baker_dozen(void)
24 | {
25 | return 13;
26 | }
27 |
--------------------------------------------------------------------------------
/tests/libdozens_livepatch1.in:
--------------------------------------------------------------------------------
1 | __ABS_BUILDDIR__/.libs/libdozens_livepatch1.so
2 | @__ABS_BUILDDIR__/.libs/libdozens.so.0.json
3 | dozen:baker_dozen
4 |
--------------------------------------------------------------------------------
/tests/libdozens_livepatch99.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | int
23 | hidden_baker_dozen(void)
24 | {
25 | return 13;
26 | }
27 |
--------------------------------------------------------------------------------
/tests/libdozens_livepatch99.in:
--------------------------------------------------------------------------------
1 | __ABS_BUILDDIR__/.libs/libdozens_livepatch99.so
2 | @__ABS_BUILDDIR__/.libs/libdozens.so.0.json
3 | hidden_dozen:hidden_baker_dozen
4 |
--------------------------------------------------------------------------------
/tests/libendbr64.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | int
23 | hundred(void)
24 | {
25 | return 100;
26 | }
27 |
--------------------------------------------------------------------------------
/tests/libendbr64_livepatch1.in:
--------------------------------------------------------------------------------
1 | __ABS_BUILDDIR__/.libs/libendbr64_livepatch1.so
2 | @__ABS_BUILDDIR__/.libs/libendbr64.so.0.json
3 | hundred:two_hundreds
4 |
--------------------------------------------------------------------------------
/tests/libexception.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 | #include
24 |
25 | void
26 | inner(void)
27 | {
28 | throw std::runtime_error("");
29 | }
30 |
31 | void
32 | outer(void)
33 | {
34 | try {
35 | inner();
36 | }
37 | catch (std::runtime_error &e) {
38 | std::cout << "caught in lib" << std::endl;
39 | throw;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/tests/libexception.h:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | void inner(void);
23 | void outer(void);
24 |
--------------------------------------------------------------------------------
/tests/libhundreds_bsymbolic_livepatch1.in:
--------------------------------------------------------------------------------
1 | __ABS_BUILDDIR__/.libs/libhundreds_bsymbolic_livepatch1.so
2 | @__ABS_BUILDDIR__/.libs/libhundreds_bsymbolic.so.0
3 | hundred:two_hundreds
4 |
--------------------------------------------------------------------------------
/tests/libhundreds_livepatch1.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | int
23 | two_hundreds(void)
24 | {
25 | return 200;
26 | }
27 |
--------------------------------------------------------------------------------
/tests/libhundreds_livepatch1.in:
--------------------------------------------------------------------------------
1 | __ABS_BUILDDIR__/.libs/libhundreds_livepatch1.so
2 | @__ABS_BUILDDIR__/.libs/libhundreds.so.0.json
3 | hundred:two_hundreds
4 |
--------------------------------------------------------------------------------
/tests/libhundreds_livepatch2.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | int
23 | three_hundreds(void)
24 | {
25 | return 300;
26 | }
27 |
--------------------------------------------------------------------------------
/tests/libhundreds_livepatch2.in:
--------------------------------------------------------------------------------
1 | __ABS_BUILDDIR__/.libs/libhundreds_livepatch2.so
2 | @__ABS_BUILDDIR__/.libs/libhundreds.so.0.json
3 | hundred:three_hundreds
4 |
--------------------------------------------------------------------------------
/tests/libhundreds_livepatch3.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | int
23 | four_hundreds(void)
24 | {
25 | return 400;
26 | }
27 |
--------------------------------------------------------------------------------
/tests/libhundreds_livepatch3.in:
--------------------------------------------------------------------------------
1 | __ABS_BUILDDIR__/.libs/libhundreds_livepatch3.so
2 | @__ABS_BUILDDIR__/.libs/libhundreds.so.0.json
3 | hundred:four_hundreds
4 |
--------------------------------------------------------------------------------
/tests/libmanyprocesses_livepatch1.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 |
24 | void
25 | new_int_params(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j)
26 | {
27 | printf("%d-%d-%d-%d-%d-%d-%d-%d-%d-%d\n", j, i, h, g, f, e, d, c, b, a);
28 | }
29 |
30 | void
31 | new_float_params(float a, float b, float c, float d, float e, float f, float g,
32 | float h, float i, float j)
33 | {
34 | printf("%.1f-%.1f-%.1f-%.1f-%.1f-%.1f-%.1f-%.1f-%.1f-%.1f\n", j, i, h, g, f,
35 | e, d, c, b, a);
36 | }
37 |
--------------------------------------------------------------------------------
/tests/libmanyprocesses_livepatch1.in:
--------------------------------------------------------------------------------
1 | __ABS_BUILDDIR__/.libs/libmanyprocesses_livepatch1.so
2 | @__ABS_BUILDDIR__/.libs/libmanyprocesses.so.0
3 | int_params:new_int_params
4 | float_params:new_float_params
5 |
--------------------------------------------------------------------------------
/tests/libnotes_livepatch1.c:
--------------------------------------------------------------------------------
1 | #include "stdbool.h"
2 | bool
3 | new_repeat(void)
4 | {
5 | return false;
6 | }
7 |
--------------------------------------------------------------------------------
/tests/libnotes_livepatch1.in:
--------------------------------------------------------------------------------
1 | __ABS_BUILDDIR__/.libs/libnotes_livepatch1.so
2 | @__ABS_BUILDDIR__/notes
3 | repeat:new_repeat
4 |
--------------------------------------------------------------------------------
/tests/libpagecross.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 |
24 | void
25 | function(void)
26 | {
27 | printf("default\n");
28 | }
29 |
--------------------------------------------------------------------------------
/tests/libpagecross_livepatch1.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 |
24 | void
25 | new_function(void)
26 | {
27 | printf("patched\n");
28 | }
29 |
--------------------------------------------------------------------------------
/tests/libpagecross_livepatch1.in:
--------------------------------------------------------------------------------
1 | __ABS_BUILDDIR__/.libs/libpagecross_livepatch1.so
2 | @__ABS_BUILDDIR__/.libs/libpagecross.so.0
3 | function:new_function
4 |
--------------------------------------------------------------------------------
/tests/libpagecross_padding.S:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | /*
23 | * From the start of a page (.align ), fill the memory with
24 | * garbage up to the end of the page less 16 bytes (.fill ),
25 | * so that the prologue of the to-be-patched function (in libpage.c)
26 | * crosses a page boundary.
27 | */
28 | .set FILL_SIZE, PAGE_SIZE-16
29 | .section .text
30 | .fill FILL_SIZE, 1, 0xCC
31 |
--------------------------------------------------------------------------------
/tests/libparameters.h:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | void int_params(int a, int b, int c, int d, int e, int f, int g, int h,
23 | int i, int j);
24 |
25 | void float_params(float a, float b, float c, float d, float e, float f,
26 | float g, float h, float i, float j);
27 |
--------------------------------------------------------------------------------
/tests/libparameters_livepatch1.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 |
24 | void
25 | new_int_params(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j)
26 | {
27 | printf("%d-%d-%d-%d-%d-%d-%d-%d-%d-%d\n", j, i, h, g, f, e, d, c, b, a);
28 | }
29 |
30 | void
31 | new_float_params(float a, float b, float c, float d, float e, float f, float g,
32 | float h, float i, float j)
33 | {
34 | printf("%.1f-%.1f-%.1f-%.1f-%.1f-%.1f-%.1f-%.1f-%.1f-%.1f\n", j, i, h, g, f,
35 | e, d, c, b, a);
36 | }
37 |
--------------------------------------------------------------------------------
/tests/libparameters_livepatch1.in:
--------------------------------------------------------------------------------
1 | __ABS_BUILDDIR__/.libs/libparameters_livepatch1.so
2 | @__ABS_BUILDDIR__/.libs/libparameters.so.0
3 | int_params:new_int_params
4 | float_params:new_float_params
5 |
--------------------------------------------------------------------------------
/tests/libparameters_livepatch2.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | /* Empty file to create and empty live patch. */
23 |
--------------------------------------------------------------------------------
/tests/libparameters_livepatch2.in:
--------------------------------------------------------------------------------
1 | __ABS_BUILDDIR__/.libs/libparameters_livepatch2.so
2 | @__ABS_BUILDDIR__/.libs/libparameters.so.0
3 |
--------------------------------------------------------------------------------
/tests/libparameters_livepatch3.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 |
24 | void
25 | new_int_params(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j)
26 | {
27 | printf("%d-%d-%d-%d-%d-%d-%d-%d-%d-%d\n", j, i, h, g, f, e, d, c, b, a);
28 | }
29 |
30 | void
31 | new_float_params(float a, float b, float c, float d, float e, float f, float g,
32 | float h, float i, float j)
33 | {
34 | printf("%.1f-%.1f-%.1f-%.1f-%.1f-%.1f-%.1f-%.1f-%.1f-%.1f\n", j, i, h, g, f,
35 | e, d, c, b, a);
36 | }
37 |
--------------------------------------------------------------------------------
/tests/libparameters_livepatch3.in:
--------------------------------------------------------------------------------
1 | __ABS_BUILDDIR__/.libs/libparameters_livepatch3.so
2 | @.libs/libparameters.so.0
3 | int_params:new_int_params
4 | float_params:new_float_params
5 |
--------------------------------------------------------------------------------
/tests/libprefix.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | int
23 | hundred(void)
24 | {
25 | return 100;
26 | }
27 |
--------------------------------------------------------------------------------
/tests/libprefix_livepatch1.in:
--------------------------------------------------------------------------------
1 | __ABS_BUILDDIR__/.libs/libprefix_livepatch1.so
2 | @__ABS_BUILDDIR__/.libs/libprefix.so.0
3 | hundred:two_hundreds
4 |
--------------------------------------------------------------------------------
/tests/libprocess_access_livepatch1.in:
--------------------------------------------------------------------------------
1 | __ABS_BUILDDIR__/.libs/libprocess_access_livepatch1.so
2 | @__ABS_BUILDDIR__/process_access
3 | banner_set:new_banner_set
4 | #banner:ulpr_banner
5 |
--------------------------------------------------------------------------------
/tests/libprocess_livepatch1.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 |
24 | void
25 | new_int_params(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j)
26 | {
27 | printf("%d-%d-%d-%d-%d-%d-%d-%d-%d-%d\n", j, i, h, g, f, e, d, c, b, a);
28 | }
29 |
30 | void
31 | new_float_params(float a, float b, float c, float d, float e, float f, float g,
32 | float h, float i, float j)
33 | {
34 | printf("%.1f-%.1f-%.1f-%.1f-%.1f-%.1f-%.1f-%.1f-%.1f-%.1f\n", j, i, h, g, f,
35 | e, d, c, b, a);
36 | }
37 |
--------------------------------------------------------------------------------
/tests/libprocess_livepatch1.in:
--------------------------------------------------------------------------------
1 | __ABS_BUILDDIR__/.libs/libprocess_livepatch1.so
2 | @__ABS_BUILDDIR__/process
3 | int_params:new_int_params
4 | float_params:new_float_params
5 |
--------------------------------------------------------------------------------
/tests/libpulp_messages.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2020-2021 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import testsuite
23 |
24 | child = testsuite.spawn('parameters')
25 |
26 | child.expect('Waiting for input.')
27 |
28 | child.sendline('')
29 | child.expect('1-2-3-4-5-6-7-8-9-10');
30 | child.expect('1.0-2.0-3.0-4.0-5.0-6.0-7.0-8.0-9.0-10.0');
31 |
32 | try:
33 | msgs = child.get_libpulp_messages()
34 | if msgs.find("libpulp loaded") != -1:
35 | error = 0
36 | except:
37 | error = 1
38 |
39 | child.close(force=True)
40 | exit(error)
41 |
--------------------------------------------------------------------------------
/tests/librecursion.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 |
24 | long long int
25 | fibonacci(long long int n)
26 | {
27 | if (n < 2)
28 | return n;
29 |
30 | return fibonacci(n - 1) + fibonacci(n - 2);
31 | }
32 |
33 | long long int
34 | lucas(long long int n)
35 | {
36 | if (n == 0)
37 | return 2;
38 | if (n == 1)
39 | return 1;
40 |
41 | return lucas(n - 1) + lucas(n - 2);
42 | }
43 |
44 | long long int
45 | recursion(long long int n)
46 | {
47 | return fibonacci(n);
48 | }
49 |
--------------------------------------------------------------------------------
/tests/librecursion.h:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | long long int fibonacci(long long int n);
23 | long long int lucas(long long int n);
24 |
25 | long long int recursion(long long int n);
26 |
--------------------------------------------------------------------------------
/tests/librecursion2.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 |
24 | long long int __attribute__((noinline))
25 | func_1(long long int n)
26 | {
27 | if (n < 0)
28 | return 0;
29 |
30 | return n + func_2(n-1);
31 | }
32 |
33 | long long int __attribute__((noinline))
34 | func_2(long long int n)
35 | {
36 | if (n < 0)
37 | return 0;
38 |
39 | return 2*n + func_1(n-1);
40 | }
41 |
42 | long long int __attribute__((noinline))
43 | recursion(long long int n)
44 | {
45 | return func_1(n);
46 | }
47 |
--------------------------------------------------------------------------------
/tests/librecursion2.h:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | long long int func_1(long long int n);
23 |
24 | long long int func_2(long long int n);
25 |
26 | long long int recursion(long long int n);
27 |
--------------------------------------------------------------------------------
/tests/librecursion2_livepatch1.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 |
24 | long long int __attribute__((noinline))
25 | new_func_1(long long int n)
26 | {
27 | if (n < 0)
28 | return 0;
29 |
30 | return -n + func_2(n-1);
31 | }
32 |
33 | long long int __attribute__((noinline))
34 | new_func_2(long long int n)
35 | {
36 | if (n < 0)
37 | return 0;
38 |
39 | return -2*n + func_1(n-1);
40 | }
41 |
--------------------------------------------------------------------------------
/tests/librecursion2_livepatch1.in:
--------------------------------------------------------------------------------
1 | __ABS_BUILDDIR__/.libs/librecursion2_livepatch1.so
2 | @__ABS_BUILDDIR__/.libs/librecursion2.so.0
3 | func_1:new_func_1
4 | func_2:new_func_2
5 |
--------------------------------------------------------------------------------
/tests/librecursion_livepatch1.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | int (*lucas_ptr)(int) = (void *)0L;
23 |
24 | long long int
25 | new_recursion(long long int n)
26 | {
27 | return lucas_ptr(n);
28 | }
29 |
--------------------------------------------------------------------------------
/tests/librecursion_livepatch1.in:
--------------------------------------------------------------------------------
1 | __ABS_BUILDDIR__/.libs/librecursion_livepatch1.so
2 | @__ABS_BUILDDIR__/.libs/librecursion.so.0
3 | recursion:new_recursion
4 | #lucas:lucas_ptr
5 |
--------------------------------------------------------------------------------
/tests/libsecdis_livepatch1.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 | #include
24 |
25 | /* This function is here for messing with seccomp. Seccomp disables
26 | mmap with EXEC | WRITE attributes, so if we call it we should get
27 | a memory allocation error with ENOPERM. */
28 |
29 | __attribute__((constructor))
30 | static void initialize(void)
31 | {
32 | void *page = mmap(NULL, 128, PROT_EXEC | PROT_READ | PROT_WRITE,
33 | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
34 |
35 | /* Check if we got the page. */
36 | if (page == (void *) -1L || page == NULL) {
37 | /* We did not get the page, abort. */
38 | abort();
39 | }
40 |
41 | /* Clean memory. */
42 | munmap(page, 128);
43 | }
44 |
45 | int
46 | baker_dozen(void)
47 | {
48 | return 13;
49 | }
50 |
--------------------------------------------------------------------------------
/tests/libsecdis_livepatch1.in:
--------------------------------------------------------------------------------
1 | __ABS_BUILDDIR__/.libs/libsecdis_livepatch1.so
2 | @__ABS_BUILDDIR__/.libs/libdozens.so.0.json
3 | dozen:baker_dozen
4 |
--------------------------------------------------------------------------------
/tests/libstress.c:
--------------------------------------------------------------------------------
1 | int
2 | value(void)
3 | {
4 | return 1;
5 | }
6 |
--------------------------------------------------------------------------------
/tests/libstress_livepatch1.c:
--------------------------------------------------------------------------------
1 | int
2 | new_value(void)
3 | {
4 | return 0;
5 | }
6 |
--------------------------------------------------------------------------------
/tests/libstress_livepatch1.in:
--------------------------------------------------------------------------------
1 | __ABS_BUILDDIR__/.libs/libstress_livepatch1.so
2 | @__ABS_BUILDDIR__/.libs/libstress.so.0
3 | value:new_value
4 |
--------------------------------------------------------------------------------
/tests/libtls.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 |
24 | static __thread char *banner = "Original TLS banner";
25 |
26 | char *
27 | banner_get(void)
28 | {
29 | return banner;
30 | }
31 |
32 | char **
33 | banner_get_ref(void)
34 | {
35 | return &banner;
36 | }
37 |
38 | void
39 | banner_set(char *new)
40 | {
41 | banner = new;
42 | }
43 |
--------------------------------------------------------------------------------
/tests/libtls_livepatch1.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 | #include
24 | #include
25 |
26 | #include "../include/ulp_common.h"
27 |
28 | // ti is overriden in the livepatching process. It must not be declared static
29 | // else the compiler may remove the variable because it is unreferenced.
30 | tls_index ti = { 0 };
31 | static char *ulpr_string = "String from live patch";
32 |
33 | void *__tls_get_addr(tls_index *);
34 |
35 | #define SWAP(a,b) { typeof(a) _t = (a); (a) = (b); (b) = _t; }
36 |
37 | void
38 | new_banner_set(__attribute__((unused)) char *new)
39 | {
40 | if (ti.ti_module == 0 && ti.ti_offset == 0)
41 | errx(EXIT_FAILURE, "Live patch data references not initialized");
42 |
43 | char **ulpr_banner = __tls_get_addr(&ti);
44 | printf("module: %lx, offset: %lx\n", ti.ti_module, ti.ti_offset);
45 | printf("addr: 0x%lx\n", (unsigned long)ulpr_banner);
46 | *ulpr_banner = ulpr_string;
47 | }
48 |
--------------------------------------------------------------------------------
/tests/libtls_livepatch1.in:
--------------------------------------------------------------------------------
1 | __ABS_BUILDDIR__/.libs/libtls_livepatch1.so
2 | @__ABS_BUILDDIR__/.libs/libtls.so.0.json
3 | banner_set:new_banner_set
4 | #%banner:ti:__TARGET_OFFSET__:__PATCH_OFFSET__
5 |
--------------------------------------------------------------------------------
/tests/libvisibility.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2024 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | /* This function has hidden visibility. We should not be able to do an weak
23 | externalization here. */
24 |
25 | static char string[] = "This is a hidden string";
26 |
27 | __attribute__((visibility("hidden")))
28 | void *get_hidden_address(void)
29 | {
30 | return string;
31 | }
32 |
33 | void *get_address(void)
34 | {
35 | return get_hidden_address();
36 | }
37 |
--------------------------------------------------------------------------------
/tests/libvisibility_livepatch1.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2024 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 |
24 | static char string[128];
25 |
26 | void *get_hidden_address(void);
27 |
28 | void *get_address_lp(void)
29 | {
30 | strcpy(string, "String from lp ");
31 | strcat(string, get_hidden_address());
32 | return string;
33 | }
34 |
--------------------------------------------------------------------------------
/tests/libvisibility_livepatch1.in:
--------------------------------------------------------------------------------
1 | __ABS_BUILDDIR__/.libs/libvisibility_livepatch1.so
2 | @__ABS_BUILDDIR__/.libs/libvisibility.so.0.json
3 | get_hidden_address:get_address_lp
4 |
--------------------------------------------------------------------------------
/tests/libvisibility_livepatch2.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2024 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 |
24 | static char string[128];
25 |
26 | // Strong externalization of get_hidden_address
27 | static __attribute__((used)) void *(*klpe_get_hidden_address)(void);
28 |
29 | void *get_address_lp(void)
30 | {
31 | strcpy(string, "String from lp ");
32 | strcat(string, (*klpe_get_hidden_address)());
33 | return string;
34 | }
35 |
--------------------------------------------------------------------------------
/tests/libvisibility_livepatch2.in:
--------------------------------------------------------------------------------
1 | __ABS_BUILDDIR__/.libs/libvisibility_livepatch2.so
2 | @__ABS_BUILDDIR__/.libs/libvisibility.so.0.json
3 | get_address:get_address_lp
4 | #get_hidden_address:klpe_get_hidden_address
5 |
--------------------------------------------------------------------------------
/tests/livepatchable.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2021 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import testsuite
23 |
24 | if testsuite.is_library_livepatchable('.libs/libexception.so') == True:
25 | exit(0)
26 |
27 | exit(1)
28 |
--------------------------------------------------------------------------------
/tests/loop.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 | #include
24 | #include
25 |
26 | /* Link against a live patchable library. */
27 | #include
28 |
29 | int
30 | main(void)
31 | {
32 | printf("Child ready\n");
33 | printf("%d\n", getpid());
34 | fflush(stdout);
35 | while (1) {
36 | pause();
37 | }
38 |
39 | return 0;
40 | }
41 |
--------------------------------------------------------------------------------
/tests/manyprocesses.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 | #include
24 |
25 | void int_params(int a, int b, int c, int d, int e, int f, int g, int h,
26 | int i, int j);
27 |
28 | void float_params(float a, float b, float c, float d, float e, float f,
29 | float g, float h, float i, float j);
30 |
31 | int
32 | main(void)
33 | {
34 | char buffer[128];
35 |
36 | /* Loop waiting for any input. */
37 | printf("Waiting for input.\n");
38 | while (1) {
39 | if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
40 | if (errno) {
41 | perror("parameters");
42 | return 1;
43 | }
44 | printf("Reached the end of file; quitting.\n");
45 | return 0;
46 | }
47 | int_params(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
48 | float_params(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
49 | }
50 |
51 | return 1;
52 | }
53 |
--------------------------------------------------------------------------------
/tests/memory_protection.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2021 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import testsuite
23 |
24 | child = testsuite.spawn('memory_protection')
25 |
26 | child.expect('Waiting for input.')
27 |
28 | # Every time a newline is sent, the test program touchs code memory
29 | child.sendline('')
30 | child.expect('pristine');
31 |
32 | child.livepatch('.libs/libaddress_livepatch1.so')
33 |
34 | # Try to touch code memory after live patching
35 | child.sendline('')
36 | try:
37 | child.expect('patched', reject='pristine');
38 | except EOFError:
39 | # Diagnose the error
40 | print('Touching code after live patch failed.')
41 | if child.isalive() == False:
42 | print('The test program is dead')
43 | else:
44 | child.close(force=True)
45 | # Let the exception propagate, so that the stack trace gets printed
46 | raise
47 |
48 | child.close(force=True)
49 | exit(0)
50 |
--------------------------------------------------------------------------------
/tests/missing_function.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2021 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import subprocess
23 | import testsuite
24 |
25 | livepatch_metadata = 'libparameters_livepatch2.ulp'
26 | livepatch_container = 'libparameters_livepatch2.so'
27 |
28 | child = testsuite.spawn('parameters')
29 |
30 | child.expect('Waiting for input.')
31 |
32 | errors = 1
33 | try:
34 | child.livepatch(livepatch_metadata)
35 | except subprocess.CalledProcessError:
36 | if not child.is_so_loaded(livepatch_container):
37 | errors = 0
38 |
39 | child.close(force=True)
40 | exit(errors)
41 |
--------------------------------------------------------------------------------
/tests/nolibpulp.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2020-2021 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import os
23 | import subprocess
24 | import time
25 |
26 | import testsuite
27 | from testsuite import ulptool
28 |
29 | errorcode = 0
30 | child = testsuite.spawn('parameters', env=None)
31 |
32 | child.expect('Waiting for input.')
33 |
34 | # Check if libpulp got loaded in the process. This may be due to libpulp being
35 | # loaded as default by the system, hence there is nothing we can do other than
36 | # skip the test.
37 | if child.is_so_loaded("libpulp.so") is True:
38 | child.close(force=True)
39 | exit(77) # Skip test.
40 |
41 | child.sendline('')
42 | child.expect('1-2-3-4-5-6-7-8-9-10');
43 | child.expect('1.0-2.0-3.0-4.0-5.0-6.0-7.0-8.0-9.0-10.0');
44 |
45 | out = child.livepatch('.libs/libparameters_livepatch1.so', capture_tool_output=True)
46 | if out.find("Libpulp not found in target process") == -1:
47 | errorcode = 1
48 |
49 | child.sendline('')
50 | child.expect('1-2-3-4-5-6-7-8-9-10', reject='10-9-8-7-6-5-4-3-2-1');
51 |
52 | child.close(force=True)
53 | exit(errorcode)
54 |
--------------------------------------------------------------------------------
/tests/notes.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | __attribute__((noinline))
6 | bool
7 | repeat()
8 | {
9 | volatile bool ret = true;
10 | return ret;
11 | }
12 |
13 | int
14 | main()
15 | {
16 | puts("Ready.");
17 |
18 | while (repeat())
19 | usleep(100);
20 |
21 | puts("Livepatched");
22 | fflush(stdout);
23 |
24 | pause();
25 |
26 | return 0;
27 | }
28 |
--------------------------------------------------------------------------------
/tests/notes.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2025 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import testsuite
23 | import platform
24 |
25 | child = testsuite.spawn('notes')
26 |
27 | child.expect('Ready.')
28 | child.livepatch('.libs/libnotes_livepatch1.so')
29 | child.expect('Livepatched');
30 |
31 | child.close(force=True)
32 | exit(0)
33 |
--------------------------------------------------------------------------------
/tests/numserv.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 | #include
24 | #include
25 |
26 | #include
27 | #include
28 |
29 | int
30 | main(void)
31 | {
32 | char input[64];
33 |
34 | printf("Waiting for input.\n");
35 | while (1) {
36 | if (scanf("%s", input) == EOF) {
37 | if (errno) {
38 | perror("numserv");
39 | return 1;
40 | }
41 | printf("Reached the end of file; quitting.\n");
42 | return 0;
43 | }
44 | if (strncmp(input, "dozen", strlen("dozen")) == 0)
45 | printf("%d\n", dozen());
46 | if (strncmp(input, "hundred", strlen("hundred")) == 0)
47 | printf("%d\n", hundred());
48 | if (strncmp(input, "quit", strlen("quit")) == 0) {
49 | printf("Quitting.\n");
50 | return 0;
51 | }
52 | }
53 |
54 | return 1;
55 | }
56 |
--------------------------------------------------------------------------------
/tests/numserv.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2020-2021 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import re
23 |
24 | import testsuite
25 |
26 | # Live patch selection variable
27 | bsymbolic = re.search('_bsymbolic', testsuite.testname)
28 |
29 | child = testsuite.spawn(testsuite.testname)
30 |
31 | child.expect('Waiting for input.')
32 |
33 | child.sendline('dozen')
34 | child.expect('12');
35 |
36 | child.sendline('hundred')
37 | child.expect('100');
38 |
39 | if not bsymbolic:
40 | child.livepatch('.libs/libdozens_livepatch1.so')
41 | else:
42 | child.livepatch('.libs/libdozens_bsymbolic_livepatch1.so')
43 |
44 | child.sendline('dozen')
45 | child.expect('13', reject='12');
46 |
47 | child.sendline('hundred')
48 | child.expect('100');
49 |
50 | if not bsymbolic:
51 | child.livepatch('.libs/libhundreds_livepatch1.so')
52 | else:
53 | child.livepatch('.libs/libhundreds_bsymbolic_livepatch1.so')
54 |
55 | child.sendline('dozen')
56 | child.expect('13', reject='12');
57 |
58 | child.sendline('hundred')
59 | child.expect('200', reject='100');
60 |
61 | child.close(force=True)
62 | exit(0)
63 |
--------------------------------------------------------------------------------
/tests/pagecross.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 | #include
24 |
25 | void function(void);
26 |
27 | int
28 | main(void)
29 | {
30 | char buffer[128];
31 |
32 | /* Signal readiness. */
33 | printf("Waiting for input.\n");
34 |
35 | /* Loop waiting for input and calling function(). */
36 | while (1) {
37 | if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
38 | if (errno) {
39 | perror("pagecross");
40 | return 1;
41 | }
42 | printf("Reached the end of file; quitting.\n");
43 | return 0;
44 | }
45 | function();
46 | }
47 |
48 | return 0;
49 | }
50 |
--------------------------------------------------------------------------------
/tests/pagecross.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2020-2021 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import testsuite
23 |
24 | child = testsuite.spawn('pagecross')
25 |
26 | child.expect('Waiting for input.')
27 |
28 | child.sendline('')
29 | child.expect('default');
30 |
31 | child.livepatch('.libs/libpagecross_livepatch1.so')
32 |
33 | child.sendline('')
34 | child.expect('patched', reject='default');
35 |
36 | child.close(force=True)
37 | exit(0)
38 |
--------------------------------------------------------------------------------
/tests/parameters.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 | #include
24 |
25 | #include
26 |
27 | int
28 | main(void)
29 | {
30 | char buffer[128];
31 |
32 | /* Loop waiting for any input. */
33 | printf("Waiting for input.\n");
34 | while (1) {
35 | if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
36 | if (errno) {
37 | perror("parameters");
38 | return 1;
39 | }
40 | printf("Reached the end of file; quitting.\n");
41 | return 0;
42 | }
43 | int_params(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
44 | float_params(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
45 | }
46 |
47 | return 1;
48 | }
49 |
--------------------------------------------------------------------------------
/tests/parameters.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2020-2021 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import testsuite
23 |
24 | child = testsuite.spawn('parameters')
25 |
26 | child.expect('Waiting for input.')
27 |
28 | child.sendline('')
29 | child.expect('1-2-3-4-5-6-7-8-9-10');
30 | child.expect('1.0-2.0-3.0-4.0-5.0-6.0-7.0-8.0-9.0-10.0');
31 |
32 | child.livepatch('.libs/libparameters_livepatch1.so')
33 |
34 | child.sendline('')
35 | child.expect('10-9-8-7-6-5-4-3-2-1', reject='1-2-3-4-5-6-7-8-9-10');
36 | child.expect('10.0-9.0-8.0-7.0-6.0-5.0-4.0-3.0-2.0-1.0',
37 | reject='1.0-2.0-3.0-4.0-5.0-6.0-7.0-8.0-9.0-10.0');
38 |
39 | child.close(force=True)
40 | exit(0)
41 |
--------------------------------------------------------------------------------
/tests/patches.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2023 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | # Test `ulp patches` command.
23 |
24 | import testsuite
25 | import subprocess
26 | import sys
27 | import os
28 |
29 | # Check if the ULP tool crashes if -p is passed to unexisting process.
30 | command = [testsuite.ulptool, "patches", "-p", "99999"]
31 | try:
32 | tool = subprocess.run(command, timeout=10, stderr=subprocess.STDOUT)
33 | except:
34 | exit(1)
35 |
36 | # It should actually return an error because we explicitly trieed to retrieve
37 | # information of a non-running process.
38 | if tool.returncode == 0:
39 | exit(1)
40 |
41 | exit(0)
42 |
--------------------------------------------------------------------------------
/tests/path_disable.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2020-2023 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import re
23 |
24 | import testsuite
25 |
26 | env = { 'LD_PRELOAD': '../lib/.libs/libpulp.so',
27 | 'LIBPULP_DISABLE_ON_PATH': '*/numserv' }
28 |
29 | child = testsuite.spawn('numserv', env=env)
30 |
31 | child.expect('Waiting for input.')
32 |
33 | child.sendline('dozen')
34 | child.expect('12');
35 |
36 | child.sendline('hundred')
37 | child.expect('100');
38 |
39 | child.livepatch('.libs/libdozens_livepatch1.so', sanity=False)
40 |
41 | child.sendline('dozen')
42 | child.expect('12', reject='13');
43 |
44 | child.close(force=True)
45 | exit(0)
46 |
--------------------------------------------------------------------------------
/tests/pcqueue.c:
--------------------------------------------------------------------------------
1 | /* Include the C file so we have access to the implementation of the pcqueue
2 | without having to implement it into a library. */
3 |
4 | #include "../tools/pcqueue.c"
5 |
6 | /* How many enqueues/dequeue. */
7 | #define NUM_TEST 1000000
8 |
9 | static void *
10 | producer_thread(void *a)
11 | {
12 | long i;
13 | producer_consumer_t *pcqueue = a;
14 |
15 | for (i = 0; i < NUM_TEST; i++) {
16 | if (producer_consumer_enqueue(pcqueue, (void *)i) != 0) {
17 | abort();
18 | }
19 | }
20 |
21 | return NULL;
22 | }
23 |
24 | int
25 | main()
26 | {
27 | pthread_t thread;
28 | long i;
29 |
30 | producer_consumer_t *pcqueue = producer_consumer_new(8);
31 | if (pcqueue == NULL) {
32 | printf("Error allocating queue\n");
33 | return 1;
34 | }
35 |
36 | pthread_create(&thread, NULL, producer_thread, pcqueue);
37 |
38 | for (i = 0; i < NUM_TEST; i++) {
39 | void *elem = producer_consumer_dequeue(pcqueue);
40 | if ((long)elem != i)
41 | abort();
42 | }
43 |
44 | pthread_join(thread, NULL);
45 | producer_consumer_delete(pcqueue);
46 | printf("Pass\n");
47 | return 0;
48 | }
49 |
--------------------------------------------------------------------------------
/tests/pcqueue.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2022 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 |
23 | import testsuite
24 |
25 | test = testsuite.spawn('./pcqueue', script=False, timeout=30)
26 | test.expect('Pass')
27 | test.close(force=True)
28 |
--------------------------------------------------------------------------------
/tests/prefix.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2022 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 | #include
24 | #include
25 |
26 | #include
27 | #include
28 |
29 | int
30 | main(void)
31 | {
32 | char input[64];
33 |
34 | printf("Waiting for input.\n");
35 | while (1) {
36 | if (scanf("%s", input) == EOF) {
37 | if (errno) {
38 | perror("numserv");
39 | return 1;
40 | }
41 | printf("Reached the end of file; quitting.\n");
42 | return 0;
43 | }
44 | if (strncmp(input, "dozen", strlen("dozen")) == 0)
45 | printf("%d\n", dozen());
46 | if (strncmp(input, "hundred", strlen("hundred")) == 0)
47 | printf("%d\n", hundred());
48 | if (strncmp(input, "quit", strlen("quit")) == 0) {
49 | printf("Quitting.\n");
50 | return 0;
51 | }
52 | }
53 |
54 | return 1;
55 | }
56 |
--------------------------------------------------------------------------------
/tests/prefix.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2020-2021 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 | #
22 | # This test checks if passing the -R option to trigger with a silly
23 | # prefix causes the patching to fail on libpulp.so side. This is
24 | # useful if ulp runs in a chroot.
25 |
26 | import testsuite
27 | import re
28 |
29 | child = testsuite.spawn('prefix')
30 |
31 | child.expect('Waiting for input.')
32 |
33 | child.sendline('hundred')
34 | child.expect('100')
35 |
36 | child.livepatch('.libs/libprefix_livepatch1.so', prefix="/silly-prefix/", sanity=False)
37 |
38 | msgs = child.get_libpulp_messages()
39 | if re.search(r'Unable to load shared object /silly-prefix/.*/.libs/libprefix_livepatch1.so', msgs):
40 | error = 0
41 | else:
42 | error = 1
43 |
44 | child.close(force=True)
45 | exit(error)
46 |
--------------------------------------------------------------------------------
/tests/process.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2020-2021 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import testsuite
23 |
24 | child = testsuite.spawn('process', script=False)
25 |
26 | child.expect('Waiting for input.')
27 |
28 | child.sendline('')
29 | child.expect('1-2-3-4-5-6-7-8-9-10');
30 | child.expect('1.0-2.0-3.0-4.0-5.0-6.0-7.0-8.0-9.0-10.0');
31 |
32 | child.livepatch('.libs/libprocess_livepatch1.so')
33 |
34 | child.sendline('')
35 | child.expect('10-9-8-7-6-5-4-3-2-1', reject='1-2-3-4-5-6-7-8-9-10');
36 | child.expect('10.0-9.0-8.0-7.0-6.0-5.0-4.0-3.0-2.0-1.0',
37 | reject='1.0-2.0-3.0-4.0-5.0-6.0-7.0-8.0-9.0-10.0');
38 |
39 | child.close(force=True)
40 | exit(0)
41 |
--------------------------------------------------------------------------------
/tests/process_access.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2021 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import testsuite
23 |
24 | # Tests if private variables in a process (not in a library) can be
25 | # correctly referenced.
26 |
27 | child = testsuite.spawn('process_access', script=False)
28 |
29 | child.expect('Original banner')
30 | child.expect('Banner changed from main')
31 |
32 | child.livepatch('.libs/libprocess_access_livepatch1.so')
33 |
34 | child.sendline('')
35 | child.expect('String from live patch',
36 | reject=['String from main',
37 | 'Live patch data references not initialized'])
38 |
39 | child.close(force=True)
40 | exit(0)
41 |
--------------------------------------------------------------------------------
/tests/process_access_livepatch1.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 | #include
24 | #include
25 |
26 | char **ulpr_banner = NULL;
27 | static char *ulpr_string = "String from live patch";
28 |
29 | void
30 | new_banner_set(__attribute__((unused)) char *new)
31 | {
32 | if (ulpr_banner == NULL)
33 | errx(EXIT_FAILURE, "Live patch data references not initialized");
34 |
35 | *ulpr_banner = ulpr_string;
36 | }
37 |
38 | /*
39 | * Touch ulpr_banner so that it does not get optimized away or placed into
40 | * read-only sections.
41 | */
42 | void
43 | banner_disturb(void)
44 | {
45 | ulpr_banner++;
46 | }
47 |
--------------------------------------------------------------------------------
/tests/process_revert.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2020-2021 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import testsuite
23 |
24 | child = testsuite.spawn('process', script=False)
25 |
26 | child.expect('Waiting for input.')
27 |
28 | child.sendline('')
29 | child.expect('1-2-3-4-5-6-7-8-9-10');
30 | child.expect('1.0-2.0-3.0-4.0-5.0-6.0-7.0-8.0-9.0-10.0');
31 |
32 | child.livepatch('.libs/libprocess_livepatch1.so')
33 |
34 | child.sendline('')
35 | child.expect('10-9-8-7-6-5-4-3-2-1', reject='1-2-3-4-5-6-7-8-9-10');
36 | child.expect('10.0-9.0-8.0-7.0-6.0-5.0-4.0-3.0-2.0-1.0',
37 | reject='1.0-2.0-3.0-4.0-5.0-6.0-7.0-8.0-9.0-10.0');
38 |
39 | child.livepatch('.libs/libprocess_livepatch1.so', revert=True)
40 |
41 | child.sendline('')
42 | child.expect('1-2-3-4-5-6-7-8-9-10');
43 | child.expect('1.0-2.0-3.0-4.0-5.0-6.0-7.0-8.0-9.0-10.0');
44 |
45 | child.close(force=True)
46 | exit(0)
47 |
--------------------------------------------------------------------------------
/tests/recursion.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 | #include
24 | #include
25 |
26 | #include
27 |
28 | int
29 | main(void)
30 | {
31 | char buffer[128];
32 | int input;
33 |
34 | /* Loop waiting for a numerical input. */
35 | printf("Waiting for input.\n");
36 | while (1) {
37 | if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
38 | if (errno) {
39 | perror("recursive");
40 | return 1;
41 | }
42 | printf("Reached the end of file; quitting.\n");
43 | return 0;
44 | }
45 | input = atoi(buffer);
46 | if (input <= 0) {
47 | printf("Input must be greater than zero.\n");
48 | continue;
49 | }
50 | printf("%lld\n", recursion(input));
51 | }
52 |
53 | return 1;
54 | }
55 |
--------------------------------------------------------------------------------
/tests/recursion.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2020-2021 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import testsuite
23 |
24 | child = testsuite.spawn('recursion', timeout=60)
25 |
26 | child.expect('Waiting for input.')
27 |
28 | child.sendline('40')
29 | child.expect('102334155');
30 |
31 | child.livepatch('.libs/librecursion_livepatch1.so')
32 |
33 | child.sendline('40')
34 | child.expect('228826127', reject='102334155');
35 |
36 | child.close(force=True)
37 | exit(0)
38 |
--------------------------------------------------------------------------------
/tests/recursion2.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 | #include
24 | #include
25 |
26 | #include
27 |
28 | int
29 | main(void)
30 | {
31 | char buffer[128];
32 | int input;
33 |
34 | /* Loop waiting for a numerical input. */
35 | printf("Waiting for input.\n");
36 | while (1) {
37 | if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
38 | if (errno) {
39 | perror("recursive");
40 | return 1;
41 | }
42 | printf("Reached the end of file; quitting.\n");
43 | return 0;
44 | }
45 | input = atoi(buffer);
46 | if (input <= 0) {
47 | printf("Input must be greater than zero.\n");
48 | continue;
49 | }
50 | printf("%lld\n", recursion(input));
51 | }
52 |
53 | return 1;
54 | }
55 |
--------------------------------------------------------------------------------
/tests/recursion2.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2020-2025 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import testsuite
23 |
24 | child = testsuite.spawn('recursion2', timeout=60)
25 |
26 | child.expect('Waiting for input.')
27 |
28 | child.sendline('2')
29 | child.expect('4');
30 |
31 | child.sendline('40')
32 | child.expect('1220');
33 |
34 | child.livepatch('.libs/librecursion2_livepatch1.so')
35 |
36 | child.sendline('2')
37 | child.expect('4');
38 |
39 | child.sendline('40')
40 | child.expect('-1220', reject='1220');
41 |
42 | child.close(force=True)
43 | exit(0)
44 |
--------------------------------------------------------------------------------
/tests/redzone.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2020-2021 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import testsuite
23 |
24 | child = testsuite.spawn('redzone', timeout=50)
25 |
26 | child.expect('Waiting for input.')
27 |
28 | child.livepatch('.libs/libblocked_livepatch1.so')
29 |
30 | # Check live patch, which should not touch the redzone
31 | child.is_patch_applied('.libs/libblocked_livepatch1.so')
32 |
33 | # Read error output, if any
34 | child.readline()
35 | child.readline()
36 |
37 | ret = child.wait()
38 | if ret:
39 | exit(1)
40 | exit(0)
41 |
--------------------------------------------------------------------------------
/tests/relative_path.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2020-2021 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import testsuite
23 |
24 | child = testsuite.spawn('parameters')
25 |
26 | child.expect('Waiting for input.')
27 |
28 | child.sendline('')
29 | child.expect('1-2-3-4-5-6-7-8-9-10');
30 | child.expect('1.0-2.0-3.0-4.0-5.0-6.0-7.0-8.0-9.0-10.0');
31 |
32 | child.livepatch('.libs/libparameters_livepatch3.so')
33 |
34 | child.sendline('')
35 | child.expect('10-9-8-7-6-5-4-3-2-1', reject='1-2-3-4-5-6-7-8-9-10');
36 | child.expect('10.0-9.0-8.0-7.0-6.0-5.0-4.0-3.0-2.0-1.0',
37 | reject='1.0-2.0-3.0-4.0-5.0-6.0-7.0-8.0-9.0-10.0');
38 |
39 | child.close(force=True)
40 | exit(0)
41 |
--------------------------------------------------------------------------------
/tests/revert_all_target1.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2020-2021 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import testsuite
23 |
24 | child = testsuite.spawn('numserv')
25 |
26 | child.expect('Waiting for input.')
27 |
28 | child.sendline('hundred')
29 | child.expect('100')
30 |
31 | child.livepatch('.libs/libhundreds_livepatch1.so')
32 |
33 | child.sendline('hundred')
34 | child.expect('200', reject='100')
35 |
36 | child.livepatch('.libs/libhundreds_livepatch2.so', revert_lib="target")
37 |
38 | child.sendline('hundred')
39 | child.expect('300', reject=['100', '200'])
40 |
41 | child.livepatch('.libs/libhundreds_livepatch1.so')
42 |
43 | child.sendline('hundred')
44 | child.expect('200', reject=['100', '300'])
45 |
46 | child.close(force=True)
47 | exit(0)
48 |
--------------------------------------------------------------------------------
/tests/revert_all_target2.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2020-2021 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import testsuite
23 |
24 | child = testsuite.spawn('numserv')
25 |
26 | child.expect('Waiting for input.')
27 |
28 | child.sendline('hundred')
29 | child.expect('100')
30 |
31 | child.livepatch('.libs/libhundreds_livepatch1.so')
32 |
33 | child.sendline('hundred')
34 | child.expect('200', reject='100')
35 |
36 | child.livepatch(revert_lib="target", sanity=False)
37 |
38 | child.sendline('hundred')
39 | child.expect('200', reject='100')
40 |
41 | child.close(force=True)
42 | exit(0)
43 |
--------------------------------------------------------------------------------
/tests/revert_and_patch.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2020-2021 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import testsuite
23 |
24 | child = testsuite.spawn('numserv')
25 |
26 | child.expect('Waiting for input.')
27 |
28 | child.sendline('hundred')
29 | child.expect('100')
30 |
31 | child.livepatch('.libs/libhundreds_livepatch1.so')
32 |
33 | child.sendline('hundred')
34 | child.expect('200', reject='100')
35 |
36 | child.livepatch('.libs/libhundreds_livepatch2.so')
37 |
38 | child.sendline('hundred')
39 | child.expect('300', reject=['100', '200'])
40 |
41 | child.livepatch(revert_lib="libhundreds.so.0")
42 |
43 | child.sendline('hundred')
44 | child.expect('100', reject=['200', '300', '400']);
45 |
46 | child.livepatch('.libs/libhundreds_livepatch3.so')
47 |
48 | child.sendline('hundred')
49 | child.expect('400', reject=['100', '200', '300'])
50 |
51 | child.close(force=True)
52 | exit(0)
53 |
--------------------------------------------------------------------------------
/tests/revert_with_invalid.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2020-2021 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import testsuite
23 |
24 | child = testsuite.spawn('numserv')
25 |
26 | child.expect('Waiting for input.')
27 |
28 | child.sendline('hundred')
29 | child.expect('100')
30 |
31 | child.livepatch('.libs/libhundreds_livepatch1.so')
32 |
33 | child.sendline('hundred')
34 | child.expect('200', reject='100')
35 |
36 | # Now try to patch a wrong file but revert all patches associated with
37 | # libhundred. If there is a fail on apply and revert-all is specified,
38 | # it shoudn't revert the livepatches. That could imply in unsecure
39 | # code being run.
40 |
41 | try:
42 | child.livepatch('.libs/libnonexistent_livepatch1.so', revert_lib="libhundreds.so.0", sanity=False)
43 | except:
44 | pass
45 |
46 | child.sendline('hundred')
47 | child.expect('200', reject='100')
48 | exit(0)
49 |
--------------------------------------------------------------------------------
/tests/seccomp_disable.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2021 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import testsuite
23 | import sys
24 | import os
25 |
26 | if os.geteuid() == 0:
27 | child = testsuite.spawn('block_mprotect ./numserv')
28 | else:
29 | print("Test not running as root.", file=sys.stdout)
30 | exit(77) # Skip test
31 |
32 | child.expect('Waiting for input.')
33 |
34 | child.sendline('dozen')
35 | child.expect('12');
36 |
37 | child.sendline('hundred')
38 | child.expect('100');
39 |
40 | # Now lets try to load a livepatch that would make seccomp complain.
41 | child.livepatch('.libs/libsecdis_livepatch1.so', disable_seccomp=True)
42 |
43 | # See if the process survived.
44 | child.sendline('dozen')
45 | child.expect('13', reject='12');
46 |
47 | child.close(force=True)
48 | exit(0)
49 |
--------------------------------------------------------------------------------
/tests/stress.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | #define NUM_PROCESSES 4000
8 |
9 | int value(void);
10 |
11 | typedef enum
12 | {
13 | NONE = 0,
14 | READY,
15 | LIVEPATCHED,
16 | } state_t;
17 |
18 | int
19 | child_main(volatile state_t *state)
20 | {
21 | *state = READY;
22 |
23 | while (value()) {
24 | sleep(1);
25 | }
26 |
27 | *state = LIVEPATCHED;
28 | return 0;
29 | }
30 |
31 | int
32 | main(void)
33 | {
34 | pid_t pids[NUM_PROCESSES];
35 | volatile state_t *states;
36 | states = mmap(NULL, NUM_PROCESSES * sizeof(state_t), PROT_READ | PROT_WRITE,
37 | MAP_SHARED | MAP_ANONYMOUS, -1, 0);
38 |
39 | for (int i = 0; i < NUM_PROCESSES; i++) {
40 | states[i] = NONE;
41 | pids[i] = fork();
42 |
43 | if (pids[i] == 0) {
44 | /* Child. */
45 | return child_main(&states[i]);
46 | }
47 | }
48 |
49 | for (int i = 0; i < NUM_PROCESSES; i++) {
50 | while (states[i] != READY)
51 | usleep(1000);
52 | }
53 |
54 | puts("Processes launched");
55 |
56 | for (int i = 0; i < NUM_PROCESSES; i++) {
57 | while (states[i] != LIVEPATCHED)
58 | usleep(1000);
59 | }
60 |
61 | for (int i = 0; i < NUM_PROCESSES; i++) {
62 | int wstatus;
63 | waitpid(pids[i], &wstatus, 0);
64 |
65 | if (WIFEXITED(wstatus)) {
66 | int r = WEXITSTATUS(wstatus);
67 | if (r) {
68 | printf("Process %d returned non-zero: %d\n", pids[i], r);
69 | }
70 | }
71 | else {
72 | printf("Process %d ended without calling exit\n", pids[i]);
73 | }
74 | }
75 |
76 | munmap((void *)states, NUM_PROCESSES * sizeof(state_t));
77 | puts("Processes finished");
78 |
79 | return 0;
80 | }
81 |
--------------------------------------------------------------------------------
/tests/stress.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | #
3 | # This file is part of libpulp.
4 | #
5 | # libpulp is free software; you can redistribute it and/or
6 | # modify it under the terms of the GNU Lesser General Public
7 | # License as published by the Free Software Foundation; either
8 | # version 2.1 of the License, or (at your option) any later version.
9 | #
10 | # libpulp is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | # Lesser General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with libpulp. If not, see .
17 |
18 | # This test stress out the ulp tool when multiple processes are running.
19 |
20 | import sys
21 | import testsuite
22 | import subprocess
23 |
24 | child = testsuite.spawn('stress')
25 | child.expect("Processes launched")
26 |
27 | testsuite.childless_livepatch(wildcard='.libs/libstress_livepatch1.so', verbose=False, timeout=120)
28 |
29 | child.expect("Processes finished", reject=['returned non-zero'])
30 | child.close(force=True)
31 |
--------------------------------------------------------------------------------
/tests/syscall_restart.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2020-2021 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import testsuite
23 |
24 | child = testsuite.spawn('syscall_restart')
25 |
26 | child.expect('Waiting for input.')
27 |
28 | # After printing the greeting message, the target process makes a call
29 | # to fgets, which calls the read syscall. Applying a live patch will
30 | # interrupt the syscall.
31 | child.livepatch('.libs/libparameters_livepatch1.so')
32 |
33 | # Send a newline, which should be received by the read syscall if it has
34 | # been successfully restarted by libpulp. If the syscall has not been
35 | # restarted, the child program will exit without printing anything.
36 | child.sendline('')
37 | child.expect('8-7-6-5-4-3-2-1');
38 | child.expect('10.0-9.0-8.0-7.0-6.0-5.0-4.0-3.0-2.0-1.0');
39 |
40 | child.close(force=True)
41 | exit(0)
42 |
--------------------------------------------------------------------------------
/tests/tempfiles.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2022 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import testsuite
23 | import os
24 |
25 | # This test checks if ulp tool left temporary files behind.
26 | errno = 0
27 | tmp_list = os.listdir("/tmp/")
28 |
29 | for fname in tmp_list:
30 | if fname.startswith("ulp-") == True:
31 | # Flag error and remove any temp file we are left, so it does not
32 | # contaminate next test run.
33 | errno = 1
34 | os.remove("/tmp/" + fname)
35 |
36 | exit(errno)
37 |
--------------------------------------------------------------------------------
/tests/terminal.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 |
28 | int
29 | main(int argc, char **argv, char **envp)
30 | {
31 | int pid;
32 | int status;
33 |
34 | if (argc < 2) {
35 | printf("Usage: %s .\n", argv[0]);
36 | return 1;
37 | }
38 |
39 | /* Signal readiness. */
40 | printf("Parent ready\n");
41 | fflush(stdout);
42 |
43 | /* Mimic a terminal by forking a new process and waiting for it. */
44 | if ((pid = fork())) {
45 | if (waitpid(pid, &status, WUNTRACED | WCONTINUED) == -1)
46 | perror("terminal");
47 | if (WIFSTOPPED(status))
48 | printf("Child stopped with %d.\n", WSTOPSIG(status));
49 | if (WIFCONTINUED(status))
50 | printf("Child continued.\n");
51 | return 7;
52 | }
53 | else
54 | execve(argv[1], argv, envp);
55 |
56 | return 0;
57 | }
58 |
--------------------------------------------------------------------------------
/tests/textrel.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2020-2025 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import re
23 | import testsuite
24 | import subprocess
25 |
26 | # Make sure libpulp is built without TEXTREL.
27 |
28 | command = ['readelf', '-d', testsuite.libpulp_path]
29 | try:
30 | output = subprocess.check_output(command, timeout=10, stderr=subprocess.STDOUT)
31 | textrel = re.search('TEXTREL', output.decode())
32 | if not textrel:
33 | exit(0)
34 |
35 | except subprocess.TimeoutExpired:
36 | print('readelf timeout')
37 | exit(77)
38 |
39 | exit(1)
40 |
--------------------------------------------------------------------------------
/tests/tls.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2021 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import testsuite
23 |
24 | child = testsuite.spawn(testsuite.testname)
25 |
26 | child.expect('Original TLS banner')
27 | child.expect('Banner changed from thread_func: 0')
28 | child.expect('Banner changed from thread_func: 1')
29 |
30 | child.livepatch('.libs/libtls_livepatch1.so')
31 |
32 | child.sendline('')
33 | child.expect('String from live patch',
34 | reject=['String from thread_func: 0',
35 | 'String from thread_func: 1',
36 | 'Live patch data references not initialized'])
37 |
38 | child.close(force=True)
39 | exit(0)
40 |
--------------------------------------------------------------------------------
/tests/visibility.c:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2024 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 | #include
24 |
25 | void *get_address(void);
26 |
27 | int main(void)
28 | {
29 | while (1) {
30 | puts("Press ENTER to continue");
31 | getchar();
32 | const char *string = get_address();
33 | puts(string);
34 | }
35 |
36 | return 0;
37 | }
38 |
--------------------------------------------------------------------------------
/tests/visibility.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # libpulp - User-space Livepatching Library
4 | #
5 | # Copyright (C) 2020-2024 SUSE Software Solutions GmbH
6 | #
7 | # This file is part of libpulp.
8 | #
9 | # libpulp is free software; you can redistribute it and/or
10 | # modify it under the terms of the GNU Lesser General Public
11 | # License as published by the Free Software Foundation; either
12 | # version 2.1 of the License, or (at your option) any later version.
13 | #
14 | # libpulp is distributed in the hope that it will be useful,
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | # Lesser General Public License for more details.
18 | #
19 | # You should have received a copy of the GNU General Public License
20 | # along with libpulp. If not, see .
21 |
22 | import testsuite
23 |
24 | child = testsuite.spawn('visibility', script=False)
25 |
26 | child.expect('Press ENTER to continue')
27 | child.sendline('')
28 | child.expect('This is a hidden string')
29 | child.expect('Press ENTER to continue')
30 | out = child.livepatch('.libs/libvisibility_livepatch1.so',
31 | sanity=False, capture_tool_output=True)
32 |
33 | child.sendline('')
34 | child.expect('This is a hidden string')
35 |
36 | # Check if we can't apply the above patch.
37 | if out.find('Failure in dlopen') < 0:
38 | child.close(force=True)
39 | exit(1)
40 |
41 | # Now try to apply the patch with strong externalization
42 | child.expect('Press ENTER to continue')
43 | child.livepatch('.libs/libvisibility_livepatch2.so')
44 |
45 | child.sendline('')
46 | child.expect('String from lp This is a hidden string')
47 |
48 | child.close(force=True)
49 | exit(0)
50 |
--------------------------------------------------------------------------------
/tools/check.h:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #ifndef CHECK_H
23 | #define CHECK_H
24 |
25 | struct arguments;
26 |
27 | int run_check(struct arguments *);
28 |
29 | #endif
30 |
--------------------------------------------------------------------------------
/tools/dump.h:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2017-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #ifndef DUMP_H
23 | #define DUMP_H
24 |
25 | struct arguments;
26 |
27 | int run_dump(struct arguments *);
28 |
29 | #endif /* DUMP_H */
30 |
--------------------------------------------------------------------------------
/tools/elf-extra.h:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2019-2022 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #include
23 | #include
24 | #include
25 |
26 | /* Extra ELF functions. */
27 |
28 | Elf_Scn *get_elfscn_by_name(Elf *elf, const char *name);
29 |
30 | Elf_Scn *get_elf_section(Elf *, ElfW(Word) sht_type);
31 |
32 | Elf *load_elf(const char *path, int *fd);
33 |
34 | void unload_elf(Elf **, int *fd);
35 |
36 | int embed_patch_metadata_into_elf(Elf *elfinput, const char *elf_path,
37 | const char *metadata,
38 | const char *section_name);
39 |
--------------------------------------------------------------------------------
/tools/insn_queue_tools.h:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2023 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #ifndef INSNQ_TOOL_H
23 | #define INSNQ_TOOL_H
24 |
25 | struct ulp_process;
26 |
27 | #include "insn_queue.h"
28 | #include
29 |
30 | int insnq_get_version(struct ulp_process *process);
31 |
32 | bool insnq_check_compatibility(struct ulp_process *process);
33 |
34 | int insnq_interpret_from_process(struct ulp_process *);
35 |
36 | #endif
37 |
--------------------------------------------------------------------------------
/tools/livepatchable.h:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2017-2022 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #ifndef LIVEPATCHABLE_H
23 | #define LIVEPATCHABLE_H
24 |
25 | struct arguments;
26 |
27 | int run_livepatchable(struct arguments *);
28 |
29 | #endif /* LIVEPATCHABLE.H */
30 |
--------------------------------------------------------------------------------
/tools/md4.h:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #define MD4_LENGTH 16
23 | uint8_t *MD4(char *input, uint64_t length);
24 |
--------------------------------------------------------------------------------
/tools/messages.h:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2017-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #ifndef MESSAGES_H
23 | #define MESSAGES_H
24 |
25 | struct arguments;
26 |
27 | int run_messages(struct arguments *);
28 |
29 | #endif /* MESSAGES.H */
30 |
--------------------------------------------------------------------------------
/tools/pcqueue.h:
--------------------------------------------------------------------------------
1 | #ifndef PCQUEUE_H
2 | #define PCQUEUE_H
3 |
4 | #include
5 | #include
6 |
7 | /* Uncoment this if the producer_consumer queue should support multiple
8 | producers and consumers. */
9 | /* #define MORE_THAN_ONE_ONE */
10 |
11 | /** A producer-consumer queue. This structure creates a channel in which
12 | two threads can communicate, one by enqueuing elements and another by
13 | dequeuing elements. */
14 | struct producer_consumer
15 | {
16 | /** Maximum number of elements in this queue. */
17 | int n;
18 |
19 | /** Position of the last inserted element.*/
20 | int head;
21 |
22 | /** Position of the oldest element in the queue. */
23 | int tail;
24 |
25 | /** Semaphore that will block any attempt of dequeuing an element if the
26 | queue is empty. */
27 | sem_t empty;
28 |
29 | /** Semaphore that will block any attempt of enqueuing an element if the
30 | queue is full. */
31 | sem_t full;
32 | #ifdef MORE_THAN_ONE_ONE
33 | /** Lock for head & tail. This is unnecessary if there is only one producer
34 | and one consumer. If you wish to support many producers and many
35 | consumers, define MORE_THAN_ONE_ONE. */
36 | pthread_mutex_t lock;
37 | #endif
38 |
39 | /** The queue buffer. The 0 array element denotes where it starts, but it is
40 | allocated in `producer_consumer_new`. */
41 | void *elem[0];
42 | };
43 |
44 | /** Typedef for a shorthand of struct producer_consumer. */
45 | typedef struct producer_consumer producer_consumer_t;
46 |
47 | producer_consumer_t *producer_consumer_new(int n);
48 |
49 | int producer_consumer_delete(producer_consumer_t *queue);
50 |
51 | int producer_consumer_enqueue(producer_consumer_t *queue, void *elem);
52 |
53 | void *producer_consumer_dequeue(producer_consumer_t *queue);
54 |
55 | #endif // PCQUEUE_H
56 |
--------------------------------------------------------------------------------
/tools/post.h:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #ifndef POST_H
23 | #define POST_H
24 |
25 | struct arguments;
26 | struct Elf_Scn;
27 | struct Elf;
28 |
29 | struct Elf_Scn *find_section_by_name(struct Elf *, const char *name);
30 |
31 | int run_post(struct arguments *);
32 |
33 | #endif /* POST_H */
34 |
--------------------------------------------------------------------------------
/tools/set_patchable.h:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2020-2023 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #ifndef SET_PATCHABLE_H
23 | #define SET_PATCHABLE_H
24 |
25 | struct arguments;
26 |
27 | int run_set_patchable(struct arguments *);
28 |
29 | #endif
30 |
--------------------------------------------------------------------------------
/tools/trigger.h:
--------------------------------------------------------------------------------
1 | /*
2 | * libpulp - User-space Livepatching Library
3 | *
4 | * Copyright (C) 2017-2021 SUSE Software Solutions GmbH
5 | *
6 | * This file is part of libpulp.
7 | *
8 | * libpulp is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * libpulp is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with libpulp. If not, see .
20 | */
21 |
22 | #ifndef TRIGGER_H
23 | #define TRIGGER_H
24 |
25 | struct arguments;
26 |
27 | int run_trigger(struct arguments *);
28 |
29 | #endif /* TRIGGER_H */
30 |
--------------------------------------------------------------------------------