AArch64 support: add aarch64 support for libcareplus
Add related code which make libcareplus can run basic demo on aarch64. Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
This commit is contained in:
parent
9389c4afb2
commit
2b0fff2855
1149
0001-Split-kpatch_storage.c-from-kpatch_user.c.patch
Normal file
1149
0001-Split-kpatch_storage.c-from-kpatch_user.c.patch
Normal file
File diff suppressed because it is too large
Load Diff
1633
0002-Split-kpatch_patch.c-from-kpatch_user.c.patch
Normal file
1633
0002-Split-kpatch_patch.c-from-kpatch_user.c.patch
Normal file
File diff suppressed because it is too large
Load Diff
152
0003-cmd_patch-pass-arguments-directly.patch
Normal file
152
0003-cmd_patch-pass-arguments-directly.patch
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
From 98833d06737a9a1128f548d15344b1cbaeed049f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Pavel Boldin <pboldin@cloudlinux.com>
|
||||||
|
Date: Wed, 24 Jan 2018 13:14:10 +0200
|
||||||
|
Subject: [PATCH 03/89] cmd_patch: pass arguments directly
|
||||||
|
|
||||||
|
Signed-off-by: Pavel Boldin <pboldin@cloudlinux.com>
|
||||||
|
---
|
||||||
|
src/kpatch_user.c | 84 ++++++++++++++++-------------------------------
|
||||||
|
1 file changed, 29 insertions(+), 55 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/kpatch_user.c b/src/kpatch_user.c
|
||||||
|
index 9ab77b9..d257b67 100644
|
||||||
|
--- a/src/kpatch_user.c
|
||||||
|
+++ b/src/kpatch_user.c
|
||||||
|
@@ -63,19 +63,36 @@ static int usage_patch(const char *err)
|
||||||
|
{
|
||||||
|
if (err)
|
||||||
|
fprintf(stderr, "err: %s\n", err);
|
||||||
|
- fprintf(stderr, "usage: libcare-ctl patch [options] <-p PID> <-r fd> <patch>\n");
|
||||||
|
+ fprintf(stderr, "usage: libcare-ctl patch [options] <-p PID> <patch>\n");
|
||||||
|
fprintf(stderr, "\nOptions:\n");
|
||||||
|
fprintf(stderr, " -h - this message\n");
|
||||||
|
- fprintf(stderr, " -s - process was just executed\n");
|
||||||
|
fprintf(stderr, " -p <PID> - target process\n");
|
||||||
|
- fprintf(stderr, " -r fd - fd used with LD_PRELOAD=execve.so.\n");
|
||||||
|
return err ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
-int cmd_patch_user(int argc, char *argv[])
|
||||||
|
+static int
|
||||||
|
+patch_user(const char *storage_path, int pid,
|
||||||
|
+ int is_just_started, int send_fd)
|
||||||
|
{
|
||||||
|
+ int ret;
|
||||||
|
kpatch_storage_t storage;
|
||||||
|
- int opt, pid = -1, is_pid_set = 0, ret, start = 0, send_fd = -1;
|
||||||
|
+
|
||||||
|
+ ret = storage_init(&storage, storage_path);
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ ret = processes_patch(&storage, pid, is_just_started, send_fd);
|
||||||
|
+
|
||||||
|
+ storage_free(&storage);
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+int cmd_patch_user(int argc, char *argv[])
|
||||||
|
+{
|
||||||
|
+ int opt, pid = -1, is_pid_set = 0, ret;
|
||||||
|
+ const char *storage_path;
|
||||||
|
|
||||||
|
if (argc < 4)
|
||||||
|
return usage_patch(NULL);
|
||||||
|
@@ -89,12 +106,6 @@ int cmd_patch_user(int argc, char *argv[])
|
||||||
|
pid = atoi(optarg);
|
||||||
|
is_pid_set = 1;
|
||||||
|
break;
|
||||||
|
- case 'r':
|
||||||
|
- send_fd = atoi(optarg);
|
||||||
|
- break;
|
||||||
|
- case 's':
|
||||||
|
- start = 1;
|
||||||
|
- break;
|
||||||
|
default:
|
||||||
|
return usage_patch("unknown option");
|
||||||
|
}
|
||||||
|
@@ -109,14 +120,9 @@ int cmd_patch_user(int argc, char *argv[])
|
||||||
|
if (!kpatch_check_system())
|
||||||
|
goto out_err;
|
||||||
|
|
||||||
|
- ret = storage_init(&storage, argv[argc - 1]);
|
||||||
|
- if (ret < 0)
|
||||||
|
- goto out_err;
|
||||||
|
-
|
||||||
|
-
|
||||||
|
- ret = processes_patch(&storage, pid, start, send_fd);
|
||||||
|
-
|
||||||
|
- storage_free(&storage);
|
||||||
|
+ storage_path = argv[argc - 1];
|
||||||
|
+ ret = patch_user(storage_path, pid,
|
||||||
|
+ /* is_just_started */ 0, /* send_fd */ -1);
|
||||||
|
|
||||||
|
out_err:
|
||||||
|
return ret;
|
||||||
|
@@ -474,24 +480,6 @@ static int
|
||||||
|
cmd_execve_startup(int fd, int argc, char *argv[], int is_just_started)
|
||||||
|
{
|
||||||
|
int rv, pid;
|
||||||
|
- char pid_str[64], send_fd_str[64];
|
||||||
|
- char *patch_pid_argv_execve[] = {
|
||||||
|
- "patch",
|
||||||
|
- "-s",
|
||||||
|
- "-p",
|
||||||
|
- pid_str,
|
||||||
|
- "-r",
|
||||||
|
- send_fd_str,
|
||||||
|
- storage_dir
|
||||||
|
- };
|
||||||
|
- char *patch_pid_argv_startup[] = {
|
||||||
|
- "patch",
|
||||||
|
- "-p",
|
||||||
|
- pid_str,
|
||||||
|
- "-r",
|
||||||
|
- send_fd_str,
|
||||||
|
- storage_dir
|
||||||
|
- };
|
||||||
|
|
||||||
|
rv = sscanf(argv[1], "%d", &pid);
|
||||||
|
if (rv != 1) {
|
||||||
|
@@ -499,16 +487,8 @@ cmd_execve_startup(int fd, int argc, char *argv[], int is_just_started)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
- sprintf(pid_str, "%d", pid);
|
||||||
|
- sprintf(send_fd_str, "%d", fd);
|
||||||
|
-
|
||||||
|
optind = 1;
|
||||||
|
- if (is_just_started)
|
||||||
|
- rv = cmd_patch_user(ARRAY_SIZE(patch_pid_argv_execve),
|
||||||
|
- patch_pid_argv_execve);
|
||||||
|
- else
|
||||||
|
- rv = cmd_patch_user(ARRAY_SIZE(patch_pid_argv_startup),
|
||||||
|
- patch_pid_argv_startup);
|
||||||
|
+ rv = patch_user(storage_dir, pid, is_just_started, fd);
|
||||||
|
|
||||||
|
if (rv < 0)
|
||||||
|
kperr("can't patch pid %d\n", pid);
|
||||||
|
@@ -578,15 +558,9 @@ cmd_storage(int argc, char *argv[])
|
||||||
|
static int
|
||||||
|
cmd_update(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
- char *patch_all[] = {
|
||||||
|
- "patch",
|
||||||
|
- "-p",
|
||||||
|
- "all",
|
||||||
|
- storage_dir
|
||||||
|
- };
|
||||||
|
-
|
||||||
|
- optind = 1;
|
||||||
|
- return cmd_patch_user(ARRAY_SIZE(patch_all), patch_all);
|
||||||
|
+ return patch_user(storage_dir, /* pid */ -1,
|
||||||
|
+ /* is_just_started */ 0,
|
||||||
|
+ /* send_fd */ -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
71
0004-travis-use-VM-for-now.patch
Normal file
71
0004-travis-use-VM-for-now.patch
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
From f4b6b37575e514f3e54f08166dc14e35815a8ebb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Pavel Boldin <pboldin@cloudlinux.com>
|
||||||
|
Date: Tue, 30 Jan 2018 08:15:11 +0200
|
||||||
|
Subject: [PATCH 04/89] travis: use VM for now
|
||||||
|
|
||||||
|
Attaching even to a children process is broken in travis's Docker.
|
||||||
|
Use VM until https://github.com/travis-ci/travis-ci/issues/9033
|
||||||
|
is fixed.
|
||||||
|
|
||||||
|
Signed-off-by: Pavel Boldin <pboldin@cloudlinux.com>
|
||||||
|
---
|
||||||
|
.travis.yml | 2 +-
|
||||||
|
Makefile | 2 +-
|
||||||
|
tests/run_tests.sh | 18 +++++++++++++++++-
|
||||||
|
3 files changed, 19 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/.travis.yml b/.travis.yml
|
||||||
|
index 4bb2614..f3ccb4e 100644
|
||||||
|
--- a/.travis.yml
|
||||||
|
+++ b/.travis.yml
|
||||||
|
@@ -3,7 +3,7 @@ script: make tests
|
||||||
|
language: c
|
||||||
|
|
||||||
|
dist: trusty
|
||||||
|
-sudo: false
|
||||||
|
+sudo: required
|
||||||
|
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
diff --git a/Makefile b/Makefile
|
||||||
|
index 2da227f..c5a2837 100644
|
||||||
|
--- a/Makefile
|
||||||
|
+++ b/Makefile
|
||||||
|
@@ -1,4 +1,4 @@
|
||||||
|
-
|
||||||
|
+#dummy
|
||||||
|
|
||||||
|
all: src
|
||||||
|
|
||||||
|
diff --git a/tests/run_tests.sh b/tests/run_tests.sh
|
||||||
|
index fcfcd56..fbfb273 100755
|
||||||
|
--- a/tests/run_tests.sh
|
||||||
|
+++ b/tests/run_tests.sh
|
||||||
|
@@ -3,7 +3,23 @@
|
||||||
|
set -e
|
||||||
|
|
||||||
|
wait_file() {
|
||||||
|
- while ! test -s $1; do sleep ${2-1}; done
|
||||||
|
+ local file="$1"
|
||||||
|
+ local pause="${2-1}"
|
||||||
|
+ local i=0
|
||||||
|
+ local timeout=60
|
||||||
|
+
|
||||||
|
+ while test $i -lt $timeout; do
|
||||||
|
+ if test -s $file; then
|
||||||
|
+ break
|
||||||
|
+ fi
|
||||||
|
+ sleep $pause
|
||||||
|
+ i=$((i + 1))
|
||||||
|
+ done
|
||||||
|
+
|
||||||
|
+ if test $i -eq $timeout; then
|
||||||
|
+ return 1
|
||||||
|
+ fi
|
||||||
|
+
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
39
0005-scripts-pkgbuild-add-prepare_env-hook.patch
Normal file
39
0005-scripts-pkgbuild-add-prepare_env-hook.patch
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
From 8e1d1d24e39464e88e92695ea5951639e789f72d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Pavel Boldin <pboldin@cloudlinux.com>
|
||||||
|
Date: Sat, 28 Oct 2017 03:47:48 +0300
|
||||||
|
Subject: [PATCH 05/89] scripts/pkgbuild: add prepare_env hook
|
||||||
|
|
||||||
|
Change-Id: Iabb96a1b9f9cd8d1415029380f825da29156a840
|
||||||
|
Signed-off-by: Pavel Boldin <pboldin@cloudlinux.com>
|
||||||
|
---
|
||||||
|
scripts/pkgbuild | 7 +++++++
|
||||||
|
1 file changed, 7 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/scripts/pkgbuild b/scripts/pkgbuild
|
||||||
|
index ea1f411..3697594 100755
|
||||||
|
--- a/scripts/pkgbuild
|
||||||
|
+++ b/scripts/pkgbuild
|
||||||
|
@@ -73,6 +73,11 @@ clean_dirs() {
|
||||||
|
rm -rf $KP_PROJECT_BUILD_ROOT /root/root.original /root/root.patched
|
||||||
|
}
|
||||||
|
|
||||||
|
+kp_prepare_env_hook() {
|
||||||
|
+ # use this to add repos
|
||||||
|
+ :
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
kp_pack_prebuilt() {
|
||||||
|
echo " packing prebuilt $KP_PROJECT into $KP_PROJECT_PREBUILT"
|
||||||
|
pushd $KP_PROJECT_BUILD_ROOT
|
||||||
|
@@ -386,6 +391,8 @@ main() {
|
||||||
|
|
||||||
|
overwrite_utils
|
||||||
|
|
||||||
|
+ kp_prepare_env_hook
|
||||||
|
+
|
||||||
|
if [ "$ACTION" == "prebuild" ]; then
|
||||||
|
kp_prepare_source
|
||||||
|
kp_prebuild_hook
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
42
0006-pkgbuild-fix-for-non-root-rpmbuild-built-root.patch
Normal file
42
0006-pkgbuild-fix-for-non-root-rpmbuild-built-root.patch
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
From 859be3502b57c87f3241c11d36059313cbdde46a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Pavel Boldin <pboldin@cloudlinux.com>
|
||||||
|
Date: Tue, 31 Oct 2017 04:04:58 +0100
|
||||||
|
Subject: [PATCH 06/89] pkgbuild: fix for non-/root/rpmbuild built root
|
||||||
|
|
||||||
|
---
|
||||||
|
scripts/pkgbuild | 5 ++++-
|
||||||
|
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/scripts/pkgbuild b/scripts/pkgbuild
|
||||||
|
index 3697594..e2ac7c7 100755
|
||||||
|
--- a/scripts/pkgbuild
|
||||||
|
+++ b/scripts/pkgbuild
|
||||||
|
@@ -120,7 +120,8 @@ kp_prepare_source_rpm() {
|
||||||
|
|
||||||
|
sed -i 's/.rpm$//g' $KP_PROJECT_BUILD_ROOT/dependencies.txt
|
||||||
|
|
||||||
|
- rpm -ivh /kcdata/$KP_PROJECT_SOURCE
|
||||||
|
+ rpm -ivh /kcdata/$KP_PROJECT_SOURCE \
|
||||||
|
+ --define "_topdir $KP_PROJECT_BUILD_ROOT"
|
||||||
|
}
|
||||||
|
|
||||||
|
kp_prepare_source_deb() {
|
||||||
|
@@ -152,6 +153,7 @@ kp_prebuild_rpm() {
|
||||||
|
eval rpmbuild --nocheck --noclean \
|
||||||
|
-bc \
|
||||||
|
$KP_RPMBUILD_FLAGS \
|
||||||
|
+ '--define "_topdir $KP_PROJECT_BUILD_ROOT"' \
|
||||||
|
$KP_PROJECT_BUILD_ROOT/SPECS/$KP_PROJECT_SPEC 2>&1 | \
|
||||||
|
tee $KP_PROJECT_BUILD_ROOT/prebuild.log
|
||||||
|
}
|
||||||
|
@@ -237,6 +239,7 @@ kp_build_rpm() {
|
||||||
|
--short-circuit \
|
||||||
|
-bc \
|
||||||
|
$KP_RPMBUILD_FLAGS \
|
||||||
|
+ '--define "_topdir $KP_PROJECT_BUILD_ROOT"' \
|
||||||
|
$KP_PROJECT_BUILD_ROOT/SPECS/$KP_PROJECT_SPEC
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
1327
0007-Toil-package-builder.patch
Normal file
1327
0007-Toil-package-builder.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,30 @@
|
|||||||
|
From 066da27aaf6b153c215bee353e7190fe226f5b3b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Pavel Boldin <pboldin@cloudlinux.com>
|
||||||
|
Date: Thu, 14 Dec 2017 18:02:15 +0200
|
||||||
|
Subject: [PATCH 08/89] pkgbuild: use yumdownloader if source url is missing
|
||||||
|
|
||||||
|
Signed-off-by: Pavel Boldin <pboldin@cloudlinux.com>
|
||||||
|
---
|
||||||
|
scripts/pkgbuild | 6 +++++-
|
||||||
|
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/scripts/pkgbuild b/scripts/pkgbuild
|
||||||
|
index 8803db3..97c78a9 100755
|
||||||
|
--- a/scripts/pkgbuild
|
||||||
|
+++ b/scripts/pkgbuild
|
||||||
|
@@ -105,7 +105,11 @@ kp_prepare_source_raw() {
|
||||||
|
|
||||||
|
kp_download_source_rpm() {
|
||||||
|
mkdir -p /kcdata
|
||||||
|
- curl $KP_PROJECT_SOURCE_URL -o /kcdata/$KP_PROJECT_SOURCE
|
||||||
|
+ if test -n "$KP_PROJECT_SOURCE_URL"; then
|
||||||
|
+ curl $KP_PROJECT_SOURCE_URL -o /kcdata/$KP_PROJECT_SOURCE
|
||||||
|
+ else
|
||||||
|
+ yumdownloader --source --destdir /kcdata ${KP_PROJECT_SOURCE%.src.rpm}
|
||||||
|
+ fi
|
||||||
|
}
|
||||||
|
|
||||||
|
kp_prepare_source_rpm() {
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
52
0009-execve-abort-on-failure.patch
Normal file
52
0009-execve-abort-on-failure.patch
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
From 2343fef023a8cd64473161fa82a0d81cb5007cf9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Pavel Boldin <pboldin@cloudlinux.com>
|
||||||
|
Date: Tue, 30 Jan 2018 00:04:54 +0200
|
||||||
|
Subject: [PATCH 09/89] execve: abort() on failure
|
||||||
|
|
||||||
|
Signed-off-by: Pavel Boldin <pboldin@cloudlinux.com>
|
||||||
|
---
|
||||||
|
tests/execve/execve.c | 7 ++++---
|
||||||
|
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/tests/execve/execve.c b/tests/execve/execve.c
|
||||||
|
index b3df0e4..eb3e9d3 100644
|
||||||
|
--- a/tests/execve/execve.c
|
||||||
|
+++ b/tests/execve/execve.c
|
||||||
|
@@ -81,7 +81,7 @@ notify_listener(void)
|
||||||
|
sock = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
|
||||||
|
if (sock == -1) {
|
||||||
|
dprintf("socket() error: %s(%d)\n", strerror(errno), errno);
|
||||||
|
- return;
|
||||||
|
+ abort();
|
||||||
|
}
|
||||||
|
dprintf("socket()\n");
|
||||||
|
|
||||||
|
@@ -96,7 +96,7 @@ notify_listener(void)
|
||||||
|
if (rv == -1) {
|
||||||
|
fprintf(stderr, "libcare-execve: connect() error: %s(%d)\n", strerror(errno), errno);
|
||||||
|
(void) close(sock);
|
||||||
|
- return;
|
||||||
|
+ abort();
|
||||||
|
}
|
||||||
|
dprintf("connect()\n");
|
||||||
|
|
||||||
|
@@ -113,7 +113,7 @@ notify_listener(void)
|
||||||
|
if (rv == -1) {
|
||||||
|
fprintf(stderr, "send() error: %s(%d)\n", strerror(errno), errno);
|
||||||
|
(void) close(sock);
|
||||||
|
- return;
|
||||||
|
+ abort();
|
||||||
|
}
|
||||||
|
dprintf("send()\n");
|
||||||
|
|
||||||
|
@@ -123,6 +123,7 @@ notify_listener(void)
|
||||||
|
|
||||||
|
if (rv == -1) {
|
||||||
|
fprintf(stderr, "recv() error: %s(%d)\n", strerror(errno), errno);
|
||||||
|
+ abort();
|
||||||
|
}
|
||||||
|
dprintf("recv()\n");
|
||||||
|
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
379
0010-Add-test-stage-to-pkgbuild.patch
Normal file
379
0010-Add-test-stage-to-pkgbuild.patch
Normal file
@ -0,0 +1,379 @@
|
|||||||
|
From 7d431211063a9bf6c789bb67a2ed216025279a66 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Roman Rashchupkin <rrashchupkin@cloudlinux.com>
|
||||||
|
Date: Tue, 23 Jan 2018 13:41:38 +0300
|
||||||
|
Subject: [PATCH 10/89] Add --test stage to pkgbuild
|
||||||
|
|
||||||
|
Signed-off-by: Roman Rashchupkin <rrashchupkin@cloudlinux.com>
|
||||||
|
---
|
||||||
|
packages/rhel7/glibc/glibc-2.17-55.el7/info | 36 ++++-----
|
||||||
|
.../glibc/glibc-2.17-55.el7/pkgfile.yaml | 1 +
|
||||||
|
scripts/pkgbuild | 81 ++++++++++++++++---
|
||||||
|
scripts/toil/build-patch.sh | 1 -
|
||||||
|
scripts/toil/pkgbuild.py | 57 +++++++++----
|
||||||
|
5 files changed, 126 insertions(+), 50 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/packages/rhel7/glibc/glibc-2.17-55.el7/info b/packages/rhel7/glibc/glibc-2.17-55.el7/info
|
||||||
|
index 8cebabb..e5805c3 100644
|
||||||
|
--- a/packages/rhel7/glibc/glibc-2.17-55.el7/info
|
||||||
|
+++ b/packages/rhel7/glibc/glibc-2.17-55.el7/info
|
||||||
|
@@ -55,21 +55,6 @@ kp_build_hook() {
|
||||||
|
$KP_PROJECT_BUILD_ROOT/SPECS/$KP_PROJECT_SPEC
|
||||||
|
}
|
||||||
|
|
||||||
|
-# Replace patch build results with original libraries for testing
|
||||||
|
-_install_originals() {
|
||||||
|
- eval set -- $KP_INSTALL_FILES
|
||||||
|
- while test -n "$1"; do
|
||||||
|
- local buildpath="$1"
|
||||||
|
- local installpath="$2"
|
||||||
|
- shift 2
|
||||||
|
-
|
||||||
|
- if test "$installpath" = "IGNORE"; then
|
||||||
|
- continue
|
||||||
|
- fi
|
||||||
|
-
|
||||||
|
- /bin/cp -r /root/root.original/$installpath $KP_PROJECT_BUILD_DIR/$buildpath
|
||||||
|
- done
|
||||||
|
-}
|
||||||
|
|
||||||
|
_run_tests() {
|
||||||
|
if test -f $LIBCARE_DIR/execve/execve.so; then
|
||||||
|
@@ -113,15 +98,22 @@ _run_tests() {
|
||||||
|
export PATH=$KCPATH
|
||||||
|
}
|
||||||
|
|
||||||
|
-kp_patch_test() {
|
||||||
|
- _install_originals
|
||||||
|
+kp_prepare_test_binaries() {
|
||||||
|
+ # Replace patch build results with original libraries for testing
|
||||||
|
+ kp_install_files /root/root.original \
|
||||||
|
+ $KP_PROJECT_BUILD_DIR \
|
||||||
|
+ "to_prebuild" \
|
||||||
|
+ "$KP_INSTALL_FILES"
|
||||||
|
+}
|
||||||
|
|
||||||
|
+kp_patch_test() {
|
||||||
|
rm -f /var/run/libcare.sock
|
||||||
|
|
||||||
|
- PATCH_ROOT=/root/${KP_PROJECT_PATCH%.*}
|
||||||
|
+ PATCH_ROOT=$KP_PROJECT_BUILD_ROOT/storage
|
||||||
|
$KPATCH_PATH/libcare-ctl -v server /var/run/libcare.sock $PATCH_ROOT \
|
||||||
|
- >/data/test.log 2>&1 & :
|
||||||
|
+ >/data/libcare-ctl.log 2>&1 & :
|
||||||
|
LISTENER_PID=$!
|
||||||
|
+
|
||||||
|
sleep 1
|
||||||
|
kill -0 $LISTENER_PID
|
||||||
|
|
||||||
|
@@ -134,11 +126,11 @@ kp_patch_test() {
|
||||||
|
|
||||||
|
popd
|
||||||
|
|
||||||
|
- local patched=$(awk '/kpatch_ctl targeting/ { n++ } END { print n }' /data/test.log)
|
||||||
|
+ local patched=$(awk '/kpatch_ctl targeting/ { n++ } END { print n }' /data/libcare-ctl.log)
|
||||||
|
|
||||||
|
test $patched -ge $executed
|
||||||
|
|
||||||
|
- grep -vq 'No patch(es) applicable to' /data/test.log
|
||||||
|
- grep 'patch hunk(s) have been successfully applied' /data/test.log \
|
||||||
|
+ grep -vq 'No patch(es) applicable to' /data/libcare-ctl.log
|
||||||
|
+ grep 'patch hunk(s) have been successfully applied' /data/libcare-ctl.log \
|
||||||
|
| wc -l
|
||||||
|
}
|
||||||
|
diff --git a/packages/rhel7/glibc/glibc-2.17-55.el7/pkgfile.yaml b/packages/rhel7/glibc/glibc-2.17-55.el7/pkgfile.yaml
|
||||||
|
index 51028ed..b17e895 100644
|
||||||
|
--- a/packages/rhel7/glibc/glibc-2.17-55.el7/pkgfile.yaml
|
||||||
|
+++ b/packages/rhel7/glibc/glibc-2.17-55.el7/pkgfile.yaml
|
||||||
|
@@ -1,5 +1,6 @@
|
||||||
|
image: kernelcare/centos7:gcc-4.8.2-16.el7
|
||||||
|
prebuild: /tmp/build.orig-glibc-2.17-55.el7.x86_64.rpm.tgz
|
||||||
|
+patch: /tmp/kpatch-glibc-2.17-55.el7.x86_64.tgz
|
||||||
|
input:
|
||||||
|
- package: .
|
||||||
|
- patches: ../../../../patches/
|
||||||
|
diff --git a/scripts/pkgbuild b/scripts/pkgbuild
|
||||||
|
index 97c78a9..f91af57 100755
|
||||||
|
--- a/scripts/pkgbuild
|
||||||
|
+++ b/scripts/pkgbuild
|
||||||
|
@@ -17,6 +17,7 @@ die() {
|
||||||
|
usage() {
|
||||||
|
echo "Usage: build [--prebuild] [--help] [--arch ARCH] DIR"
|
||||||
|
echo " -p|--prebuild prebuild project for further use"
|
||||||
|
+ echo " -t|--test run unit and stress tests"
|
||||||
|
echo " -a|--arch ARCH target architecture(x86_64 by default)"
|
||||||
|
echo " -h|--help print this message"
|
||||||
|
echo " DIR directory with project's info file and other resources"
|
||||||
|
@@ -32,6 +33,9 @@ prepare() {
|
||||||
|
-p|--prebuild)
|
||||||
|
ACTION=prebuild
|
||||||
|
;;
|
||||||
|
+ -t|--test)
|
||||||
|
+ ACTION=test
|
||||||
|
+ ;;
|
||||||
|
-a|--arch)
|
||||||
|
shift
|
||||||
|
ARCH=$1
|
||||||
|
@@ -247,13 +251,17 @@ kp_build_rpm() {
|
||||||
|
-bc \
|
||||||
|
$KP_RPMBUILD_FLAGS \
|
||||||
|
'--define "_topdir $KP_PROJECT_BUILD_ROOT"' \
|
||||||
|
- $KP_PROJECT_BUILD_ROOT/SPECS/$KP_PROJECT_SPEC
|
||||||
|
+ $KP_PROJECT_BUILD_ROOT/SPECS/$KP_PROJECT_SPEC 2>&1 |
|
||||||
|
+ tee $KP_PROJECT_BUILD_ROOT/build.log
|
||||||
|
}
|
||||||
|
|
||||||
|
-kp_install_generic() {
|
||||||
|
- local ROOT_PATCHED="$HOME/root.patched"
|
||||||
|
+kp_install_files() {
|
||||||
|
+ local src="$1"
|
||||||
|
+ local dest="$2"
|
||||||
|
+ local direction="$3"
|
||||||
|
+ local files="$4"
|
||||||
|
|
||||||
|
- eval set -- $KP_INSTALL_FILES
|
||||||
|
+ eval set -- $files
|
||||||
|
while test -n "$1"; do
|
||||||
|
local buildpath="$1"
|
||||||
|
local installpath="$2"
|
||||||
|
@@ -263,12 +271,16 @@ kp_install_generic() {
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
- installpath="$ROOT_PATCHED/$installpath"
|
||||||
|
-
|
||||||
|
- mkdir -p "$(dirname "$installpath")"
|
||||||
|
-
|
||||||
|
- /bin/cp -ra $KP_PROJECT_BUILD_DIR/$buildpath $installpath
|
||||||
|
+ if test $direction = "from_prebuild"; then
|
||||||
|
+ install -D $src/$buildpath $dest/$installpath
|
||||||
|
+ else
|
||||||
|
+ install -D $src/$installpath $dest/$buildpath
|
||||||
|
+ fi
|
||||||
|
done
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+kp_check_missing_files() {
|
||||||
|
+ local builddir="$1"
|
||||||
|
|
||||||
|
local failed=
|
||||||
|
pushd $KP_PROJECT_BUILD_DIR
|
||||||
|
@@ -295,6 +307,16 @@ kp_install_generic() {
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
+kp_install_generic() {
|
||||||
|
+ local root_patched="$HOME/root.patched"
|
||||||
|
+
|
||||||
|
+ kp_install_files $KP_PROJECT_BUILD_DIR \
|
||||||
|
+ $root_patched \
|
||||||
|
+ "from_prebuild" \
|
||||||
|
+ "$KP_INSTALL_FILES"
|
||||||
|
+ kp_check_missing_files $KP_PROJECT_BUILD_DIR
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
kp_install_rpm() {
|
||||||
|
kp_install_orig_rpm
|
||||||
|
kp_install_generic
|
||||||
|
@@ -367,6 +389,33 @@ kp_pack_patch() {
|
||||||
|
popd
|
||||||
|
}
|
||||||
|
|
||||||
|
+kp_unpack_patch() {
|
||||||
|
+ local tmpdir=$(mktemp -d --tmpdir)
|
||||||
|
+
|
||||||
|
+ echo " unpacking patches for $KP_PROJECT into $KP_PROJECT_BUILD_ROOT/storage"
|
||||||
|
+
|
||||||
|
+ tar -xf /kcdata/$KP_PROJECT_PATCH -C $tmpdir
|
||||||
|
+
|
||||||
|
+ find $tmpdir -name \*.kpatch > $tmpdir/patchlist
|
||||||
|
+
|
||||||
|
+ while read patchfile; do
|
||||||
|
+ local patchname=${patchfile##*/}
|
||||||
|
+ local buildid=${patchname%.kpatch}
|
||||||
|
+
|
||||||
|
+ local KP_STORAGE=$KP_PROJECT_BUILD_ROOT/storage/$buildid
|
||||||
|
+
|
||||||
|
+ mkdir -p $KP_STORAGE/1
|
||||||
|
+ cp $patchfile $KP_STORAGE/1/kpatch.bin
|
||||||
|
+ ln -rs $KP_STORAGE/1 $KP_STORAGE/latest
|
||||||
|
+ done < $tmpdir/patchlist
|
||||||
|
+
|
||||||
|
+ rm -fr $tmpdir
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+kp_mark_tests_fail() {
|
||||||
|
+ touch /kcdata/Tests-FAIL
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
overwrite_utils() {
|
||||||
|
TMPBIN=$(mktemp -d --tmpdir)
|
||||||
|
|
||||||
|
@@ -394,7 +443,8 @@ overwrite_utils() {
|
||||||
|
}
|
||||||
|
|
||||||
|
kp_patch_test() {
|
||||||
|
- :
|
||||||
|
+ echo "Empty kp_patch_test called, override it!"
|
||||||
|
+ exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
@@ -408,20 +458,25 @@ main() {
|
||||||
|
|
||||||
|
kp_prepare_env_hook
|
||||||
|
|
||||||
|
- if [ "$ACTION" == "prebuild" ]; then
|
||||||
|
+ if test "$ACTION" == "prebuild"; then
|
||||||
|
kp_prepare_source
|
||||||
|
kp_prebuild_hook
|
||||||
|
kp_prebuild
|
||||||
|
kp_pack_prebuilt
|
||||||
|
- else
|
||||||
|
+ elif test "$ACTION" == "build"; then
|
||||||
|
kp_unpack_prebuilt
|
||||||
|
kp_patch_source
|
||||||
|
kp_build_hook
|
||||||
|
kp_build
|
||||||
|
kp_sanity_check
|
||||||
|
kp_gen_kpatch
|
||||||
|
- kp_patch_test
|
||||||
|
kp_pack_patch
|
||||||
|
+ elif test "$ACTION" == "test"; then
|
||||||
|
+ kp_unpack_prebuilt
|
||||||
|
+ kp_prepare_test_binaries
|
||||||
|
+ kp_unpack_patch
|
||||||
|
+ #kp_patch_source
|
||||||
|
+ kp_patch_test
|
||||||
|
fi
|
||||||
|
|
||||||
|
#clean_dirs
|
||||||
|
diff --git a/scripts/toil/build-patch.sh b/scripts/toil/build-patch.sh
|
||||||
|
index 0e12de4..28720a1 100755
|
||||||
|
--- a/scripts/toil/build-patch.sh
|
||||||
|
+++ b/scripts/toil/build-patch.sh
|
||||||
|
@@ -15,4 +15,3 @@ make -C $KPATCH_PATH clean all
|
||||||
|
make -C /data/execve clean all
|
||||||
|
|
||||||
|
/kcdata/scripts/pkgbuild $@ /kcdata/package
|
||||||
|
-ls /kcdata -lR
|
||||||
|
diff --git a/scripts/toil/pkgbuild.py b/scripts/toil/pkgbuild.py
|
||||||
|
index c4b009a..e091032 100755
|
||||||
|
--- a/scripts/toil/pkgbuild.py
|
||||||
|
+++ b/scripts/toil/pkgbuild.py
|
||||||
|
@@ -12,8 +12,9 @@ The basic components are the following:
|
||||||
|
first job.
|
||||||
|
|
||||||
|
#. `DoBuild` checks presence of the object in the Storage and runs
|
||||||
|
- `prebuildJob` chained with `uploadJob` and `buildJob` if the object is missing.
|
||||||
|
- Only `buildJob` is run otherwise.
|
||||||
|
+ `prebuildJob` chained with `uploadPrebuildJob`, `buildJob`,
|
||||||
|
+ `uploadPatchJob` and `testJob` if the object is missing.
|
||||||
|
+ Only `buildJob` and it's children are run otherwise.
|
||||||
|
|
||||||
|
This is used to build missing parts such as an archive with the baseline
|
||||||
|
source code called `prebuilt` which is listed as optional for the
|
||||||
|
@@ -625,7 +626,7 @@ class S3DownloadJob(S3FileJob):
|
||||||
|
self.fileName = fileName
|
||||||
|
super(S3DownloadJob, self).__init__(
|
||||||
|
memory="1M", cores=1, unitName="download %s" % url,
|
||||||
|
- disk=self.obj['ContentLength'])
|
||||||
|
+ disk=max(4096, self.obj['ContentLength']))
|
||||||
|
|
||||||
|
def run(self, fileStore):
|
||||||
|
with fileStore.writeGlobalFileStream() as (fh, fileId):
|
||||||
|
@@ -731,24 +732,35 @@ class DoBuild(Job):
|
||||||
|
"""If prebuild archive is not in storage do a prebuild and upload it to the
|
||||||
|
specified location. Otherwise just do a build."""
|
||||||
|
|
||||||
|
- def __init__(self, fileName, prebuildJob, uploadJob, buildJob):
|
||||||
|
+ def __init__(self, prebuildFileName, buildFileName, prebuildJob, uploadPrebuildJob, buildJob, uploadPatchJob, testJob):
|
||||||
|
super(DoBuild, self).__init__(memory="256M")
|
||||||
|
|
||||||
|
- self.fileName = fileName
|
||||||
|
+ self.prebuildFileName = prebuildFileName
|
||||||
|
+ self.buildFileName = buildFileName
|
||||||
|
self.prebuildJob = prebuildJob
|
||||||
|
self.buildJob = buildJob
|
||||||
|
- self.uploadJob = uploadJob
|
||||||
|
+ self.uploadPrebuildJob = uploadPrebuildJob
|
||||||
|
+ self.uploadPatchJob = uploadPatchJob
|
||||||
|
+ self.testJob = testJob
|
||||||
|
|
||||||
|
def run(self, fileStore):
|
||||||
|
- if self.fileName not in self.storage:
|
||||||
|
+ if self.prebuildFileName not in self.storage:
|
||||||
|
self.addChild(self.prebuildJob)
|
||||||
|
|
||||||
|
self.prebuildJob.addChildNoStorage(self.buildJob)
|
||||||
|
- self.prebuildJob.addChildNoStorage(self.uploadJob)
|
||||||
|
+ self.prebuildJob.addChildNoStorage(self.uploadPrebuildJob)
|
||||||
|
+
|
||||||
|
+ self.buildJob.addChildNoStorage(self.uploadPatchJob)
|
||||||
|
+ self.buildJob.addChildNoStorage(self.testJob)
|
||||||
|
else:
|
||||||
|
- self.addChild(self.buildJob)
|
||||||
|
+ if self.buildFileName not in self.storage:
|
||||||
|
+ self.addChild(self.buildJob)
|
||||||
|
+ self.buildJob.addChildNoStorage(self.uploadPatchJob)
|
||||||
|
+ self.buildJob.addChildNoStorage(self.testJob)
|
||||||
|
+ else:
|
||||||
|
+ self.addChild(self.testJob)
|
||||||
|
|
||||||
|
- self._storage = self.buildJob.storage
|
||||||
|
+ self._storage = self.testJob.storage
|
||||||
|
|
||||||
|
|
||||||
|
class BuildPatchJob(toilJob):
|
||||||
|
@@ -784,21 +796,33 @@ class BuildPatchJob(toilJob):
|
||||||
|
prebuildUrl = self.packageDescription['prebuild']
|
||||||
|
prebuildName = os.path.basename(prebuildUrl)
|
||||||
|
|
||||||
|
+ patchUrl = self.packageDescription['patch']
|
||||||
|
+ buildName = os.path.basename(patchUrl)
|
||||||
|
+
|
||||||
|
prebuildJob = DockerScriptJob(
|
||||||
|
script=self.script,
|
||||||
|
image=self.image,
|
||||||
|
- args=['-p'],
|
||||||
|
+ args=['--prebuild'],
|
||||||
|
logfileName="prebuild.log")
|
||||||
|
- uploadJob = UploadJob([(prebuildName, prebuildUrl)])
|
||||||
|
+ uploadPrebuildJob = UploadJob([(prebuildName, prebuildUrl)])
|
||||||
|
+
|
||||||
|
|
||||||
|
buildJob = DockerScriptJob(
|
||||||
|
script=self.script,
|
||||||
|
image=self.image,
|
||||||
|
logfileName="build.log")
|
||||||
|
+ uploadPatchJob = UploadJob([(buildName, patchUrl)])
|
||||||
|
|
||||||
|
+ testJob = DockerScriptJob(
|
||||||
|
+ script=self.script,
|
||||||
|
+ image=self.image,
|
||||||
|
+ args=['--test'],
|
||||||
|
+ logfileName="test.log")
|
||||||
|
+
|
||||||
|
+ doBuild = DoBuild(prebuildFileName=prebuildName, buildFileName=buildName, prebuildJob=prebuildJob,
|
||||||
|
+ uploadPrebuildJob=uploadPrebuildJob, buildJob=buildJob,
|
||||||
|
+ uploadPatchJob=uploadPatchJob, testJob=testJob)
|
||||||
|
|
||||||
|
- doBuild = DoBuild(fileName=prebuildName, prebuildJob=prebuildJob,
|
||||||
|
- uploadJob=uploadJob, buildJob=buildJob)
|
||||||
|
tail.addFollowOn(doBuild)
|
||||||
|
tail = doBuild
|
||||||
|
|
||||||
|
@@ -831,6 +855,11 @@ def readPackageDescription(packageFile):
|
||||||
|
prebuildUrl = '*' + prebuildUrl
|
||||||
|
inputs.append(prebuildUrl)
|
||||||
|
|
||||||
|
+ patchUrl = packageDescription['patch']
|
||||||
|
+ if not patchUrl.startswith('*'):
|
||||||
|
+ patchUrl = '*' + patchUrl
|
||||||
|
+ inputs.append(patchUrl)
|
||||||
|
+
|
||||||
|
return packageDescription
|
||||||
|
|
||||||
|
def start(toil):
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
36
0011-glibc-minimal-readme-for-toil-builder.patch
Normal file
36
0011-glibc-minimal-readme-for-toil-builder.patch
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
From 0c0f6387230d6164eaa58ae4a95656539ace5159 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Pavel Boldin <pboldin@cloudlinux.com>
|
||||||
|
Date: Tue, 30 Jan 2018 16:42:32 +0200
|
||||||
|
Subject: [PATCH 11/89] glibc: minimal readme for toil builder
|
||||||
|
|
||||||
|
Signed-off-by: Pavel Boldin <pboldin@cloudlinux.com>
|
||||||
|
---
|
||||||
|
packages/rhel7/glibc/glibc-2.17-55.el7/README.md | 16 ++++++++++++++++
|
||||||
|
1 file changed, 16 insertions(+)
|
||||||
|
create mode 100644 packages/rhel7/glibc/glibc-2.17-55.el7/README.md
|
||||||
|
|
||||||
|
diff --git a/packages/rhel7/glibc/glibc-2.17-55.el7/README.md b/packages/rhel7/glibc/glibc-2.17-55.el7/README.md
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..740d294
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/packages/rhel7/glibc/glibc-2.17-55.el7/README.md
|
||||||
|
@@ -0,0 +1,16 @@
|
||||||
|
+Use toil-based build script to build patches for the `glibc`. For that simple
|
||||||
|
+run::
|
||||||
|
+
|
||||||
|
+```shell
|
||||||
|
+$ LIBCARE_DIR=~/libcare-opensource
|
||||||
|
+$ pip install -r $LIBCARE_DIR/scripts/toil/requirements.txt
|
||||||
|
+$ python $LIBCARE_DIR/scripts/toil/pkgbuild.py workdir pkgfile.yaml
|
||||||
|
+...
|
||||||
|
+```
|
||||||
|
+
|
||||||
|
+This should build the following files:
|
||||||
|
+```shell
|
||||||
|
+$ ls /tmp/build.orig-glibc-2.17-55.el7.x86_64.rpm.tgz /tmp/kpatch-glibc-2.17-55.el7.x86_64.tgz
|
||||||
|
+/tmp/build.orig-glibc-2.17-55.el7.x86_64.rpm.tgz
|
||||||
|
+/tmp/kpatch-glibc-2.17-55.el7.x86_64.tgz
|
||||||
|
+```
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
46
0012-Fix-kpatch_process_init-kpatch_coroutines_free.patch
Normal file
46
0012-Fix-kpatch_process_init-kpatch_coroutines_free.patch
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
From 3566489ee43a348f41bb0fd9c779f1064956ea82 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Roman Rashchupkin <rrashchupkin@cloudlinux.com>
|
||||||
|
Date: Thu, 25 Jan 2018 10:18:33 +0300
|
||||||
|
Subject: [PATCH 12/89] Fix kpatch_process_init/kpatch_coroutines_free
|
||||||
|
|
||||||
|
---
|
||||||
|
src/kpatch_coro.c | 7 ++++---
|
||||||
|
src/kpatch_process.c | 4 ++--
|
||||||
|
2 files changed, 6 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/kpatch_coro.c b/src/kpatch_coro.c
|
||||||
|
index ff485fc..45d4a0b 100644
|
||||||
|
--- a/src/kpatch_coro.c
|
||||||
|
+++ b/src/kpatch_coro.c
|
||||||
|
@@ -622,7 +622,8 @@ void kpatch_coroutines_free(struct kpatch_process *proc)
|
||||||
|
if (proc->coro.unwd)
|
||||||
|
unw_destroy_addr_space(proc->coro.unwd);
|
||||||
|
|
||||||
|
- list_for_each_entry_safe(c, tmp, &proc->coro.coros, list) {
|
||||||
|
- kpatch_coro_free(c);
|
||||||
|
- }
|
||||||
|
+ if (!list_empty(&proc->coro.coros))
|
||||||
|
+ list_for_each_entry_safe(c, tmp, &proc->coro.coros, list) {
|
||||||
|
+ kpatch_coro_free(c);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
diff --git a/src/kpatch_process.c b/src/kpatch_process.c
|
||||||
|
index d394925..2f85373 100644
|
||||||
|
--- a/src/kpatch_process.c
|
||||||
|
+++ b/src/kpatch_process.c
|
||||||
|
@@ -1121,10 +1121,10 @@ kpatch_process_init(kpatch_process_t *proc,
|
||||||
|
list_init(&proc->vmaholes);
|
||||||
|
proc->num_objs = 0;
|
||||||
|
|
||||||
|
- if (process_get_comm(proc))
|
||||||
|
- goto out_unlock;
|
||||||
|
if (kpatch_coroutines_init(proc))
|
||||||
|
goto out_unlock;
|
||||||
|
+ if (process_get_comm(proc))
|
||||||
|
+ goto out_unlock;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
206
0013-Add-libcare-stresstest.patch
Normal file
206
0013-Add-libcare-stresstest.patch
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
From 4cd3610aa11c7b6add5cf090127c522d8004a528 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Roman Rashchupkin <rrashchupkin@cloudlinux.com>
|
||||||
|
Date: Wed, 24 Jan 2018 16:01:51 +0300
|
||||||
|
Subject: [PATCH 13/89] Add libcare-stresstest
|
||||||
|
|
||||||
|
---
|
||||||
|
src/Makefile | 10 ++++-
|
||||||
|
src/kpatch_user.c | 106 +++++++++++++++++++++++++++++++++++++++++++++-
|
||||||
|
2 files changed, 114 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/Makefile b/src/Makefile
|
||||||
|
index cd766e1..58e942a 100644
|
||||||
|
--- a/src/Makefile
|
||||||
|
+++ b/src/Makefile
|
||||||
|
@@ -3,7 +3,8 @@ TARGETS = kpatch_gensrc \
|
||||||
|
kpatch_strip \
|
||||||
|
libcare-cc \
|
||||||
|
libcare-client \
|
||||||
|
- libcare-ctl
|
||||||
|
+ libcare-ctl \
|
||||||
|
+ libcare-stresstest
|
||||||
|
DEBUG = yes # comment out this line if not debug
|
||||||
|
|
||||||
|
CC = gcc
|
||||||
|
@@ -39,6 +40,10 @@ libcare-ctl: kpatch_user.o kpatch_storage.o kpatch_patch.c kpatch_elf.o kpatch_p
|
||||||
|
libcare-ctl: kpatch_process.o kpatch_common.o rbtree.o kpatch_log.o
|
||||||
|
libcare-ctl: LDLIBS += -lelf -lrt $(LIBUNWIND_LIBS)
|
||||||
|
|
||||||
|
+libcare-stresstest: kpatch_user-stresstest.o kpatch_storage.o kpatch_patch.c kpatch_elf.o kpatch_ptrace.o kpatch_coro.o
|
||||||
|
+libcare-stresstest: kpatch_process.o kpatch_common.o rbtree.o kpatch_log.o
|
||||||
|
+libcare-stresstest: LDLIBS += -lelf -lrt $(LIBUNWIND_LIBS)
|
||||||
|
+
|
||||||
|
libcare-client: libcare-client.o
|
||||||
|
|
||||||
|
kpatch_strip: kpatch_strip.o kpatch_elf_objinfo.o kpatch_log.o
|
||||||
|
@@ -61,6 +66,9 @@ endif
|
||||||
|
%.o: %.c deps/%.d
|
||||||
|
$(CC) $(CFLAGS) $(CFLAGS_$(*)) -o $(@) -c $(<)
|
||||||
|
|
||||||
|
+%-stresstest.o: %.c
|
||||||
|
+ $(CC) -DSTRESS_TEST=1 $(CFLAGS) $(CFLAGS_$(*)) -o $(@) -c $(<)
|
||||||
|
+
|
||||||
|
clean:
|
||||||
|
rm -rf *.o core.* deps/*.d $(TARGETS)
|
||||||
|
for f in tests/gensrc/*.s; do \
|
||||||
|
diff --git a/src/kpatch_user.c b/src/kpatch_user.c
|
||||||
|
index d257b67..e6649b0 100644
|
||||||
|
--- a/src/kpatch_user.c
|
||||||
|
+++ b/src/kpatch_user.c
|
||||||
|
@@ -6,6 +6,7 @@
|
||||||
|
#include <string.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <regex.h>
|
||||||
|
+#include <time.h>
|
||||||
|
#include <sys/fcntl.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
@@ -563,6 +564,88 @@ cmd_update(int argc, char *argv[])
|
||||||
|
/* send_fd */ -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
+#ifdef STRESS_TEST
|
||||||
|
+
|
||||||
|
+struct test_data {
|
||||||
|
+ int option_period;
|
||||||
|
+ int stat_cycle_num;
|
||||||
|
+} test_info = { .option_period = 0, .stat_cycle_num = 0 };
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+server_wait(int pid, int period)
|
||||||
|
+{
|
||||||
|
+ struct timespec req, rem;
|
||||||
|
+ int i;
|
||||||
|
+ req.tv_sec = 0;
|
||||||
|
+ req.tv_nsec = 1000*1000;
|
||||||
|
+ for (i=0; i<period; i++) {
|
||||||
|
+ nanosleep(&req, &rem);
|
||||||
|
+ if (kill(pid, 0) != 0) {
|
||||||
|
+ fprintf(stderr, "Process %d terminated.\n", pid);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+server_stress_test(int fd, int argc, char *argv[])
|
||||||
|
+{
|
||||||
|
+ int pid;
|
||||||
|
+ int delay;
|
||||||
|
+ test_info.stat_cycle_num = 0;
|
||||||
|
+ srand(time(NULL));
|
||||||
|
+
|
||||||
|
+ if (sscanf(argv[1], "%d", &pid) != 1) {
|
||||||
|
+ kperr("Can't parse pid from %s\n", argv[1]);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ while (1) {
|
||||||
|
+ while (patch_user(storage_dir, pid, 0, fd) < 0)
|
||||||
|
+ if (server_wait(pid, 1) < 0)
|
||||||
|
+ return 0;
|
||||||
|
+ if (fd > 0)
|
||||||
|
+ close(fd);
|
||||||
|
+ fd = -1;
|
||||||
|
+ if (test_info.option_period == 0)
|
||||||
|
+ return 0;
|
||||||
|
+ delay = rand() % test_info.option_period;
|
||||||
|
+ if (server_wait(pid, delay) < 0)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ while (processes_unpatch(pid, 0, 0) < 0)
|
||||||
|
+ if (server_wait(pid, 1) < 0)
|
||||||
|
+ return 0;
|
||||||
|
+ test_info.stat_cycle_num++;
|
||||||
|
+
|
||||||
|
+ delay = rand() % test_info.option_period;
|
||||||
|
+ if (server_wait(pid, delay) < 0)
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int cmd_stress_test(int fd, int argc, char *argv[])
|
||||||
|
+{
|
||||||
|
+ int child = fork();
|
||||||
|
+ if (child == 0) {
|
||||||
|
+ int rv = server_stress_test(fd, argc, argv);
|
||||||
|
+ exit(rv);
|
||||||
|
+ }
|
||||||
|
+ close(fd);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int usage_stresstest()
|
||||||
|
+{
|
||||||
|
+ fprintf(stderr, "usage: libcare-stresstest PERIOD(ms, 0 - only patch) <UNIX socket> [STORAGE ROOT]\n");
|
||||||
|
+ return -1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
static int
|
||||||
|
server_execute_cmd(int fd, int argc, char *argv[])
|
||||||
|
{
|
||||||
|
@@ -572,8 +655,13 @@ server_execute_cmd(int fd, int argc, char *argv[])
|
||||||
|
|
||||||
|
if (!strcmp(cmd, "execve"))
|
||||||
|
return cmd_execve_startup(fd, argc, argv, 1);
|
||||||
|
- if (!strcmp(cmd, "startup"))
|
||||||
|
+ if (!strcmp(cmd, "startup")) {
|
||||||
|
+#ifdef STRESS_TEST
|
||||||
|
+ return cmd_stress_test(fd, argc, argv);
|
||||||
|
+#else
|
||||||
|
return cmd_execve_startup(fd, argc, argv, 0);
|
||||||
|
+#endif
|
||||||
|
+ }
|
||||||
|
if (!strcmp(cmd, "update"))
|
||||||
|
return cmd_update(argc, argv);
|
||||||
|
if (!strcmp(cmd, "storage"))
|
||||||
|
@@ -739,6 +827,12 @@ cmd_server(int argc, char *argv[])
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+#ifdef STRESS_TEST
|
||||||
|
+ if (sscanf(argv[0], "%d", &test_info.option_period) != 1) {
|
||||||
|
+ kplogerror("Can't parse period from %s\n", argv[0]);
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
sfd = server_bind_socket(argv[1]);
|
||||||
|
if (sfd < 0)
|
||||||
|
return sfd;
|
||||||
|
@@ -824,6 +918,9 @@ static int usage(const char *err)
|
||||||
|
{
|
||||||
|
if (err)
|
||||||
|
fprintf(stderr, "err: %s\n", err);
|
||||||
|
+#ifdef STRESS_TEST
|
||||||
|
+ return usage_stresstest();
|
||||||
|
+#endif
|
||||||
|
fprintf(stderr, "usage: libcare-ctl [options] <cmd> [args]\n");
|
||||||
|
fprintf(stderr, "\nOptions:\n");
|
||||||
|
fprintf(stderr, " -v - verbose mode\n");
|
||||||
|
@@ -872,6 +969,12 @@ int main(int argc, char *argv[])
|
||||||
|
argc -= optind;
|
||||||
|
argv += optind;
|
||||||
|
|
||||||
|
+#ifdef STRESS_TEST
|
||||||
|
+ if (argc < 3)
|
||||||
|
+ return usage("not enough arguments.");
|
||||||
|
+ signal(SIGCHLD, SIG_IGN);
|
||||||
|
+ return cmd_server(argc, argv);
|
||||||
|
+#else
|
||||||
|
if (argc < 1)
|
||||||
|
return usage("not enough arguments.");
|
||||||
|
|
||||||
|
@@ -879,4 +982,5 @@ int main(int argc, char *argv[])
|
||||||
|
return cmd_server(argc, argv);
|
||||||
|
else
|
||||||
|
return execute_cmd(argc, argv);
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
93
0014-read-auxv-from-proc-pid-auxv.patch
Normal file
93
0014-read-auxv-from-proc-pid-auxv.patch
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
From 212e98a668117a11aa528e5669189b58dcaacd95 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Pavel Boldin <pboldin@cloudlinux.com>
|
||||||
|
Date: Wed, 7 Feb 2018 09:14:39 +0200
|
||||||
|
Subject: [PATCH 14/89] read auxv from /proc/pid/auxv
|
||||||
|
|
||||||
|
Signed-off-by: Pavel Boldin <pboldin@cloudlinux.com>
|
||||||
|
---
|
||||||
|
src/kpatch_ptrace.c | 54 +++++++++++++++++----------------------------
|
||||||
|
1 file changed, 20 insertions(+), 34 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/kpatch_ptrace.c b/src/kpatch_ptrace.c
|
||||||
|
index f732004..f91b80e 100644
|
||||||
|
--- a/src/kpatch_ptrace.c
|
||||||
|
+++ b/src/kpatch_ptrace.c
|
||||||
|
@@ -143,55 +143,41 @@ int kpatch_process_mem_iter_peek_ulong(struct process_mem_iter *iter,
|
||||||
|
return kpatch_process_mem_iter_peek(iter, dst, sizeof(*dst), remote_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
-/* FIXME(pboldin): read these from /proc/pid/auxv */
|
||||||
|
int kpatch_ptrace_get_entry_point(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
unsigned long *pentry_point)
|
||||||
|
{
|
||||||
|
- int ret;
|
||||||
|
- unsigned long *rstack, val;
|
||||||
|
- struct user_regs_struct regs;
|
||||||
|
- struct process_mem_iter *iter;
|
||||||
|
+ int fd, ret;
|
||||||
|
+ unsigned long entry[2] = { AT_NULL, 0 };
|
||||||
|
+ char path[sizeof("/proc/0123456789/auxv")];
|
||||||
|
|
||||||
|
kpdebug("Looking for entry point...");
|
||||||
|
|
||||||
|
- ret = ptrace(PTRACE_GETREGS, pctx->pid, NULL, ®s);
|
||||||
|
- if (ret < 0) {
|
||||||
|
- kplogerror("can't get regs\n");
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- iter = kpatch_process_mem_iter_init(pctx->proc);
|
||||||
|
- if (!iter) {
|
||||||
|
- kplogerror("can't allocate iterator\n");
|
||||||
|
+ sprintf(path, "/proc/%d/auxv", pctx->pid);
|
||||||
|
+ fd = open(path, O_RDONLY);
|
||||||
|
+ if (fd == -1) {
|
||||||
|
+ kplogerror("can't open %s\n", path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* Read stack and look for AUX data */
|
||||||
|
- rstack = (unsigned long*)regs.rsp;
|
||||||
|
-
|
||||||
|
- /* rstack now points to envs */
|
||||||
|
- rstack += PEEK_ULONG(rstack) + 2;
|
||||||
|
-
|
||||||
|
- /* Skip envs */
|
||||||
|
- for (; PEEK_ULONG(rstack); rstack++)
|
||||||
|
- continue;
|
||||||
|
+ do {
|
||||||
|
+ ret = read(fd, entry, sizeof(entry));
|
||||||
|
+ if (ret < 0 && errno == EINTR)
|
||||||
|
+ continue;
|
||||||
|
+ if (ret != sizeof(entry))
|
||||||
|
+ break;
|
||||||
|
|
||||||
|
- /* Now got to AUX */
|
||||||
|
- for (rstack++; (val = PEEK_ULONG(rstack)) != AT_NULL; rstack += 2) {
|
||||||
|
- if (val == AT_ENTRY) {
|
||||||
|
- *pentry_point = PEEK_ULONG(rstack + 1);
|
||||||
|
+ if (entry[0] == AT_ENTRY) {
|
||||||
|
+ *pentry_point = entry[1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
- }
|
||||||
|
+ } while (1);
|
||||||
|
|
||||||
|
- if (val != AT_ENTRY)
|
||||||
|
- kpdebug("FAIL\n");
|
||||||
|
- else
|
||||||
|
- kpdebug("OK\n");
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ kplogerror("reading %s\n", path);
|
||||||
|
|
||||||
|
- kpatch_process_mem_iter_free(iter);
|
||||||
|
+ close(fd);
|
||||||
|
|
||||||
|
- return val == AT_ENTRY ? 0 : -1;
|
||||||
|
+ return entry[0] == AT_ENTRY ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BREAK_INSN_LENGTH 1
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
147
0015-add-fail-to-unpatch-test.patch
Normal file
147
0015-add-fail-to-unpatch-test.patch
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
From f25aa052cd31cab4c6301cca5eb8e5e5f129d5bd Mon Sep 17 00:00:00 2001
|
||||||
|
From: Pavel Boldin <pboldin@cloudlinux.com>
|
||||||
|
Date: Wed, 7 Feb 2018 23:59:39 +0200
|
||||||
|
Subject: [PATCH 15/89] add `fail to unpatch` test
|
||||||
|
|
||||||
|
Add a test sample where patch is always busy in the loop and cannot
|
||||||
|
be unapplied.
|
||||||
|
|
||||||
|
Signed-off-by: Pavel Boldin <pboldin@cloudlinux.com>
|
||||||
|
---
|
||||||
|
tests/fail_unpatch/Makefile | 4 ++++
|
||||||
|
tests/fail_unpatch/desc | 1 +
|
||||||
|
tests/fail_unpatch/fail_unpatch.c | 29 ++++++++++++++++++++++++++++
|
||||||
|
tests/fail_unpatch/fail_unpatch.diff | 11 +++++++++++
|
||||||
|
tests/run_tests.sh | 25 ++++++++++++++++++++++--
|
||||||
|
5 files changed, 68 insertions(+), 2 deletions(-)
|
||||||
|
create mode 100644 tests/fail_unpatch/Makefile
|
||||||
|
create mode 100644 tests/fail_unpatch/desc
|
||||||
|
create mode 100644 tests/fail_unpatch/fail_unpatch.c
|
||||||
|
create mode 100644 tests/fail_unpatch/fail_unpatch.diff
|
||||||
|
|
||||||
|
diff --git a/tests/fail_unpatch/Makefile b/tests/fail_unpatch/Makefile
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..d7680e9
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/fail_unpatch/Makefile
|
||||||
|
@@ -0,0 +1,4 @@
|
||||||
|
+
|
||||||
|
+LDLIBS:=-lpthread
|
||||||
|
+
|
||||||
|
+include ../makefile.inc
|
||||||
|
diff --git a/tests/fail_unpatch/desc b/tests/fail_unpatch/desc
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..02151c5
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/fail_unpatch/desc
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+fails to unpatch the code
|
||||||
|
diff --git a/tests/fail_unpatch/fail_unpatch.c b/tests/fail_unpatch/fail_unpatch.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..6b5c50f
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/fail_unpatch/fail_unpatch.c
|
||||||
|
@@ -0,0 +1,29 @@
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <unistd.h>
|
||||||
|
+
|
||||||
|
+void print_greetings_patched(void)
|
||||||
|
+{
|
||||||
|
+ while (1) {
|
||||||
|
+ printf("Hello. This a PATCHED version!\n");
|
||||||
|
+ sleep(1);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void print_greetings(void)
|
||||||
|
+{
|
||||||
|
+ printf("Hello. This is an UNPATCHED version!\n");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void do_work() {
|
||||||
|
+ while (1) {
|
||||||
|
+ print_greetings();
|
||||||
|
+ sleep(1);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int main()
|
||||||
|
+{
|
||||||
|
+ do_work();
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
diff --git a/tests/fail_unpatch/fail_unpatch.diff b/tests/fail_unpatch/fail_unpatch.diff
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..49738bd
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/fail_unpatch/fail_unpatch.diff
|
||||||
|
@@ -0,0 +1,11 @@
|
||||||
|
+--- ./fail_unpatch.c 2018-02-07 18:39:27.145493215 +0200
|
||||||
|
++++ ./fail_unpatch.c 2018-02-07 18:39:43.349482218 +0200
|
||||||
|
+@@ -11,7 +11,7 @@
|
||||||
|
+
|
||||||
|
+ void print_greetings(void)
|
||||||
|
+ {
|
||||||
|
+- printf("Hello. This is an UNPATCHED version!\n");
|
||||||
|
++ print_greetings_patched();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ void do_work() {
|
||||||
|
diff --git a/tests/run_tests.sh b/tests/run_tests.sh
|
||||||
|
index fbfb273..2bdd303 100755
|
||||||
|
--- a/tests/run_tests.sh
|
||||||
|
+++ b/tests/run_tests.sh
|
||||||
|
@@ -105,6 +105,10 @@ check_result() {
|
||||||
|
! grep_tail 'UNPATCHED'
|
||||||
|
return $?
|
||||||
|
;;
|
||||||
|
+ fail_unpatch)
|
||||||
|
+ grep_tail '\<PATCHED'
|
||||||
|
+ return $?
|
||||||
|
+ ;;
|
||||||
|
fail_*)
|
||||||
|
grep_tail 'UNPATCHED'
|
||||||
|
return $?
|
||||||
|
@@ -163,9 +167,24 @@ test_patch_files_fini() {
|
||||||
|
|
||||||
|
|
||||||
|
check_result_unpatch() {
|
||||||
|
+ local testname="$1"
|
||||||
|
local outfile="$2"
|
||||||
|
+
|
||||||
|
check_result "$@"
|
||||||
|
- test $? -ne "$(cat ${outfile}_patched)"
|
||||||
|
+ test $? -eq 0
|
||||||
|
+ local is_unpatched=$?
|
||||||
|
+
|
||||||
|
+ test "$(cat ${outfile}_patched)" -eq 1
|
||||||
|
+ local was_patched=$?
|
||||||
|
+
|
||||||
|
+ case $testname in
|
||||||
|
+ fail_unpatch)
|
||||||
|
+ test $is_unpatched -eq 0 && test $was_patched -eq 1
|
||||||
|
+ ;;
|
||||||
|
+ *)
|
||||||
|
+ test $is_unpatched -eq 1 && test $was_patched -eq 1
|
||||||
|
+ ;;
|
||||||
|
+ esac
|
||||||
|
}
|
||||||
|
|
||||||
|
test_unpatch_files_init() {
|
||||||
|
@@ -200,9 +219,11 @@ test_unpatch_files() {
|
||||||
|
|
||||||
|
check_result $testname $outfile
|
||||||
|
echo $? >${outfile}_patched
|
||||||
|
+ cat ${outfile}_patched
|
||||||
|
|
||||||
|
+ echo "============unpatching===============" >>$logfile
|
||||||
|
libcare_ctl unpatch-user -p $pid \
|
||||||
|
- >$logfile 2>&1 || :
|
||||||
|
+ >>$logfile 2>&1 || :
|
||||||
|
|
||||||
|
sleep 2
|
||||||
|
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
67
0016-Waitpid-for-finished-threads-after-detach.patch
Normal file
67
0016-Waitpid-for-finished-threads-after-detach.patch
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
From b6b35d80755caed0528dfdf3825ecf055fe9ea76 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Roman Rashchupkin <rrashchupkin@cloudlinux.com>
|
||||||
|
Date: Wed, 28 Feb 2018 23:05:50 +0300
|
||||||
|
Subject: [PATCH 16/89] Waitpid for finished threads after detach.
|
||||||
|
|
||||||
|
---
|
||||||
|
src/kpatch_process.c | 14 +++++++++++++-
|
||||||
|
src/kpatch_ptrace.c | 2 +-
|
||||||
|
2 files changed, 14 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/kpatch_process.c b/src/kpatch_process.c
|
||||||
|
index 2f85373..5c0374a 100644
|
||||||
|
--- a/src/kpatch_process.c
|
||||||
|
+++ b/src/kpatch_process.c
|
||||||
|
@@ -12,6 +12,11 @@
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/sysmacros.h>
|
||||||
|
|
||||||
|
+#include <sys/syscall.h>
|
||||||
|
+#include <sys/types.h>
|
||||||
|
+#include <sys/wait.h>
|
||||||
|
+#include <sys/ptrace.h>
|
||||||
|
+
|
||||||
|
#include <gelf.h>
|
||||||
|
#include <libunwind.h>
|
||||||
|
#include <libunwind-ptrace.h>
|
||||||
|
@@ -537,6 +542,8 @@ static void
|
||||||
|
process_detach(kpatch_process_t *proc)
|
||||||
|
{
|
||||||
|
struct kpatch_ptrace_ctx *p, *ptmp;
|
||||||
|
+ int status;
|
||||||
|
+ pid_t pid;
|
||||||
|
|
||||||
|
if (proc->memfd >= 0 && close(proc->memfd) < 0)
|
||||||
|
kplogerror("can't close memfd");
|
||||||
|
@@ -546,9 +553,14 @@ process_detach(kpatch_process_t *proc)
|
||||||
|
unw_destroy_addr_space(proc->ptrace.unwd);
|
||||||
|
|
||||||
|
list_for_each_entry_safe(p, ptmp, &proc->ptrace.pctxs, list) {
|
||||||
|
- kpatch_ptrace_detach(p);
|
||||||
|
+ if (kpatch_ptrace_detach(p) == -ESRCH) {
|
||||||
|
+ do {
|
||||||
|
+ pid = waitpid(p->pid, &status, __WALL);
|
||||||
|
+ } while (pid > 0 && !WIFEXITED(status));
|
||||||
|
+ }
|
||||||
|
kpatch_ptrace_ctx_destroy(p);
|
||||||
|
}
|
||||||
|
+ kpinfo("Finished ptrace detaching.");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
diff --git a/src/kpatch_ptrace.c b/src/kpatch_ptrace.c
|
||||||
|
index f91b80e..a5f61b3 100644
|
||||||
|
--- a/src/kpatch_ptrace.c
|
||||||
|
+++ b/src/kpatch_ptrace.c
|
||||||
|
@@ -1186,7 +1186,7 @@ int kpatch_ptrace_detach(struct kpatch_ptrace_ctx *pctx)
|
||||||
|
ret = ptrace(PTRACE_DETACH, pctx->pid, NULL, NULL);
|
||||||
|
if (ret < 0) {
|
||||||
|
kplogerror("can't detach from %d\n", pctx->pid);
|
||||||
|
- return -1;
|
||||||
|
+ return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
kpdebug("OK\n");
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
28
0017-.gitignore-build-artefacts.patch
Normal file
28
0017-.gitignore-build-artefacts.patch
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
From 90a310f57710abb3f5e41c431d26e77fef63ad2b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Pavel Boldin <boldin.pavel@gmail.com>
|
||||||
|
Date: Thu, 13 Sep 2018 12:00:02 +0300
|
||||||
|
Subject: [PATCH 17/89] .gitignore build artefacts
|
||||||
|
|
||||||
|
Signed-off-by: Pavel Boldin <boldin.pavel@gmail.com>
|
||||||
|
---
|
||||||
|
.gitignore | 9 +++++++++
|
||||||
|
1 file changed, 9 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/.gitignore b/.gitignore
|
||||||
|
index 5761abc..065f093 100644
|
||||||
|
--- a/.gitignore
|
||||||
|
+++ b/.gitignore
|
||||||
|
@@ -1 +1,10 @@
|
||||||
|
*.o
|
||||||
|
+*.d
|
||||||
|
+src/kpatch_gensrc
|
||||||
|
+src/kpatch_make
|
||||||
|
+src/kpatch_strip
|
||||||
|
+src/libcare-cc
|
||||||
|
+src/libcare-client
|
||||||
|
+src/libcare-ctl
|
||||||
|
+src/libcare-stresstest
|
||||||
|
+tags
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
From 3954dd43124e87c788352ccc528cc79e8fca6f6d Mon Sep 17 00:00:00 2001
|
||||||
|
From: YiFan <loyfan@users.noreply.github.com>
|
||||||
|
Date: Tue, 13 Aug 2019 11:02:36 +0800
|
||||||
|
Subject: [PATCH 18/89] kpatch_storage: put an end to description string loaded
|
||||||
|
|
||||||
|
Description string should be ended up with a '\0'.
|
||||||
|
---
|
||||||
|
src/kpatch_storage.c | 4 +++-
|
||||||
|
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/kpatch_storage.c b/src/kpatch_storage.c
|
||||||
|
index a466460..2375559 100644
|
||||||
|
--- a/src/kpatch_storage.c
|
||||||
|
+++ b/src/kpatch_storage.c
|
||||||
|
@@ -377,8 +377,10 @@ char *storage_get_description(kpatch_storage_t *storage,
|
||||||
|
if (rv == -1)
|
||||||
|
goto err_free;
|
||||||
|
|
||||||
|
- if (rv == 0)
|
||||||
|
+ if (rv == 0) {
|
||||||
|
+ desc[sz] = '\0';
|
||||||
|
break;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
sz += rv;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
51
0019-Fix-README-files.patch
Normal file
51
0019-Fix-README-files.patch
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
From 43e10a5ef1db3c56a872e3a61edaf224b51822f0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Pavel Artsishevsky <polter.rnd@gmail.com>
|
||||||
|
Date: Tue, 18 Feb 2020 15:21:26 +0300
|
||||||
|
Subject: [PATCH 19/89] Fix README files
|
||||||
|
|
||||||
|
- Update patch build instructions for GHOST sample;
|
||||||
|
- Add Travis CI status image to main readme file.
|
||||||
|
---
|
||||||
|
README.rst | 3 +++
|
||||||
|
samples/ghost/README.rst | 11 +++++++++++
|
||||||
|
2 files changed, 14 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/README.rst b/README.rst
|
||||||
|
index 927325d..932b7c5 100644
|
||||||
|
--- a/README.rst
|
||||||
|
+++ b/README.rst
|
||||||
|
@@ -1,6 +1,9 @@
|
||||||
|
LibCare -- Patch Userspace Code on Live Processes
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
+.. image:: https://travis-ci.org/cloudlinux/libcare.svg?branch=master
|
||||||
|
+ :target: https://travis-ci.org/cloudlinux/libcare
|
||||||
|
+
|
||||||
|
Welcome to LibCare --- Live Patch Updates for Userspace Processes and Libraries.
|
||||||
|
|
||||||
|
LibCare delivers live patches to any of your Linux executables or libraries at
|
||||||
|
diff --git a/samples/ghost/README.rst b/samples/ghost/README.rst
|
||||||
|
index da97926..e274b54 100644
|
||||||
|
--- a/samples/ghost/README.rst
|
||||||
|
+++ b/samples/ghost/README.rst
|
||||||
|
@@ -32,6 +32,17 @@ Now, from inside the container let's install vulnerable version of glibc:
|
||||||
|
glibc-headers-2.17-55.el7 glibc-common-2.17-55.el7
|
||||||
|
...
|
||||||
|
|
||||||
|
+Also we have to downgrade elfutils since newer versions of ``eu-unstrip``
|
||||||
|
+fail to work with glibc utilities:
|
||||||
|
+
|
||||||
|
+.. code:: console
|
||||||
|
+
|
||||||
|
+ [root@... /]# yum downgrade -y --enablerepo=C7.0.1406-base \
|
||||||
|
+ elfutils-devel-0.158-3.el7.x86_64 elfutils-0.158-3.el7.x86_64 \
|
||||||
|
+ elfutils-libs-0.158-3.el7.x86_64 elfutils-libelf-0.158-3.el7.x86_64 \
|
||||||
|
+ elfutils-libelf-devel-0.158-3.el7.x86_64
|
||||||
|
+ ...
|
||||||
|
+
|
||||||
|
Build the ``libcare`` tools:
|
||||||
|
|
||||||
|
.. code:: console
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
129
0020-include-Create-include-directory-for-header-files.patch
Normal file
129
0020-include-Create-include-directory-for-header-files.patch
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
From ca5872b354b7987ce2dfd6f5268771268ad006d0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Date: Sat, 10 Oct 2020 16:46:38 +0800
|
||||||
|
Subject: [PATCH 20/89] include: Create include directory for header files
|
||||||
|
|
||||||
|
Move all header files from src directory into newly created include directory
|
||||||
|
|
||||||
|
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||||
|
---
|
||||||
|
src/{ => include}/kpatch_common.h | 0
|
||||||
|
src/{ => include}/kpatch_coro.h | 0
|
||||||
|
src/{ => include}/kpatch_dbgfilter.h | 0
|
||||||
|
src/{ => include}/kpatch_elf.h | 0
|
||||||
|
src/{ => include}/kpatch_elf_objinfo.h | 0
|
||||||
|
src/{ => include}/kpatch_file.h | 0
|
||||||
|
src/{ => include}/kpatch_flags.h | 0
|
||||||
|
src/{ => include}/kpatch_io.h | 0
|
||||||
|
src/{ => include}/kpatch_log.h | 0
|
||||||
|
src/{ => include}/kpatch_parse.h | 0
|
||||||
|
src/{ => include}/kpatch_patch.h | 0
|
||||||
|
src/{ => include}/kpatch_process.h | 0
|
||||||
|
src/{ => include}/kpatch_ptrace.h | 0
|
||||||
|
src/{ => include}/kpatch_storage.h | 0
|
||||||
|
src/{ => include}/kpatch_str.h | 0
|
||||||
|
src/{ => include}/kpatch_user.h | 0
|
||||||
|
src/{ => include}/list.h | 0
|
||||||
|
src/{ => include}/rbtree.h | 0
|
||||||
|
src/{ => include}/util.h | 0
|
||||||
|
19 files changed, 0 insertions(+), 0 deletions(-)
|
||||||
|
rename src/{ => include}/kpatch_common.h (100%)
|
||||||
|
rename src/{ => include}/kpatch_coro.h (100%)
|
||||||
|
rename src/{ => include}/kpatch_dbgfilter.h (100%)
|
||||||
|
rename src/{ => include}/kpatch_elf.h (100%)
|
||||||
|
rename src/{ => include}/kpatch_elf_objinfo.h (100%)
|
||||||
|
rename src/{ => include}/kpatch_file.h (100%)
|
||||||
|
rename src/{ => include}/kpatch_flags.h (100%)
|
||||||
|
rename src/{ => include}/kpatch_io.h (100%)
|
||||||
|
rename src/{ => include}/kpatch_log.h (100%)
|
||||||
|
rename src/{ => include}/kpatch_parse.h (100%)
|
||||||
|
rename src/{ => include}/kpatch_patch.h (100%)
|
||||||
|
rename src/{ => include}/kpatch_process.h (100%)
|
||||||
|
rename src/{ => include}/kpatch_ptrace.h (100%)
|
||||||
|
rename src/{ => include}/kpatch_storage.h (100%)
|
||||||
|
rename src/{ => include}/kpatch_str.h (100%)
|
||||||
|
rename src/{ => include}/kpatch_user.h (100%)
|
||||||
|
rename src/{ => include}/list.h (100%)
|
||||||
|
rename src/{ => include}/rbtree.h (100%)
|
||||||
|
rename src/{ => include}/util.h (100%)
|
||||||
|
|
||||||
|
diff --git a/src/kpatch_common.h b/src/include/kpatch_common.h
|
||||||
|
similarity index 100%
|
||||||
|
rename from src/kpatch_common.h
|
||||||
|
rename to src/include/kpatch_common.h
|
||||||
|
diff --git a/src/kpatch_coro.h b/src/include/kpatch_coro.h
|
||||||
|
similarity index 100%
|
||||||
|
rename from src/kpatch_coro.h
|
||||||
|
rename to src/include/kpatch_coro.h
|
||||||
|
diff --git a/src/kpatch_dbgfilter.h b/src/include/kpatch_dbgfilter.h
|
||||||
|
similarity index 100%
|
||||||
|
rename from src/kpatch_dbgfilter.h
|
||||||
|
rename to src/include/kpatch_dbgfilter.h
|
||||||
|
diff --git a/src/kpatch_elf.h b/src/include/kpatch_elf.h
|
||||||
|
similarity index 100%
|
||||||
|
rename from src/kpatch_elf.h
|
||||||
|
rename to src/include/kpatch_elf.h
|
||||||
|
diff --git a/src/kpatch_elf_objinfo.h b/src/include/kpatch_elf_objinfo.h
|
||||||
|
similarity index 100%
|
||||||
|
rename from src/kpatch_elf_objinfo.h
|
||||||
|
rename to src/include/kpatch_elf_objinfo.h
|
||||||
|
diff --git a/src/kpatch_file.h b/src/include/kpatch_file.h
|
||||||
|
similarity index 100%
|
||||||
|
rename from src/kpatch_file.h
|
||||||
|
rename to src/include/kpatch_file.h
|
||||||
|
diff --git a/src/kpatch_flags.h b/src/include/kpatch_flags.h
|
||||||
|
similarity index 100%
|
||||||
|
rename from src/kpatch_flags.h
|
||||||
|
rename to src/include/kpatch_flags.h
|
||||||
|
diff --git a/src/kpatch_io.h b/src/include/kpatch_io.h
|
||||||
|
similarity index 100%
|
||||||
|
rename from src/kpatch_io.h
|
||||||
|
rename to src/include/kpatch_io.h
|
||||||
|
diff --git a/src/kpatch_log.h b/src/include/kpatch_log.h
|
||||||
|
similarity index 100%
|
||||||
|
rename from src/kpatch_log.h
|
||||||
|
rename to src/include/kpatch_log.h
|
||||||
|
diff --git a/src/kpatch_parse.h b/src/include/kpatch_parse.h
|
||||||
|
similarity index 100%
|
||||||
|
rename from src/kpatch_parse.h
|
||||||
|
rename to src/include/kpatch_parse.h
|
||||||
|
diff --git a/src/kpatch_patch.h b/src/include/kpatch_patch.h
|
||||||
|
similarity index 100%
|
||||||
|
rename from src/kpatch_patch.h
|
||||||
|
rename to src/include/kpatch_patch.h
|
||||||
|
diff --git a/src/kpatch_process.h b/src/include/kpatch_process.h
|
||||||
|
similarity index 100%
|
||||||
|
rename from src/kpatch_process.h
|
||||||
|
rename to src/include/kpatch_process.h
|
||||||
|
diff --git a/src/kpatch_ptrace.h b/src/include/kpatch_ptrace.h
|
||||||
|
similarity index 100%
|
||||||
|
rename from src/kpatch_ptrace.h
|
||||||
|
rename to src/include/kpatch_ptrace.h
|
||||||
|
diff --git a/src/kpatch_storage.h b/src/include/kpatch_storage.h
|
||||||
|
similarity index 100%
|
||||||
|
rename from src/kpatch_storage.h
|
||||||
|
rename to src/include/kpatch_storage.h
|
||||||
|
diff --git a/src/kpatch_str.h b/src/include/kpatch_str.h
|
||||||
|
similarity index 100%
|
||||||
|
rename from src/kpatch_str.h
|
||||||
|
rename to src/include/kpatch_str.h
|
||||||
|
diff --git a/src/kpatch_user.h b/src/include/kpatch_user.h
|
||||||
|
similarity index 100%
|
||||||
|
rename from src/kpatch_user.h
|
||||||
|
rename to src/include/kpatch_user.h
|
||||||
|
diff --git a/src/list.h b/src/include/list.h
|
||||||
|
similarity index 100%
|
||||||
|
rename from src/list.h
|
||||||
|
rename to src/include/list.h
|
||||||
|
diff --git a/src/rbtree.h b/src/include/rbtree.h
|
||||||
|
similarity index 100%
|
||||||
|
rename from src/rbtree.h
|
||||||
|
rename to src/include/rbtree.h
|
||||||
|
diff --git a/src/util.h b/src/include/util.h
|
||||||
|
similarity index 100%
|
||||||
|
rename from src/util.h
|
||||||
|
rename to src/include/util.h
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
373
0021-src-Update-header-file-position.patch
Normal file
373
0021-src-Update-header-file-position.patch
Normal file
@ -0,0 +1,373 @@
|
|||||||
|
From 64f163e9bd26b0af65f12e7cc4205da0d787e7fc Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Date: Sat, 10 Oct 2020 16:50:15 +0800
|
||||||
|
Subject: [PATCH 21/89] src: Update header file position
|
||||||
|
|
||||||
|
Update header file positon with include prefix to source file in src directory.
|
||||||
|
|
||||||
|
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||||
|
---
|
||||||
|
src/kpatch_common.c | 6 +++---
|
||||||
|
src/kpatch_coro.c | 12 ++++++------
|
||||||
|
src/kpatch_dbgfilter.c | 6 +++---
|
||||||
|
src/kpatch_elf.c | 14 +++++++-------
|
||||||
|
src/kpatch_elf_objinfo.c | 6 +++---
|
||||||
|
src/kpatch_gensrc.c | 8 ++++----
|
||||||
|
src/kpatch_io.c | 6 +++---
|
||||||
|
src/kpatch_log.c | 2 +-
|
||||||
|
src/kpatch_make.c | 2 +-
|
||||||
|
src/kpatch_parse.c | 6 +++---
|
||||||
|
src/kpatch_patch.c | 20 ++++++++++----------
|
||||||
|
src/kpatch_process.c | 14 +++++++-------
|
||||||
|
src/kpatch_ptrace.c | 8 ++++----
|
||||||
|
src/kpatch_storage.c | 14 +++++++-------
|
||||||
|
src/kpatch_strip.c | 8 ++++----
|
||||||
|
src/kpatch_user.c | 18 +++++++++---------
|
||||||
|
src/rbtree.c | 2 +-
|
||||||
|
17 files changed, 76 insertions(+), 76 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/kpatch_common.c b/src/kpatch_common.c
|
||||||
|
index 99bc0b3..95d4a54 100644
|
||||||
|
--- a/src/kpatch_common.c
|
||||||
|
+++ b/src/kpatch_common.c
|
||||||
|
@@ -6,9 +6,9 @@
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
-#include "kpatch_file.h"
|
||||||
|
-#include "kpatch_common.h"
|
||||||
|
-#include "kpatch_log.h"
|
||||||
|
+#include "include/kpatch_file.h"
|
||||||
|
+#include "include/kpatch_common.h"
|
||||||
|
+#include "include/kpatch_log.h"
|
||||||
|
|
||||||
|
int kpatch_openat_file(int atfd, const char *fname, struct kp_file *kpatch)
|
||||||
|
{
|
||||||
|
diff --git a/src/kpatch_coro.c b/src/kpatch_coro.c
|
||||||
|
index 45d4a0b..02d421b 100644
|
||||||
|
--- a/src/kpatch_coro.c
|
||||||
|
+++ b/src/kpatch_coro.c
|
||||||
|
@@ -8,12 +8,12 @@
|
||||||
|
|
||||||
|
#include <asm/prctl.h>
|
||||||
|
|
||||||
|
-#include "kpatch_user.h"
|
||||||
|
-#include "kpatch_coro.h"
|
||||||
|
-#include "kpatch_common.h"
|
||||||
|
-#include "kpatch_elf.h"
|
||||||
|
-#include "kpatch_ptrace.h"
|
||||||
|
-#include "kpatch_log.h"
|
||||||
|
+#include "include/kpatch_user.h"
|
||||||
|
+#include "include/kpatch_coro.h"
|
||||||
|
+#include "include/kpatch_common.h"
|
||||||
|
+#include "include/kpatch_elf.h"
|
||||||
|
+#include "include/kpatch_ptrace.h"
|
||||||
|
+#include "include/kpatch_log.h"
|
||||||
|
|
||||||
|
/* Indicates that the next CORO flavours should be tried */
|
||||||
|
#define CORO_SEARCH_NEXT (1<<31)
|
||||||
|
diff --git a/src/kpatch_dbgfilter.c b/src/kpatch_dbgfilter.c
|
||||||
|
index 73a9bc3..d385c18 100644
|
||||||
|
--- a/src/kpatch_dbgfilter.c
|
||||||
|
+++ b/src/kpatch_dbgfilter.c
|
||||||
|
@@ -1,9 +1,9 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
-#include "kpatch_parse.h"
|
||||||
|
-#include "kpatch_str.h"
|
||||||
|
-#include "kpatch_dbgfilter.h"
|
||||||
|
+#include "include/kpatch_parse.h"
|
||||||
|
+#include "include/kpatch_str.h"
|
||||||
|
+#include "include/kpatch_dbgfilter.h"
|
||||||
|
|
||||||
|
static int is_cold_hot(char *s)
|
||||||
|
{
|
||||||
|
diff --git a/src/kpatch_elf.c b/src/kpatch_elf.c
|
||||||
|
index e42642b..b1dfed0 100644
|
||||||
|
--- a/src/kpatch_elf.c
|
||||||
|
+++ b/src/kpatch_elf.c
|
||||||
|
@@ -7,13 +7,13 @@
|
||||||
|
|
||||||
|
#include <gelf.h>
|
||||||
|
|
||||||
|
-#include "kpatch_common.h"
|
||||||
|
-#include "kpatch_user.h"
|
||||||
|
-#include "kpatch_process.h"
|
||||||
|
-#include "kpatch_elf.h"
|
||||||
|
-#include "kpatch_file.h"
|
||||||
|
-#include "kpatch_ptrace.h"
|
||||||
|
-#include "kpatch_log.h"
|
||||||
|
+#include "include/kpatch_common.h"
|
||||||
|
+#include "include/kpatch_user.h"
|
||||||
|
+#include "include/kpatch_process.h"
|
||||||
|
+#include "include/kpatch_elf.h"
|
||||||
|
+#include "include/kpatch_file.h"
|
||||||
|
+#include "include/kpatch_ptrace.h"
|
||||||
|
+#include "include/kpatch_log.h"
|
||||||
|
|
||||||
|
static int
|
||||||
|
elf_object_peek_phdr(struct object_file *o)
|
||||||
|
diff --git a/src/kpatch_elf_objinfo.c b/src/kpatch_elf_objinfo.c
|
||||||
|
index 65b7144..c967c37 100644
|
||||||
|
--- a/src/kpatch_elf_objinfo.c
|
||||||
|
+++ b/src/kpatch_elf_objinfo.c
|
||||||
|
@@ -4,9 +4,9 @@
|
||||||
|
|
||||||
|
#include <gelf.h>
|
||||||
|
|
||||||
|
-#include "kpatch_common.h"
|
||||||
|
-#include "kpatch_elf_objinfo.h"
|
||||||
|
-#include "kpatch_log.h"
|
||||||
|
+#include "include/kpatch_common.h"
|
||||||
|
+#include "include/kpatch_elf_objinfo.h"
|
||||||
|
+#include "include/kpatch_log.h"
|
||||||
|
|
||||||
|
const char *kpatch_objinfo_strptr(kpatch_objinfo *oi, int type, size_t nameidx)
|
||||||
|
{
|
||||||
|
diff --git a/src/kpatch_gensrc.c b/src/kpatch_gensrc.c
|
||||||
|
index a15fa2c..a16b652 100644
|
||||||
|
--- a/src/kpatch_gensrc.c
|
||||||
|
+++ b/src/kpatch_gensrc.c
|
||||||
|
@@ -4,10 +4,10 @@
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
|
||||||
|
-#include "kpatch_log.h"
|
||||||
|
-#include "kpatch_parse.h"
|
||||||
|
-#include "kpatch_dbgfilter.h"
|
||||||
|
-#include "kpatch_flags.h"
|
||||||
|
+#include "include/kpatch_log.h"
|
||||||
|
+#include "include/kpatch_parse.h"
|
||||||
|
+#include "include/kpatch_dbgfilter.h"
|
||||||
|
+#include "include/kpatch_flags.h"
|
||||||
|
|
||||||
|
#define OS_RHEL5 1
|
||||||
|
#define OS_RHEL6 2
|
||||||
|
diff --git a/src/kpatch_io.c b/src/kpatch_io.c
|
||||||
|
index 663bed0..7bdc298 100644
|
||||||
|
--- a/src/kpatch_io.c
|
||||||
|
+++ b/src/kpatch_io.c
|
||||||
|
@@ -4,9 +4,9 @@
|
||||||
|
#include <errno.h>
|
||||||
|
#include <libgen.h>
|
||||||
|
|
||||||
|
-#include "kpatch_log.h"
|
||||||
|
-#include "kpatch_io.h"
|
||||||
|
-#include "kpatch_str.h"
|
||||||
|
+#include "include/kpatch_log.h"
|
||||||
|
+#include "include/kpatch_io.h"
|
||||||
|
+#include "include/kpatch_str.h"
|
||||||
|
|
||||||
|
void *kp_realloc(void *p, int oldsz, int newsz)
|
||||||
|
{
|
||||||
|
diff --git a/src/kpatch_log.c b/src/kpatch_log.c
|
||||||
|
index de80f7b..6e48de4 100644
|
||||||
|
--- a/src/kpatch_log.c
|
||||||
|
+++ b/src/kpatch_log.c
|
||||||
|
@@ -4,7 +4,7 @@
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
-#include "kpatch_log.h"
|
||||||
|
+#include "include/kpatch_log.h"
|
||||||
|
|
||||||
|
int log_level = LOG_INFO;
|
||||||
|
int log_indent;
|
||||||
|
diff --git a/src/kpatch_make.c b/src/kpatch_make.c
|
||||||
|
index c584b06..6a173e6 100644
|
||||||
|
--- a/src/kpatch_make.c
|
||||||
|
+++ b/src/kpatch_make.c
|
||||||
|
@@ -9,7 +9,7 @@
|
||||||
|
#include <errno.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
-#include "kpatch_file.h"
|
||||||
|
+#include "include/kpatch_file.h"
|
||||||
|
|
||||||
|
#define ALIGN(x, align) ((x + align - 1) & (~(align - 1)))
|
||||||
|
|
||||||
|
diff --git a/src/kpatch_parse.c b/src/kpatch_parse.c
|
||||||
|
index 358916b..dfb3109 100644
|
||||||
|
--- a/src/kpatch_parse.c
|
||||||
|
+++ b/src/kpatch_parse.c
|
||||||
|
@@ -1,8 +1,8 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
-#include "kpatch_log.h"
|
||||||
|
-#include "kpatch_parse.h"
|
||||||
|
-#include "kpatch_flags.h"
|
||||||
|
+#include "include/kpatch_log.h"
|
||||||
|
+#include "include/kpatch_parse.h"
|
||||||
|
+#include "include/kpatch_flags.h"
|
||||||
|
|
||||||
|
char *cline(struct kp_file *f, int l)
|
||||||
|
{
|
||||||
|
diff --git a/src/kpatch_patch.c b/src/kpatch_patch.c
|
||||||
|
index e32c702..21a160a 100644
|
||||||
|
--- a/src/kpatch_patch.c
|
||||||
|
+++ b/src/kpatch_patch.c
|
||||||
|
@@ -10,16 +10,16 @@
|
||||||
|
#include <libunwind.h>
|
||||||
|
#include <libunwind-ptrace.h>
|
||||||
|
|
||||||
|
-#include "kpatch_patch.h"
|
||||||
|
-#include "kpatch_user.h"
|
||||||
|
-#include "kpatch_storage.h"
|
||||||
|
-#include "kpatch_process.h"
|
||||||
|
-#include "kpatch_file.h"
|
||||||
|
-#include "kpatch_common.h"
|
||||||
|
-#include "kpatch_elf.h"
|
||||||
|
-#include "kpatch_ptrace.h"
|
||||||
|
-#include "list.h"
|
||||||
|
-#include "kpatch_log.h"
|
||||||
|
+#include "include/kpatch_patch.h"
|
||||||
|
+#include "include/kpatch_user.h"
|
||||||
|
+#include "include/kpatch_storage.h"
|
||||||
|
+#include "include/kpatch_process.h"
|
||||||
|
+#include "include/kpatch_file.h"
|
||||||
|
+#include "include/kpatch_common.h"
|
||||||
|
+#include "include/kpatch_elf.h"
|
||||||
|
+#include "include/kpatch_ptrace.h"
|
||||||
|
+#include "include/list.h"
|
||||||
|
+#include "include/kpatch_log.h"
|
||||||
|
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
diff --git a/src/kpatch_process.c b/src/kpatch_process.c
|
||||||
|
index 5c0374a..3f7f2f6 100644
|
||||||
|
--- a/src/kpatch_process.c
|
||||||
|
+++ b/src/kpatch_process.c
|
||||||
|
@@ -23,13 +23,13 @@
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
-#include "kpatch_process.h"
|
||||||
|
-#include "kpatch_file.h"
|
||||||
|
-#include "kpatch_common.h"
|
||||||
|
-#include "kpatch_elf.h"
|
||||||
|
-#include "kpatch_ptrace.h"
|
||||||
|
-#include "list.h"
|
||||||
|
-#include "kpatch_log.h"
|
||||||
|
+#include "include/kpatch_process.h"
|
||||||
|
+#include "include/kpatch_file.h"
|
||||||
|
+#include "include/kpatch_common.h"
|
||||||
|
+#include "include/kpatch_elf.h"
|
||||||
|
+#include "include/kpatch_ptrace.h"
|
||||||
|
+#include "include/list.h"
|
||||||
|
+#include "include/kpatch_log.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Locks process by opening /proc/<pid>/maps
|
||||||
|
diff --git a/src/kpatch_ptrace.c b/src/kpatch_ptrace.c
|
||||||
|
index a5f61b3..8910aa8 100644
|
||||||
|
--- a/src/kpatch_ptrace.c
|
||||||
|
+++ b/src/kpatch_ptrace.c
|
||||||
|
@@ -15,10 +15,10 @@
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
-#include "kpatch_process.h"
|
||||||
|
-#include "kpatch_common.h"
|
||||||
|
-#include "kpatch_ptrace.h"
|
||||||
|
-#include "kpatch_log.h"
|
||||||
|
+#include "include/kpatch_process.h"
|
||||||
|
+#include "include/kpatch_common.h"
|
||||||
|
+#include "include/kpatch_ptrace.h"
|
||||||
|
+#include "include/kpatch_log.h"
|
||||||
|
|
||||||
|
#include <gelf.h>
|
||||||
|
|
||||||
|
diff --git a/src/kpatch_storage.c b/src/kpatch_storage.c
|
||||||
|
index 2375559..9165cbf 100644
|
||||||
|
--- a/src/kpatch_storage.c
|
||||||
|
+++ b/src/kpatch_storage.c
|
||||||
|
@@ -10,13 +10,13 @@
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <gelf.h>
|
||||||
|
|
||||||
|
-#include "kpatch_storage.h"
|
||||||
|
-#include "kpatch_file.h"
|
||||||
|
-#include "kpatch_common.h"
|
||||||
|
-#include "kpatch_elf.h"
|
||||||
|
-#include "kpatch_ptrace.h"
|
||||||
|
-#include "list.h"
|
||||||
|
-#include "kpatch_log.h"
|
||||||
|
+#include "include/kpatch_storage.h"
|
||||||
|
+#include "include/kpatch_file.h"
|
||||||
|
+#include "include/kpatch_common.h"
|
||||||
|
+#include "include/kpatch_elf.h"
|
||||||
|
+#include "include/kpatch_ptrace.h"
|
||||||
|
+#include "include/list.h"
|
||||||
|
+#include "include/kpatch_log.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
diff --git a/src/kpatch_strip.c b/src/kpatch_strip.c
|
||||||
|
index b4de32d..6ad56a3 100644
|
||||||
|
--- a/src/kpatch_strip.c
|
||||||
|
+++ b/src/kpatch_strip.c
|
||||||
|
@@ -7,13 +7,13 @@
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
-#include "kpatch_file.h"
|
||||||
|
-#include "kpatch_common.h"
|
||||||
|
+#include "include/kpatch_file.h"
|
||||||
|
+#include "include/kpatch_common.h"
|
||||||
|
|
||||||
|
#include <gelf.h>
|
||||||
|
-#include "kpatch_elf_objinfo.h"
|
||||||
|
+#include "include/kpatch_elf_objinfo.h"
|
||||||
|
|
||||||
|
-#include "kpatch_log.h"
|
||||||
|
+#include "include/kpatch_log.h"
|
||||||
|
|
||||||
|
#define ALIGN(off,sz) (((off)+(sz)-1)&~((sz)-1))
|
||||||
|
|
||||||
|
diff --git a/src/kpatch_user.c b/src/kpatch_user.c
|
||||||
|
index e6649b0..11e3408 100644
|
||||||
|
--- a/src/kpatch_user.c
|
||||||
|
+++ b/src/kpatch_user.c
|
||||||
|
@@ -16,15 +16,15 @@
|
||||||
|
#include <libunwind.h>
|
||||||
|
#include <libunwind-ptrace.h>
|
||||||
|
|
||||||
|
-#include "kpatch_user.h"
|
||||||
|
-#include "kpatch_storage.h"
|
||||||
|
-#include "kpatch_patch.h"
|
||||||
|
-#include "kpatch_process.h"
|
||||||
|
-#include "kpatch_file.h"
|
||||||
|
-#include "kpatch_common.h"
|
||||||
|
-#include "kpatch_elf.h"
|
||||||
|
-#include "list.h"
|
||||||
|
-#include "kpatch_log.h"
|
||||||
|
+#include "include/kpatch_user.h"
|
||||||
|
+#include "include/kpatch_storage.h"
|
||||||
|
+#include "include/kpatch_patch.h"
|
||||||
|
+#include "include/kpatch_process.h"
|
||||||
|
+#include "include/kpatch_file.h"
|
||||||
|
+#include "include/kpatch_common.h"
|
||||||
|
+#include "include/kpatch_elf.h"
|
||||||
|
+#include "include/list.h"
|
||||||
|
+#include "include/kpatch_log.h"
|
||||||
|
|
||||||
|
/* Global variables */
|
||||||
|
static char storage_dir[PATH_MAX] = "/var/lib/libcare";
|
||||||
|
diff --git a/src/rbtree.c b/src/rbtree.c
|
||||||
|
index fee5844..6aff1d1 100644
|
||||||
|
--- a/src/rbtree.c
|
||||||
|
+++ b/src/rbtree.c
|
||||||
|
@@ -21,7 +21,7 @@
|
||||||
|
linux/lib/rbtree.c
|
||||||
|
*/
|
||||||
|
|
||||||
|
-#include "rbtree.h"
|
||||||
|
+#include "include/rbtree.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* red-black trees properties: http://en.wikipedia.org/wiki/Rbtree
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
73
0022-arch-Create-arch-directory-to-support-multi-arch.patch
Normal file
73
0022-arch-Create-arch-directory-to-support-multi-arch.patch
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
From b0d5f7f4e15bd19e7dc055b3f24171a3b14aa445 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Date: Sat, 10 Oct 2020 16:59:16 +0800
|
||||||
|
Subject: [PATCH 22/89] arch: Create arch directory to support multi-arch
|
||||||
|
|
||||||
|
Create directory arch/aarch64 and arch/x86 hold arch-related source files.
|
||||||
|
Create arch-related source files in libcare.
|
||||||
|
Files list below are architecture dependent:
|
||||||
|
arch_coro.c
|
||||||
|
arch_elf.c
|
||||||
|
arch_parse.c
|
||||||
|
arch_patch.c
|
||||||
|
arch_ptrace.c
|
||||||
|
arch_process.c
|
||||||
|
|
||||||
|
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||||
|
---
|
||||||
|
src/arch/aarch64/arch_coro.c | 0
|
||||||
|
src/arch/aarch64/arch_elf.c | 0
|
||||||
|
src/arch/aarch64/arch_parse.c | 0
|
||||||
|
src/arch/aarch64/arch_patch.c | 0
|
||||||
|
src/arch/aarch64/arch_ptrace.c | 0
|
||||||
|
src/arch/x86/arch_coro.c | 0
|
||||||
|
src/arch/x86/arch_elf.c | 0
|
||||||
|
src/arch/x86/arch_parse.c | 0
|
||||||
|
src/arch/x86/arch_patch.c | 0
|
||||||
|
src/arch/x86/arch_ptrace.c | 0
|
||||||
|
10 files changed, 0 insertions(+), 0 deletions(-)
|
||||||
|
create mode 100644 src/arch/aarch64/arch_coro.c
|
||||||
|
create mode 100644 src/arch/aarch64/arch_elf.c
|
||||||
|
create mode 100644 src/arch/aarch64/arch_parse.c
|
||||||
|
create mode 100644 src/arch/aarch64/arch_patch.c
|
||||||
|
create mode 100644 src/arch/aarch64/arch_ptrace.c
|
||||||
|
create mode 100644 src/arch/x86/arch_coro.c
|
||||||
|
create mode 100644 src/arch/x86/arch_elf.c
|
||||||
|
create mode 100644 src/arch/x86/arch_parse.c
|
||||||
|
create mode 100644 src/arch/x86/arch_patch.c
|
||||||
|
create mode 100644 src/arch/x86/arch_ptrace.c
|
||||||
|
|
||||||
|
diff --git a/src/arch/aarch64/arch_coro.c b/src/arch/aarch64/arch_coro.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..e69de29
|
||||||
|
diff --git a/src/arch/aarch64/arch_elf.c b/src/arch/aarch64/arch_elf.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..e69de29
|
||||||
|
diff --git a/src/arch/aarch64/arch_parse.c b/src/arch/aarch64/arch_parse.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..e69de29
|
||||||
|
diff --git a/src/arch/aarch64/arch_patch.c b/src/arch/aarch64/arch_patch.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..e69de29
|
||||||
|
diff --git a/src/arch/aarch64/arch_ptrace.c b/src/arch/aarch64/arch_ptrace.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..e69de29
|
||||||
|
diff --git a/src/arch/x86/arch_coro.c b/src/arch/x86/arch_coro.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..e69de29
|
||||||
|
diff --git a/src/arch/x86/arch_elf.c b/src/arch/x86/arch_elf.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..e69de29
|
||||||
|
diff --git a/src/arch/x86/arch_parse.c b/src/arch/x86/arch_parse.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..e69de29
|
||||||
|
diff --git a/src/arch/x86/arch_patch.c b/src/arch/x86/arch_patch.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..e69de29
|
||||||
|
diff --git a/src/arch/x86/arch_ptrace.c b/src/arch/x86/arch_ptrace.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..e69de29
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
26
0023-config-configure-out-the-running-arch.patch
Normal file
26
0023-config-configure-out-the-running-arch.patch
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
From d9b5d88e94b8be0100b0fc2ee0054c78fb0737be Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Date: Tue, 13 Oct 2020 09:36:24 +0800
|
||||||
|
Subject: [PATCH 23/89] config: configure out the running arch
|
||||||
|
|
||||||
|
To support multi-arch, we need to figure out which architecture we stands on.
|
||||||
|
So let's get arch type before running the compilation process.
|
||||||
|
|
||||||
|
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||||
|
---
|
||||||
|
src/config | 2 ++
|
||||||
|
1 file changed, 2 insertions(+)
|
||||||
|
create mode 100755 src/config
|
||||||
|
|
||||||
|
diff --git a/src/config b/src/config
|
||||||
|
new file mode 100755
|
||||||
|
index 0000000..6c44cf2
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/config
|
||||||
|
@@ -0,0 +1,2 @@
|
||||||
|
+#!/bin/bash
|
||||||
|
+uname -m > arch.desc
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
@ -0,0 +1,72 @@
|
|||||||
|
From d12c8e57c24649e6c8c74e6dc72f02f54e82aea7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Date: Tue, 13 Oct 2020 14:55:53 +0800
|
||||||
|
Subject: [PATCH 24/89] Makefile: Adapt Makefile for different architectures
|
||||||
|
|
||||||
|
First take the arch information from config file. Then compile the
|
||||||
|
right file accroding to the architecture and find right header file
|
||||||
|
postion from src/include.
|
||||||
|
|
||||||
|
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||||
|
---
|
||||||
|
src/Makefile | 21 +++++++++++++++------
|
||||||
|
1 file changed, 15 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/Makefile b/src/Makefile
|
||||||
|
index 58e942a..9108a02 100644
|
||||||
|
--- a/src/Makefile
|
||||||
|
+++ b/src/Makefile
|
||||||
|
@@ -7,8 +7,10 @@ TARGETS = kpatch_gensrc \
|
||||||
|
libcare-stresstest
|
||||||
|
DEBUG = yes # comment out this line if not debug
|
||||||
|
|
||||||
|
+SRC_PATH := $(shell pwd)
|
||||||
|
+
|
||||||
|
CC = gcc
|
||||||
|
-CFLAGS_MISC = -Wall -g -O2 -D_GNU_SOURCE
|
||||||
|
+CFLAGS_MISC = -Wall -g -O2 -D_GNU_SOURCE -I $(SRC_PATH)
|
||||||
|
|
||||||
|
cc-option = $(shell if $(CC) $(CFLAGS_MISC) $(1) -S -o /dev/null -xc /dev/null \
|
||||||
|
> /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;)
|
||||||
|
@@ -18,6 +20,13 @@ CFLAGS_WARN += $(call cc-option,-Wno-builtin-macro-redefined)
|
||||||
|
CFLAGS_WARN += $(call cc-option,-Wno-deprecated-declarations)
|
||||||
|
CFLAGS = $(CFLAGS_MISC) $(CFLAGS_WARN)
|
||||||
|
|
||||||
|
+ARCH := $(shell cat arch.desc)
|
||||||
|
+ifeq ($(ARCH),aarch64)
|
||||||
|
+VPATH = arch/aarch64
|
||||||
|
+else
|
||||||
|
+VPATH = arch/x86
|
||||||
|
+endif
|
||||||
|
+
|
||||||
|
ifdef DEBUG
|
||||||
|
CFLAGS += -DDEBUG -O0 -g
|
||||||
|
endif
|
||||||
|
@@ -30,18 +39,18 @@ all: $(TARGETS)
|
||||||
|
|
||||||
|
.SUFFIXES:
|
||||||
|
|
||||||
|
-kpatch_gensrc: kpatch_gensrc.o kpatch_dbgfilter.o kpatch_parse.o kpatch_io.o rbtree.o kpatch_log.o
|
||||||
|
+kpatch_gensrc: kpatch_gensrc.o kpatch_dbgfilter.o kpatch_parse.o kpatch_io.o rbtree.o kpatch_log.o arch_parse.o
|
||||||
|
kpatch_make: kpatch_make.o
|
||||||
|
|
||||||
|
LIBUNWIND_LIBS := $(shell pkg-config --libs libunwind libunwind-ptrace)
|
||||||
|
|
||||||
|
|
||||||
|
-libcare-ctl: kpatch_user.o kpatch_storage.o kpatch_patch.c kpatch_elf.o kpatch_ptrace.o kpatch_coro.o
|
||||||
|
-libcare-ctl: kpatch_process.o kpatch_common.o rbtree.o kpatch_log.o
|
||||||
|
+libcare-ctl: kpatch_user.o kpatch_storage.o kpatch_patch.o kpatch_elf.o kpatch_ptrace.o kpatch_coro.o arch_patch.o arch_elf.o arch_ptrace.o arch_coro.o
|
||||||
|
+libcare-ctl: kpatch_process.o kpatch_common.o rbtree.o kpatch_log.o arch_process.o
|
||||||
|
libcare-ctl: LDLIBS += -lelf -lrt $(LIBUNWIND_LIBS)
|
||||||
|
|
||||||
|
-libcare-stresstest: kpatch_user-stresstest.o kpatch_storage.o kpatch_patch.c kpatch_elf.o kpatch_ptrace.o kpatch_coro.o
|
||||||
|
-libcare-stresstest: kpatch_process.o kpatch_common.o rbtree.o kpatch_log.o
|
||||||
|
+libcare-stresstest: kpatch_user-stresstest.o kpatch_storage.o kpatch_patch.o kpatch_elf.o kpatch_ptrace.o kpatch_coro.o arch_patch.o arch_elf.o arch_ptrace.o arch_coro.o
|
||||||
|
+libcare-stresstest: kpatch_process.o kpatch_common.o rbtree.o kpatch_log.o arch_process.o
|
||||||
|
libcare-stresstest: LDLIBS += -lelf -lrt $(LIBUNWIND_LIBS)
|
||||||
|
|
||||||
|
libcare-client: libcare-client.o
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
31
0025-kpatch_parse-Update-asm_directives-for-aarch64.patch
Normal file
31
0025-kpatch_parse-Update-asm_directives-for-aarch64.patch
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
From 48a7b69f85710e1db33db994e79fdcd568ceacda Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Date: Mon, 12 Oct 2020 10:53:28 +0800
|
||||||
|
Subject: [PATCH 25/89] kpatch_parse: Update asm_directives for aarch64
|
||||||
|
|
||||||
|
Update asm_directives in kpatch_parse.c, because
|
||||||
|
the golbal identifier in x86 is ".globl"
|
||||||
|
which is different from the ".global"in aarch64.
|
||||||
|
|
||||||
|
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||||
|
---
|
||||||
|
src/kpatch_parse.c | 2 ++
|
||||||
|
1 file changed, 2 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/kpatch_parse.c b/src/kpatch_parse.c
|
||||||
|
index dfb3109..44e8a60 100644
|
||||||
|
--- a/src/kpatch_parse.c
|
||||||
|
+++ b/src/kpatch_parse.c
|
||||||
|
@@ -82,6 +82,8 @@ static struct {
|
||||||
|
{ DIRECTIVE_SUBSECTION, ".subsection"},
|
||||||
|
|
||||||
|
{ DIRECTIVE_GLOBL, ".globl"},
|
||||||
|
+ { DIRECTIVE_GLOBL, ".global"},
|
||||||
|
+
|
||||||
|
{ DIRECTIVE_LOCAL, ".local"},
|
||||||
|
{ DIRECTIVE_HIDDEN, ".hidden"},
|
||||||
|
{ DIRECTIVE_PROTECTED, ".protected"},
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
154
0026-kpatch_parse-Split-function-parse_ctype.patch
Normal file
154
0026-kpatch_parse-Split-function-parse_ctype.patch
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
From 13dafd93cf011d79f1f4baf2c9035faeb52f4945 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Date: Mon, 12 Oct 2020 13:31:41 +0800
|
||||||
|
Subject: [PATCH 26/89] kpatch_parse: Split function parse_ctype
|
||||||
|
|
||||||
|
The parse_ctype function is arch related, so let's make two
|
||||||
|
separate definations in arch/x86/arch_parse.c and arch/aarch64/arch_parse.c
|
||||||
|
|
||||||
|
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||||
|
---
|
||||||
|
src/arch/aarch64/arch_parse.c | 34 ++++++++++++++++++++++++++++++++++
|
||||||
|
src/arch/x86/arch_parse.c | 31 +++++++++++++++++++++++++++++++
|
||||||
|
src/include/kpatch_parse.h | 2 ++
|
||||||
|
src/kpatch_parse.c | 28 +---------------------------
|
||||||
|
4 files changed, 68 insertions(+), 27 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/arch/aarch64/arch_parse.c b/src/arch/aarch64/arch_parse.c
|
||||||
|
index e69de29..8eb88a9 100644
|
||||||
|
--- a/src/arch/aarch64/arch_parse.c
|
||||||
|
+++ b/src/arch/aarch64/arch_parse.c
|
||||||
|
@@ -0,0 +1,34 @@
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+
|
||||||
|
+#include "include/kpatch_log.h"
|
||||||
|
+#include "include/kpatch_parse.h"
|
||||||
|
+#include "include/kpatch_flags.h"
|
||||||
|
+
|
||||||
|
+int parse_ctype(char *origs, bool with_checks)
|
||||||
|
+{
|
||||||
|
+ char *s = origs;
|
||||||
|
+ int type;
|
||||||
|
+ kpstr_t t;
|
||||||
|
+
|
||||||
|
+ s = skip_blanks(s);
|
||||||
|
+ if (s[0] == '#')
|
||||||
|
+ return DIRECTIVE_COMMENT; /* Single-line comment */
|
||||||
|
+
|
||||||
|
+ if (s[0] == '/' && s[1] == '/')
|
||||||
|
+ return DIRECTIVE_COMMENT; /* Arm disassembly support c style comment */
|
||||||
|
+
|
||||||
|
+ get_token(&s, &t);
|
||||||
|
+ type = find_ctype(&t);
|
||||||
|
+
|
||||||
|
+ if (type >= 0)
|
||||||
|
+ return type;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Asm labels starting from digits are local labels, they can be even created multiple times in the same function.
|
||||||
|
+ * So there is no reason to handle them and bother with renaming at all. It would create conflicts at our brains
|
||||||
|
+ * and require special tracking and matching... Brrrr.... */
|
||||||
|
+ if (s && *s == ':')
|
||||||
|
+ return !isdigit(t.s[0]) ? DIRECTIVE_LABEL : DIRECTIVE_LOCAL_LABEL;
|
||||||
|
+
|
||||||
|
+ return DIRECTIVE_OTHER;
|
||||||
|
+}
|
||||||
|
diff --git a/src/arch/x86/arch_parse.c b/src/arch/x86/arch_parse.c
|
||||||
|
index e69de29..5a67116 100644
|
||||||
|
--- a/src/arch/x86/arch_parse.c
|
||||||
|
+++ b/src/arch/x86/arch_parse.c
|
||||||
|
@@ -0,0 +1,31 @@
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+
|
||||||
|
+#include "include/kpatch_log.h"
|
||||||
|
+#include "include/kpatch_parse.h"
|
||||||
|
+#include "include/kpatch_flags.h"
|
||||||
|
+
|
||||||
|
+int parse_ctype(char *origs, bool with_checks)
|
||||||
|
+{
|
||||||
|
+ char *s = origs;
|
||||||
|
+ int type;
|
||||||
|
+ kpstr_t t;
|
||||||
|
+
|
||||||
|
+ s = skip_blanks(s);
|
||||||
|
+ if (s[0] == '#')
|
||||||
|
+ return DIRECTIVE_COMMENT; /* Single-line comment */
|
||||||
|
+
|
||||||
|
+ get_token(&s, &t);
|
||||||
|
+ type = find_ctype(&t);
|
||||||
|
+
|
||||||
|
+ if (type >= 0)
|
||||||
|
+ return type;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Asm labels starting from digits are local labels, they can be even created multiple times in the same function.
|
||||||
|
+ * So there is no reason to handle them and bother with renaming at all. It would create conflicts at our brains
|
||||||
|
+ * and require special tracking and matching... Brrrr.... */
|
||||||
|
+ if (s && *s == ':')
|
||||||
|
+ return !isdigit(t.s[0]) ? DIRECTIVE_LABEL : DIRECTIVE_LOCAL_LABEL;
|
||||||
|
+
|
||||||
|
+ return DIRECTIVE_OTHER;
|
||||||
|
+}
|
||||||
|
diff --git a/src/include/kpatch_parse.h b/src/include/kpatch_parse.h
|
||||||
|
index 1012d5d..e1b7501 100644
|
||||||
|
--- a/src/include/kpatch_parse.h
|
||||||
|
+++ b/src/include/kpatch_parse.h
|
||||||
|
@@ -51,6 +51,8 @@ void init_ctypes(struct kp_file *f);
|
||||||
|
int ctype(struct kp_file *f, int l);
|
||||||
|
int is_sect_cmd(struct kp_file *f, int l);
|
||||||
|
|
||||||
|
+
|
||||||
|
+int find_ctype(kpstr_t *t);
|
||||||
|
int parse_ctype(char *s, bool with_checks);
|
||||||
|
|
||||||
|
/* ----------------------------------------- sections ----------------------------------------- */
|
||||||
|
diff --git a/src/kpatch_parse.c b/src/kpatch_parse.c
|
||||||
|
index 44e8a60..4bafdb7 100644
|
||||||
|
--- a/src/kpatch_parse.c
|
||||||
|
+++ b/src/kpatch_parse.c
|
||||||
|
@@ -109,7 +109,7 @@ static void get_type_args(char *s, kpstr_t *nm, kpstr_t *attr)
|
||||||
|
kpfatal("can't parse .type command");
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int find_ctype(kpstr_t *t)
|
||||||
|
+int find_ctype(kpstr_t *t)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < (int)(sizeof(asm_directives)/sizeof(asm_directives[0])); i++) {
|
||||||
|
@@ -119,32 +119,6 @@ static int find_ctype(kpstr_t *t)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
-int parse_ctype(char *origs, bool with_checks)
|
||||||
|
-{
|
||||||
|
- char *s = origs;
|
||||||
|
- int type;
|
||||||
|
- kpstr_t t;
|
||||||
|
-
|
||||||
|
- s = skip_blanks(s);
|
||||||
|
- if (s[0] == '#')
|
||||||
|
- return DIRECTIVE_COMMENT; /* Single-line comment */
|
||||||
|
-
|
||||||
|
- get_token(&s, &t);
|
||||||
|
- type = find_ctype(&t);
|
||||||
|
-
|
||||||
|
- if (type >= 0)
|
||||||
|
- return type;
|
||||||
|
-
|
||||||
|
- /*
|
||||||
|
- * Asm labels starting from digits are local labels, they can be even created multiple times in the same function.
|
||||||
|
- * So there is no reason to handle them and bother with renaming at all. It would create conflicts at our brains
|
||||||
|
- * and require special tracking and matching... Brrrr.... */
|
||||||
|
- if (s && *s == ':')
|
||||||
|
- return !isdigit(t.s[0]) ? DIRECTIVE_LABEL : DIRECTIVE_LOCAL_LABEL;
|
||||||
|
-
|
||||||
|
- return DIRECTIVE_OTHER;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
int ctype(struct kp_file *f, int l)
|
||||||
|
{
|
||||||
|
if (l >= f->nr_lines)
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
249
0027-kpatch_parse-Split-function-init_multilines.patch
Normal file
249
0027-kpatch_parse-Split-function-init_multilines.patch
Normal file
@ -0,0 +1,249 @@
|
|||||||
|
From 0e0e7195fca05f706c1701484710fea9fc8b21f5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Date: Mon, 12 Oct 2020 13:41:06 +0800
|
||||||
|
Subject: [PATCH 27/89] kpatch_parse: Split function init_multilines
|
||||||
|
|
||||||
|
The function init_multilines is arch related, so let's make
|
||||||
|
two definations in arch/x86/arch_parse.c and arch/aarch64/arch_parse.c
|
||||||
|
|
||||||
|
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||||
|
---
|
||||||
|
src/arch/aarch64/arch_parse.c | 67 +++++++++++++++++++++++++++++++++++
|
||||||
|
src/arch/x86/arch_parse.c | 65 +++++++++++++++++++++++++++++++++
|
||||||
|
src/kpatch_parse.c | 65 ---------------------------------
|
||||||
|
3 files changed, 132 insertions(+), 65 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/arch/aarch64/arch_parse.c b/src/arch/aarch64/arch_parse.c
|
||||||
|
index 8eb88a9..1233e03 100644
|
||||||
|
--- a/src/arch/aarch64/arch_parse.c
|
||||||
|
+++ b/src/arch/aarch64/arch_parse.c
|
||||||
|
@@ -4,6 +4,73 @@
|
||||||
|
#include "include/kpatch_parse.h"
|
||||||
|
#include "include/kpatch_flags.h"
|
||||||
|
|
||||||
|
+/* break manually crafted multiple statements separated by ; to separate lines */
|
||||||
|
+void init_multilines(struct kp_file *f)
|
||||||
|
+{
|
||||||
|
+ int i, nr, sz = 64, slen, first_token;
|
||||||
|
+ char **lines = NULL, *s, *se;
|
||||||
|
+ int *lines_num = NULL;
|
||||||
|
+ kpstr_t t;
|
||||||
|
+
|
||||||
|
+ nr = 0;
|
||||||
|
+ for (i = 0; i < f->nr_lines; i++) {
|
||||||
|
+ if (nr + 1000 >= sz || !lines) {
|
||||||
|
+ sz *= 2;
|
||||||
|
+ lines = kp_realloc(lines, (sz/2) * sizeof(char *), sz * sizeof(char *));
|
||||||
|
+ lines_num = kp_realloc(lines_num, (sz/2) * sizeof(int), sz * sizeof(int));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ s = f->lines[i];
|
||||||
|
+ if (strpbrk(s, ";:") != NULL) {
|
||||||
|
+ while (s && *s) {
|
||||||
|
+ se = s;
|
||||||
|
+ slen = strlen(s);
|
||||||
|
+ first_token = 1;
|
||||||
|
+ while (se) {
|
||||||
|
+ get_token(&se, &t);
|
||||||
|
+ if (t.l == 1 && t.s[0] == '#')
|
||||||
|
+ goto done;
|
||||||
|
+ if (t.l == 2 && t.s[0] == '/' && t.s[1] == '/')
|
||||||
|
+ goto done;
|
||||||
|
+ if (t.l == 1 && t.s[0] == ';') {
|
||||||
|
+ slen = t.s - s;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ /* first token with ':' after is
|
||||||
|
+ * the label, separate it unless
|
||||||
|
+ * it is done already (next non-blank
|
||||||
|
+ * is '\0')
|
||||||
|
+ */
|
||||||
|
+ if (first_token && se &&
|
||||||
|
+ se[0] == ':' &&
|
||||||
|
+ se[1] != '\0') {
|
||||||
|
+ slen = se - s + 1;
|
||||||
|
+ se++;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ first_token = 0;
|
||||||
|
+ }
|
||||||
|
+ lines[nr] = strndup(s, slen);
|
||||||
|
+ s = se;
|
||||||
|
+ lines_num[nr] = i;
|
||||||
|
+ nr++;
|
||||||
|
+ if (nr >= sz)
|
||||||
|
+ kpfatal("oops, not prepared to handle >1000 asm statements in single line");
|
||||||
|
+ }
|
||||||
|
+ free(f->lines[i]);
|
||||||
|
+ } else {
|
||||||
|
+done:
|
||||||
|
+ lines[nr] = s;
|
||||||
|
+ lines_num[nr] = i;
|
||||||
|
+ nr++;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ free(f->lines);
|
||||||
|
+ f->lines = lines;
|
||||||
|
+ f->lines_num = lines_num;
|
||||||
|
+ f->nr_lines = nr;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int parse_ctype(char *origs, bool with_checks)
|
||||||
|
{
|
||||||
|
char *s = origs;
|
||||||
|
diff --git a/src/arch/x86/arch_parse.c b/src/arch/x86/arch_parse.c
|
||||||
|
index 5a67116..92ff483 100644
|
||||||
|
--- a/src/arch/x86/arch_parse.c
|
||||||
|
+++ b/src/arch/x86/arch_parse.c
|
||||||
|
@@ -4,6 +4,71 @@
|
||||||
|
#include "include/kpatch_parse.h"
|
||||||
|
#include "include/kpatch_flags.h"
|
||||||
|
|
||||||
|
+/* break manually crafted multiple statements separated by ; to separate lines */
|
||||||
|
+void init_multilines(struct kp_file *f)
|
||||||
|
+{
|
||||||
|
+ int i, nr, sz = 64, slen, first_token;
|
||||||
|
+ char **lines = NULL, *s, *se;
|
||||||
|
+ int *lines_num = NULL;
|
||||||
|
+ kpstr_t t;
|
||||||
|
+
|
||||||
|
+ nr = 0;
|
||||||
|
+ for (i = 0; i < f->nr_lines; i++) {
|
||||||
|
+ if (nr + 1000 >= sz || !lines) {
|
||||||
|
+ sz *= 2;
|
||||||
|
+ lines = kp_realloc(lines, (sz/2) * sizeof(char *), sz * sizeof(char *));
|
||||||
|
+ lines_num = kp_realloc(lines_num, (sz/2) * sizeof(int), sz * sizeof(int));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ s = f->lines[i];
|
||||||
|
+ if (strpbrk(s, ";:") != NULL) {
|
||||||
|
+ while (s && *s) {
|
||||||
|
+ se = s;
|
||||||
|
+ slen = strlen(s);
|
||||||
|
+ first_token = 1;
|
||||||
|
+ while (se) {
|
||||||
|
+ get_token(&se, &t);
|
||||||
|
+ if (t.l == 1 && t.s[0] == '#')
|
||||||
|
+ goto done;
|
||||||
|
+ if (t.l == 1 && t.s[0] == ';') {
|
||||||
|
+ slen = t.s - s;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ /* first token with ':' after is
|
||||||
|
+ * the label, separate it unless
|
||||||
|
+ * it is done already (next non-blank
|
||||||
|
+ * is '\0')
|
||||||
|
+ */
|
||||||
|
+ if (first_token && se &&
|
||||||
|
+ se[0] == ':' &&
|
||||||
|
+ se[1] != '\0') {
|
||||||
|
+ slen = se - s + 1;
|
||||||
|
+ se++;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ first_token = 0;
|
||||||
|
+ }
|
||||||
|
+ lines[nr] = strndup(s, slen);
|
||||||
|
+ s = se;
|
||||||
|
+ lines_num[nr] = i;
|
||||||
|
+ nr++;
|
||||||
|
+ if (nr >= sz)
|
||||||
|
+ kpfatal("oops, not prepared to handle >1000 asm statements in single line");
|
||||||
|
+ }
|
||||||
|
+ free(f->lines[i]);
|
||||||
|
+ } else {
|
||||||
|
+done:
|
||||||
|
+ lines[nr] = s;
|
||||||
|
+ lines_num[nr] = i;
|
||||||
|
+ nr++;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ free(f->lines);
|
||||||
|
+ f->lines = lines;
|
||||||
|
+ f->lines_num = lines_num;
|
||||||
|
+ f->nr_lines = nr;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int parse_ctype(char *origs, bool with_checks)
|
||||||
|
{
|
||||||
|
char *s = origs;
|
||||||
|
diff --git a/src/kpatch_parse.c b/src/kpatch_parse.c
|
||||||
|
index 4bafdb7..857dbf3 100644
|
||||||
|
--- a/src/kpatch_parse.c
|
||||||
|
+++ b/src/kpatch_parse.c
|
||||||
|
@@ -136,71 +136,6 @@ int is_sect_cmd(struct kp_file *f, int l)
|
||||||
|
t == DIRECTIVE_PREVIOUS || t == DIRECTIVE_SUBSECTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
-/* break manually crafted multiple statements separated by ; to separate lines */
|
||||||
|
-void init_multilines(struct kp_file *f)
|
||||||
|
-{
|
||||||
|
- int i, nr, sz = 64, slen, first_token;
|
||||||
|
- char **lines = NULL, *s, *se;
|
||||||
|
- int *lines_num = NULL;
|
||||||
|
- kpstr_t t;
|
||||||
|
-
|
||||||
|
- nr = 0;
|
||||||
|
- for (i = 0; i < f->nr_lines; i++) {
|
||||||
|
- if (nr + 1000 >= sz || !lines) {
|
||||||
|
- sz *= 2;
|
||||||
|
- lines = kp_realloc(lines, (sz/2) * sizeof(char *), sz * sizeof(char *));
|
||||||
|
- lines_num = kp_realloc(lines_num, (sz/2) * sizeof(int), sz * sizeof(int));
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- s = f->lines[i];
|
||||||
|
- if (strpbrk(s, ";:") != NULL) {
|
||||||
|
- while (s && *s) {
|
||||||
|
- se = s;
|
||||||
|
- slen = strlen(s);
|
||||||
|
- first_token = 1;
|
||||||
|
- while (se) {
|
||||||
|
- get_token(&se, &t);
|
||||||
|
- if (t.l == 1 && t.s[0] == '#')
|
||||||
|
- goto done;
|
||||||
|
- if (t.l == 1 && t.s[0] == ';') {
|
||||||
|
- slen = t.s - s;
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
- /* first token with ':' after is
|
||||||
|
- * the label, separate it unless
|
||||||
|
- * it is done already (next non-blank
|
||||||
|
- * is '\0')
|
||||||
|
- */
|
||||||
|
- if (first_token && se &&
|
||||||
|
- se[0] == ':' &&
|
||||||
|
- se[1] != '\0') {
|
||||||
|
- slen = se - s + 1;
|
||||||
|
- se++;
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
- first_token = 0;
|
||||||
|
- }
|
||||||
|
- lines[nr] = strndup(s, slen);
|
||||||
|
- s = se;
|
||||||
|
- lines_num[nr] = i;
|
||||||
|
- nr++;
|
||||||
|
- if (nr >= sz)
|
||||||
|
- kpfatal("oops, not prepared to handle >1000 asm statements in single line");
|
||||||
|
- }
|
||||||
|
- free(f->lines[i]);
|
||||||
|
- } else {
|
||||||
|
-done:
|
||||||
|
- lines[nr] = s;
|
||||||
|
- lines_num[nr] = i;
|
||||||
|
- nr++;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- free(f->lines);
|
||||||
|
- f->lines = lines;
|
||||||
|
- f->lines_num = lines_num;
|
||||||
|
- f->nr_lines = nr;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
void init_ctypes(struct kp_file *f)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
282
0028-kpatch_parse-Split-function-is_variable_start.patch
Normal file
282
0028-kpatch_parse-Split-function-is_variable_start.patch
Normal file
@ -0,0 +1,282 @@
|
|||||||
|
From a3fce6e82d24afe186a46461b9cf931f2f023f36 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Date: Mon, 12 Oct 2020 13:48:18 +0800
|
||||||
|
Subject: [PATCH 28/89] kpatch_parse: Split function is_variable_start
|
||||||
|
|
||||||
|
The function is_variable_start is arch related, since different arch may
|
||||||
|
use different assembly directives to describe variables. So let's make
|
||||||
|
two definations in arch/x86/arch_parse.c and arch/aarch64/arch_parse.c
|
||||||
|
|
||||||
|
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||||
|
---
|
||||||
|
src/arch/aarch64/arch_parse.c | 69 ++++++++++++++++++++++++++++++++++
|
||||||
|
src/arch/x86/arch_parse.c | 69 ++++++++++++++++++++++++++++++++++
|
||||||
|
src/include/kpatch_parse.h | 1 +
|
||||||
|
src/kpatch_parse.c | 71 +----------------------------------
|
||||||
|
4 files changed, 140 insertions(+), 70 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/arch/aarch64/arch_parse.c b/src/arch/aarch64/arch_parse.c
|
||||||
|
index 1233e03..abbc38c 100644
|
||||||
|
--- a/src/arch/aarch64/arch_parse.c
|
||||||
|
+++ b/src/arch/aarch64/arch_parse.c
|
||||||
|
@@ -4,6 +4,75 @@
|
||||||
|
#include "include/kpatch_parse.h"
|
||||||
|
#include "include/kpatch_flags.h"
|
||||||
|
|
||||||
|
+int is_variable_start(struct kp_file *f, int l, int *e, int *pglobl, kpstr_t *nm)
|
||||||
|
+{
|
||||||
|
+ char *s;
|
||||||
|
+ int l0 = l, globl = 0;
|
||||||
|
+ kpstr_t nm2, attr;
|
||||||
|
+
|
||||||
|
+ kpstrset(nm, "", 0);
|
||||||
|
+ for ( ; cline(f, l); l++) {
|
||||||
|
+
|
||||||
|
+ /* first verify that all the commands we met has the same symbol name... just to be safe! */
|
||||||
|
+ s = cline(f, l);
|
||||||
|
+ if (*s == '\0' && l != l0)
|
||||||
|
+ continue;
|
||||||
|
+ switch (ctype(f, l)) {
|
||||||
|
+ case DIRECTIVE_TYPE:
|
||||||
|
+ case DIRECTIVE_GLOBL:
|
||||||
|
+ case DIRECTIVE_LOCAL:
|
||||||
|
+ get_token(&s, &nm2);
|
||||||
|
+ case DIRECTIVE_LABEL:
|
||||||
|
+ get_token(&s, &nm2);
|
||||||
|
+ if (nm->l && kpstrcmp(nm, &nm2)) /* some other symbol met... stop */
|
||||||
|
+ return 0;
|
||||||
|
+ *nm = nm2;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ switch (ctype(f, l)) {
|
||||||
|
+ case DIRECTIVE_TEXT:
|
||||||
|
+ case DIRECTIVE_DATA:
|
||||||
|
+ case DIRECTIVE_BSS:
|
||||||
|
+ case DIRECTIVE_SECTION:
|
||||||
|
+ case DIRECTIVE_PUSHSECTION:
|
||||||
|
+ case DIRECTIVE_POPSECTION:
|
||||||
|
+ case DIRECTIVE_PREVIOUS:
|
||||||
|
+ case DIRECTIVE_SUBSECTION:
|
||||||
|
+ break;
|
||||||
|
+ case DIRECTIVE_TYPE:
|
||||||
|
+ get_type_args(cline(f, l), &nm2, &attr);
|
||||||
|
+ if (kpstrcmpz(&attr, "%object") && kpstrcmpz(&attr, "%tls_object"))
|
||||||
|
+ return 0;
|
||||||
|
+ break;
|
||||||
|
+ case DIRECTIVE_GLOBL:
|
||||||
|
+ globl = 1;
|
||||||
|
+ break;
|
||||||
|
+ case DIRECTIVE_ALIGN:
|
||||||
|
+ break;
|
||||||
|
+ case DIRECTIVE_COMMENT:
|
||||||
|
+ case DIRECTIVE_SIZE:
|
||||||
|
+ /* can't start with .size */
|
||||||
|
+ if (l0 == l)
|
||||||
|
+ return 0;
|
||||||
|
+ break;
|
||||||
|
+ case DIRECTIVE_LABEL:
|
||||||
|
+ if (!is_data_sect(csect(f, l)))
|
||||||
|
+ return 0;
|
||||||
|
+ /* fall throught */
|
||||||
|
+ case DIRECTIVE_LOCAL:
|
||||||
|
+ if (e)
|
||||||
|
+ *e = l + 1;
|
||||||
|
+ if (pglobl)
|
||||||
|
+ *pglobl = globl;
|
||||||
|
+ return 1;
|
||||||
|
+ default:
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* break manually crafted multiple statements separated by ; to separate lines */
|
||||||
|
void init_multilines(struct kp_file *f)
|
||||||
|
{
|
||||||
|
diff --git a/src/arch/x86/arch_parse.c b/src/arch/x86/arch_parse.c
|
||||||
|
index 92ff483..ca57507 100644
|
||||||
|
--- a/src/arch/x86/arch_parse.c
|
||||||
|
+++ b/src/arch/x86/arch_parse.c
|
||||||
|
@@ -4,6 +4,75 @@
|
||||||
|
#include "include/kpatch_parse.h"
|
||||||
|
#include "include/kpatch_flags.h"
|
||||||
|
|
||||||
|
+int is_variable_start(struct kp_file *f, int l, int *e, int *pglobl, kpstr_t *nm)
|
||||||
|
+{
|
||||||
|
+ char *s;
|
||||||
|
+ int l0 = l, globl = 0;
|
||||||
|
+ kpstr_t nm2, attr;
|
||||||
|
+
|
||||||
|
+ kpstrset(nm, "", 0);
|
||||||
|
+ for ( ; cline(f, l); l++) {
|
||||||
|
+
|
||||||
|
+ /* first verify that all the commands we met has the same symbol name... just to be safe! */
|
||||||
|
+ s = cline(f, l);
|
||||||
|
+ if (*s == '\0' && l != l0)
|
||||||
|
+ continue;
|
||||||
|
+ switch (ctype(f, l)) {
|
||||||
|
+ case DIRECTIVE_TYPE:
|
||||||
|
+ case DIRECTIVE_GLOBL:
|
||||||
|
+ case DIRECTIVE_LOCAL:
|
||||||
|
+ get_token(&s, &nm2);
|
||||||
|
+ case DIRECTIVE_LABEL:
|
||||||
|
+ get_token(&s, &nm2);
|
||||||
|
+ if (nm->l && kpstrcmp(nm, &nm2)) /* some other symbol met... stop */
|
||||||
|
+ return 0;
|
||||||
|
+ *nm = nm2;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ switch (ctype(f, l)) {
|
||||||
|
+ case DIRECTIVE_TEXT:
|
||||||
|
+ case DIRECTIVE_DATA:
|
||||||
|
+ case DIRECTIVE_BSS:
|
||||||
|
+ case DIRECTIVE_SECTION:
|
||||||
|
+ case DIRECTIVE_PUSHSECTION:
|
||||||
|
+ case DIRECTIVE_POPSECTION:
|
||||||
|
+ case DIRECTIVE_PREVIOUS:
|
||||||
|
+ case DIRECTIVE_SUBSECTION:
|
||||||
|
+ break;
|
||||||
|
+ case DIRECTIVE_TYPE:
|
||||||
|
+ get_type_args(cline(f, l), &nm2, &attr);
|
||||||
|
+ if (kpstrcmpz(&attr, "@object"))
|
||||||
|
+ return 0;
|
||||||
|
+ break;
|
||||||
|
+ case DIRECTIVE_GLOBL:
|
||||||
|
+ globl = 1;
|
||||||
|
+ break;
|
||||||
|
+ case DIRECTIVE_ALIGN:
|
||||||
|
+ break;
|
||||||
|
+ case DIRECTIVE_COMMENT:
|
||||||
|
+ case DIRECTIVE_SIZE:
|
||||||
|
+ /* can't start with .size */
|
||||||
|
+ if (l0 == l)
|
||||||
|
+ return 0;
|
||||||
|
+ break;
|
||||||
|
+ case DIRECTIVE_LABEL:
|
||||||
|
+ if (!is_data_sect(csect(f, l)))
|
||||||
|
+ return 0;
|
||||||
|
+ /* fall throught */
|
||||||
|
+ case DIRECTIVE_LOCAL:
|
||||||
|
+ if (e)
|
||||||
|
+ *e = l + 1;
|
||||||
|
+ if (pglobl)
|
||||||
|
+ *pglobl = globl;
|
||||||
|
+ return 1;
|
||||||
|
+ default:
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* break manually crafted multiple statements separated by ; to separate lines */
|
||||||
|
void init_multilines(struct kp_file *f)
|
||||||
|
{
|
||||||
|
diff --git a/src/include/kpatch_parse.h b/src/include/kpatch_parse.h
|
||||||
|
index e1b7501..0f41509 100644
|
||||||
|
--- a/src/include/kpatch_parse.h
|
||||||
|
+++ b/src/include/kpatch_parse.h
|
||||||
|
@@ -109,6 +109,7 @@ void __get_token(char **str, kpstr_t *x, const char *delim);
|
||||||
|
int is_function_start(struct kp_file *f, int l, kpstr_t *nm);
|
||||||
|
int is_function_end(struct kp_file *f, int l, kpstr_t *nm);
|
||||||
|
|
||||||
|
+void get_type_args(char *s, kpstr_t *nm, kpstr_t *attr);
|
||||||
|
int is_variable_start(struct kp_file *f, int l, int *e, int *globl, kpstr_t *nm);
|
||||||
|
int is_data_def(char *s, int type);
|
||||||
|
|
||||||
|
diff --git a/src/kpatch_parse.c b/src/kpatch_parse.c
|
||||||
|
index 857dbf3..a3be7c0 100644
|
||||||
|
--- a/src/kpatch_parse.c
|
||||||
|
+++ b/src/kpatch_parse.c
|
||||||
|
@@ -93,7 +93,7 @@ static struct {
|
||||||
|
};
|
||||||
|
|
||||||
|
/* parse arguments of .type command */
|
||||||
|
-static void get_type_args(char *s, kpstr_t *nm, kpstr_t *attr)
|
||||||
|
+void get_type_args(char *s, kpstr_t *nm, kpstr_t *attr)
|
||||||
|
{
|
||||||
|
kpstr_t t, t2;
|
||||||
|
|
||||||
|
@@ -674,75 +674,6 @@ int is_function_end(struct kp_file *f, int l, kpstr_t *nm)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
-int is_variable_start(struct kp_file *f, int l, int *e, int *pglobl, kpstr_t *nm)
|
||||||
|
-{
|
||||||
|
- char *s;
|
||||||
|
- int l0 = l, globl = 0;
|
||||||
|
- kpstr_t nm2, attr;
|
||||||
|
-
|
||||||
|
- kpstrset(nm, "", 0);
|
||||||
|
- for ( ; cline(f, l); l++) {
|
||||||
|
-
|
||||||
|
- /* first verify that all the commands we met has the same symbol name... just to be safe! */
|
||||||
|
- s = cline(f, l);
|
||||||
|
- if (*s == '\0' && l != l0)
|
||||||
|
- continue;
|
||||||
|
- switch (ctype(f, l)) {
|
||||||
|
- case DIRECTIVE_TYPE:
|
||||||
|
- case DIRECTIVE_GLOBL:
|
||||||
|
- case DIRECTIVE_LOCAL:
|
||||||
|
- get_token(&s, &nm2);
|
||||||
|
- case DIRECTIVE_LABEL:
|
||||||
|
- get_token(&s, &nm2);
|
||||||
|
- if (nm->l && kpstrcmp(nm, &nm2)) /* some other symbol met... stop */
|
||||||
|
- return 0;
|
||||||
|
- *nm = nm2;
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- switch (ctype(f, l)) {
|
||||||
|
- case DIRECTIVE_TEXT:
|
||||||
|
- case DIRECTIVE_DATA:
|
||||||
|
- case DIRECTIVE_BSS:
|
||||||
|
- case DIRECTIVE_SECTION:
|
||||||
|
- case DIRECTIVE_PUSHSECTION:
|
||||||
|
- case DIRECTIVE_POPSECTION:
|
||||||
|
- case DIRECTIVE_PREVIOUS:
|
||||||
|
- case DIRECTIVE_SUBSECTION:
|
||||||
|
- break;
|
||||||
|
- case DIRECTIVE_TYPE:
|
||||||
|
- get_type_args(cline(f, l), &nm2, &attr);
|
||||||
|
- if (kpstrcmpz(&attr, "@object"))
|
||||||
|
- return 0;
|
||||||
|
- break;
|
||||||
|
- case DIRECTIVE_GLOBL:
|
||||||
|
- globl = 1;
|
||||||
|
- break;
|
||||||
|
- case DIRECTIVE_ALIGN:
|
||||||
|
- break;
|
||||||
|
- case DIRECTIVE_COMMENT:
|
||||||
|
- case DIRECTIVE_SIZE:
|
||||||
|
- /* can't start with .size */
|
||||||
|
- if (l0 == l)
|
||||||
|
- return 0;
|
||||||
|
- break;
|
||||||
|
- case DIRECTIVE_LABEL:
|
||||||
|
- if (!is_data_sect(csect(f, l)))
|
||||||
|
- return 0;
|
||||||
|
- /* fall throught */
|
||||||
|
- case DIRECTIVE_LOCAL:
|
||||||
|
- if (e)
|
||||||
|
- *e = l + 1;
|
||||||
|
- if (pglobl)
|
||||||
|
- *pglobl = globl;
|
||||||
|
- return 1;
|
||||||
|
- default:
|
||||||
|
- return 0;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- return 0;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
int is_data_def(char *s, int type)
|
||||||
|
{
|
||||||
|
kpstr_t t;
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
180
0029-kpatch_parse-Split-function-is_data_def.patch
Normal file
180
0029-kpatch_parse-Split-function-is_data_def.patch
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
From eaff972f8edd58491eeca17f4b7553cceb1fb5d4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Date: Mon, 12 Oct 2020 13:53:01 +0800
|
||||||
|
Subject: [PATCH 29/89] kpatch_parse: Split function is_data_def
|
||||||
|
|
||||||
|
The function is_data_def is arch related, so let's make two
|
||||||
|
separate definations in arch/x86/arch_parse.c and arch/aarch64/arch_parse.c
|
||||||
|
|
||||||
|
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
---
|
||||||
|
src/arch/aarch64/arch_parse.c | 64 +++++++++++++++++++++++++++++++++++
|
||||||
|
src/arch/x86/arch_parse.c | 34 +++++++++++++++++++
|
||||||
|
src/kpatch_parse.c | 33 ------------------
|
||||||
|
3 files changed, 98 insertions(+), 33 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/arch/aarch64/arch_parse.c b/src/arch/aarch64/arch_parse.c
|
||||||
|
index abbc38c..fea09f6 100644
|
||||||
|
--- a/src/arch/aarch64/arch_parse.c
|
||||||
|
+++ b/src/arch/aarch64/arch_parse.c
|
||||||
|
@@ -4,6 +4,70 @@
|
||||||
|
#include "include/kpatch_parse.h"
|
||||||
|
#include "include/kpatch_flags.h"
|
||||||
|
|
||||||
|
+int is_data_def(char *s, int type)
|
||||||
|
+{
|
||||||
|
+ kpstr_t t;
|
||||||
|
+
|
||||||
|
+ get_token(&s, &t);
|
||||||
|
+ if (
|
||||||
|
+ /* strings */
|
||||||
|
+ !kpstrcmpz(&t, ".ascii") ||
|
||||||
|
+ !kpstrcmpz(&t, ".asciz") ||
|
||||||
|
+ !kpstrcmpz(&t, ".string") ||
|
||||||
|
+ !kpstrcmpz(&t, ".string8") ||
|
||||||
|
+ !kpstrcmpz(&t, ".string16") ||
|
||||||
|
+ !kpstrcmpz(&t, ".string32") ||
|
||||||
|
+ !kpstrcmpz(&t, ".string64") ||
|
||||||
|
+ /* numeric */
|
||||||
|
+ !kpstrcmpz(&t, ".byte") ||
|
||||||
|
+ !kpstrcmpz(&t, ".1byte") ||
|
||||||
|
+ !kpstrcmpz(&t, ".dc.b") ||
|
||||||
|
+
|
||||||
|
+ !kpstrcmpz(&t, ".hword") ||
|
||||||
|
+ !kpstrcmpz(&t, ".short") ||
|
||||||
|
+ !kpstrcmpz(&t, ".2byte") ||
|
||||||
|
+ !kpstrcmpz(&t, ".dc") ||
|
||||||
|
+ !kpstrcmpz(&t, ".dc.w") ||
|
||||||
|
+ !kpstrcmpz(&t, ".value") ||
|
||||||
|
+ !kpstrcmpz(&t, ".octa") ||
|
||||||
|
+
|
||||||
|
+ !kpstrcmpz(&t, ".word") ||
|
||||||
|
+ !kpstrcmpz(&t, ".4byte") ||
|
||||||
|
+ !kpstrcmpz(&t, ".long") ||
|
||||||
|
+ !kpstrcmpz(&t, ".int") ||
|
||||||
|
+ !kpstrcmpz(&t, ".dc.l") ||
|
||||||
|
+ !kpstrcmpz(&t, ".dc.a") ||// (AArch32 only)
|
||||||
|
+
|
||||||
|
+ !kpstrcmpz(&t, ".quad") ||
|
||||||
|
+ !kpstrcmpz(&t, ".8byte") ||
|
||||||
|
+ !kpstrcmpz(&t, ".xword") ||//(AArch64 only)
|
||||||
|
+ !kpstrcmpz(&t, ".dc.a") ||//(AArch64 only)
|
||||||
|
+
|
||||||
|
+ !kpstrcmpz(&t, ".short") ||
|
||||||
|
+ !kpstrcmpz(&t, ".int") ||
|
||||||
|
+ !kpstrcmpz(&t, ".long") ||
|
||||||
|
+ !kpstrcmpz(&t, ".quad") ||
|
||||||
|
+ /* float */
|
||||||
|
+ !kpstrcmpz(&t, ".double") ||
|
||||||
|
+ !kpstrcmpz(&t, ".dc.d") ||
|
||||||
|
+ !kpstrcmpz(&t, ".float") ||
|
||||||
|
+ !kpstrcmpz(&t, ".single") ||
|
||||||
|
+ !kpstrcmpz(&t, ".dc.s") ||
|
||||||
|
+ /* other */
|
||||||
|
+ !kpstrcmpz(&t, ".value") ||
|
||||||
|
+ !kpstrcmpz(&t, ".comm") ||
|
||||||
|
+ !kpstrcmpz(&t, ".zero") ||
|
||||||
|
+ !kpstrcmpz(&t, ".fill") ||
|
||||||
|
+ !kpstrcmpz(&t, ".space") ||
|
||||||
|
+ !kpstrcmpz(&t, ".skip") ||
|
||||||
|
+ /* dwarf types */
|
||||||
|
+ !kpstrcmpz(&t, ".uleb128") ||
|
||||||
|
+ !kpstrcmpz(&t, ".sleb128")
|
||||||
|
+ )
|
||||||
|
+ return 1;
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int is_variable_start(struct kp_file *f, int l, int *e, int *pglobl, kpstr_t *nm)
|
||||||
|
{
|
||||||
|
char *s;
|
||||||
|
diff --git a/src/arch/x86/arch_parse.c b/src/arch/x86/arch_parse.c
|
||||||
|
index ca57507..81edaf8 100644
|
||||||
|
--- a/src/arch/x86/arch_parse.c
|
||||||
|
+++ b/src/arch/x86/arch_parse.c
|
||||||
|
@@ -4,6 +4,40 @@
|
||||||
|
#include "include/kpatch_parse.h"
|
||||||
|
#include "include/kpatch_flags.h"
|
||||||
|
|
||||||
|
+int is_data_def(char *s, int type)
|
||||||
|
+{
|
||||||
|
+ kpstr_t t;
|
||||||
|
+
|
||||||
|
+ get_token(&s, &t);
|
||||||
|
+ if (
|
||||||
|
+ /* strings */
|
||||||
|
+ !kpstrcmpz(&t, ".ascii") ||
|
||||||
|
+ !kpstrcmpz(&t, ".asciz") ||
|
||||||
|
+ !kpstrcmpz(&t, ".string") ||
|
||||||
|
+ /* numeric */
|
||||||
|
+ !kpstrcmpz(&t, ".byte") ||
|
||||||
|
+ !kpstrcmpz(&t, ".word") ||
|
||||||
|
+ !kpstrcmpz(&t, ".short") ||
|
||||||
|
+ !kpstrcmpz(&t, ".int") ||
|
||||||
|
+ !kpstrcmpz(&t, ".long") ||
|
||||||
|
+ !kpstrcmpz(&t, ".quad") ||
|
||||||
|
+ /* float */
|
||||||
|
+ !kpstrcmpz(&t, ".double") ||
|
||||||
|
+ !kpstrcmpz(&t, ".float") ||
|
||||||
|
+ !kpstrcmpz(&t, ".single") ||
|
||||||
|
+ /* other */
|
||||||
|
+ !kpstrcmpz(&t, ".value") ||
|
||||||
|
+ !kpstrcmpz(&t, ".comm") ||
|
||||||
|
+ !kpstrcmpz(&t, ".zero") ||
|
||||||
|
+ /* dwarf types */
|
||||||
|
+ !kpstrcmpz(&t, ".uleb128") ||
|
||||||
|
+ !kpstrcmpz(&t, ".sleb128") ||
|
||||||
|
+ !kpstrcmpz(&t, ".4byte")
|
||||||
|
+ )
|
||||||
|
+ return 1;
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int is_variable_start(struct kp_file *f, int l, int *e, int *pglobl, kpstr_t *nm)
|
||||||
|
{
|
||||||
|
char *s;
|
||||||
|
diff --git a/src/kpatch_parse.c b/src/kpatch_parse.c
|
||||||
|
index a3be7c0..f486b55 100644
|
||||||
|
--- a/src/kpatch_parse.c
|
||||||
|
+++ b/src/kpatch_parse.c
|
||||||
|
@@ -674,37 +674,4 @@ int is_function_end(struct kp_file *f, int l, kpstr_t *nm)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
-int is_data_def(char *s, int type)
|
||||||
|
-{
|
||||||
|
- kpstr_t t;
|
||||||
|
-
|
||||||
|
- get_token(&s, &t);
|
||||||
|
- if (
|
||||||
|
- /* strings */
|
||||||
|
- !kpstrcmpz(&t, ".ascii") ||
|
||||||
|
- !kpstrcmpz(&t, ".asciz") ||
|
||||||
|
- !kpstrcmpz(&t, ".string") ||
|
||||||
|
- /* numeric */
|
||||||
|
- !kpstrcmpz(&t, ".byte") ||
|
||||||
|
- !kpstrcmpz(&t, ".word") ||
|
||||||
|
- !kpstrcmpz(&t, ".short") ||
|
||||||
|
- !kpstrcmpz(&t, ".int") ||
|
||||||
|
- !kpstrcmpz(&t, ".long") ||
|
||||||
|
- !kpstrcmpz(&t, ".quad") ||
|
||||||
|
- /* float */
|
||||||
|
- !kpstrcmpz(&t, ".double") ||
|
||||||
|
- !kpstrcmpz(&t, ".float") ||
|
||||||
|
- !kpstrcmpz(&t, ".single") ||
|
||||||
|
- /* other */
|
||||||
|
- !kpstrcmpz(&t, ".value") ||
|
||||||
|
- !kpstrcmpz(&t, ".comm") ||
|
||||||
|
- !kpstrcmpz(&t, ".zero") ||
|
||||||
|
- /* dwarf types */
|
||||||
|
- !kpstrcmpz(&t, ".uleb128") ||
|
||||||
|
- !kpstrcmpz(&t, ".sleb128") ||
|
||||||
|
- !kpstrcmpz(&t, ".4byte")
|
||||||
|
- )
|
||||||
|
- return 1;
|
||||||
|
- return 0;
|
||||||
|
-}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
149
0030-kpatch_parse-Split-function-is_function_start.patch
Normal file
149
0030-kpatch_parse-Split-function-is_function_start.patch
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
From 3ecebe9ea858d5502af5f5cd79141e4546ae3fe8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Date: Mon, 12 Oct 2020 13:58:58 +0800
|
||||||
|
Subject: [PATCH 30/89] kpatch_parse: Split function is_function_start
|
||||||
|
|
||||||
|
The function is_function_start is arch related, so make two
|
||||||
|
separate definations in arch/x86/arch_parse.c and arch/aarch64/arch_parse.c
|
||||||
|
|
||||||
|
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||||
|
---
|
||||||
|
src/arch/aarch64/arch_parse.c | 32 ++++++++++++++++++++++++++++++++
|
||||||
|
src/arch/x86/arch_parse.c | 32 ++++++++++++++++++++++++++++++++
|
||||||
|
src/kpatch_parse.c | 33 ---------------------------------
|
||||||
|
3 files changed, 64 insertions(+), 33 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/arch/aarch64/arch_parse.c b/src/arch/aarch64/arch_parse.c
|
||||||
|
index fea09f6..e0f0c8b 100644
|
||||||
|
--- a/src/arch/aarch64/arch_parse.c
|
||||||
|
+++ b/src/arch/aarch64/arch_parse.c
|
||||||
|
@@ -4,6 +4,38 @@
|
||||||
|
#include "include/kpatch_parse.h"
|
||||||
|
#include "include/kpatch_flags.h"
|
||||||
|
|
||||||
|
+int is_function_start(struct kp_file *f, int l, kpstr_t *nm)
|
||||||
|
+{
|
||||||
|
+ char *s;
|
||||||
|
+ kpstr_t nm2, attr;
|
||||||
|
+ int l0 = l, func = 0;
|
||||||
|
+
|
||||||
|
+ kpstrset(nm, "", 0);
|
||||||
|
+ for (; l < f->nr_lines; l++) {
|
||||||
|
+ if (l != l0 && cline(f, l)[0] == '\0')
|
||||||
|
+ continue;
|
||||||
|
+ if ((is_sect_cmd(f, l) && is_code_sect(csect(f, l))) ||
|
||||||
|
+ ctype(f, l) == DIRECTIVE_ALIGN)
|
||||||
|
+ continue;
|
||||||
|
+ get_type_args(cline(f, l), &nm2, &attr);
|
||||||
|
+ if ((ctype(f, l) == DIRECTIVE_WEAK && l0 != l) ||
|
||||||
|
+ ctype(f, l) == DIRECTIVE_GLOBL || ctype(f, l) == DIRECTIVE_HIDDEN ||
|
||||||
|
+ ctype(f, l) == DIRECTIVE_PROTECTED || ctype(f, l) == DIRECTIVE_INTERNAL ||
|
||||||
|
+ (ctype(f, l) == DIRECTIVE_TYPE && !kpstrcmpz(&attr, "%function"))) {
|
||||||
|
+ s = cline(f, l);
|
||||||
|
+ get_token(&s, &nm2); /* skip command */
|
||||||
|
+ get_token(&s, &nm2);
|
||||||
|
+ if (nm->l && kpstrcmp(nm, &nm2)) /* verify name matches in all .weak/.globl/.type commands */
|
||||||
|
+ return 0;
|
||||||
|
+ *nm = nm2;
|
||||||
|
+ func = func ? 1 : ctype(f, l) == DIRECTIVE_TYPE;
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ return func;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int is_data_def(char *s, int type)
|
||||||
|
{
|
||||||
|
kpstr_t t;
|
||||||
|
diff --git a/src/arch/x86/arch_parse.c b/src/arch/x86/arch_parse.c
|
||||||
|
index 81edaf8..c51c49b 100644
|
||||||
|
--- a/src/arch/x86/arch_parse.c
|
||||||
|
+++ b/src/arch/x86/arch_parse.c
|
||||||
|
@@ -4,6 +4,38 @@
|
||||||
|
#include "include/kpatch_parse.h"
|
||||||
|
#include "include/kpatch_flags.h"
|
||||||
|
|
||||||
|
+int is_function_start(struct kp_file *f, int l, kpstr_t *nm)
|
||||||
|
+{
|
||||||
|
+ char *s;
|
||||||
|
+ kpstr_t nm2, attr;
|
||||||
|
+ int l0 = l, func = 0;
|
||||||
|
+
|
||||||
|
+ kpstrset(nm, "", 0);
|
||||||
|
+ for (; l < f->nr_lines; l++) {
|
||||||
|
+ if (l != l0 && cline(f, l)[0] == '\0')
|
||||||
|
+ continue;
|
||||||
|
+ if ((is_sect_cmd(f, l) && is_code_sect(csect(f, l))) ||
|
||||||
|
+ ctype(f, l) == DIRECTIVE_ALIGN)
|
||||||
|
+ continue;
|
||||||
|
+ get_type_args(cline(f, l), &nm2, &attr);
|
||||||
|
+ if ((ctype(f, l) == DIRECTIVE_WEAK && l0 != l) ||
|
||||||
|
+ ctype(f, l) == DIRECTIVE_GLOBL || ctype(f, l) == DIRECTIVE_HIDDEN ||
|
||||||
|
+ ctype(f, l) == DIRECTIVE_PROTECTED || ctype(f, l) == DIRECTIVE_INTERNAL ||
|
||||||
|
+ (ctype(f, l) == DIRECTIVE_TYPE && !kpstrcmpz(&attr, "@function"))) {
|
||||||
|
+ s = cline(f, l);
|
||||||
|
+ get_token(&s, &nm2); /* skip command */
|
||||||
|
+ get_token(&s, &nm2);
|
||||||
|
+ if (nm->l && kpstrcmp(nm, &nm2)) /* verify name matches in all .weak/.globl/.type commands */
|
||||||
|
+ return 0;
|
||||||
|
+ *nm = nm2;
|
||||||
|
+ func = func ? 1 : ctype(f, l) == DIRECTIVE_TYPE;
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ return func;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int is_data_def(char *s, int type)
|
||||||
|
{
|
||||||
|
kpstr_t t;
|
||||||
|
diff --git a/src/kpatch_parse.c b/src/kpatch_parse.c
|
||||||
|
index f486b55..3df658d 100644
|
||||||
|
--- a/src/kpatch_parse.c
|
||||||
|
+++ b/src/kpatch_parse.c
|
||||||
|
@@ -625,39 +625,6 @@ void init_sections(struct kp_file *f)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------- code block boundaries detection ---------------------------------------- */
|
||||||
|
-
|
||||||
|
-int is_function_start(struct kp_file *f, int l, kpstr_t *nm)
|
||||||
|
-{
|
||||||
|
- char *s;
|
||||||
|
- kpstr_t nm2, attr;
|
||||||
|
- int l0 = l, func = 0;
|
||||||
|
-
|
||||||
|
- kpstrset(nm, "", 0);
|
||||||
|
- for (; l < f->nr_lines; l++) {
|
||||||
|
- if (l != l0 && cline(f, l)[0] == '\0')
|
||||||
|
- continue;
|
||||||
|
- if ((is_sect_cmd(f, l) && is_code_sect(csect(f, l))) ||
|
||||||
|
- ctype(f, l) == DIRECTIVE_ALIGN)
|
||||||
|
- continue;
|
||||||
|
- get_type_args(cline(f, l), &nm2, &attr);
|
||||||
|
- if ((ctype(f, l) == DIRECTIVE_WEAK && l0 != l) ||
|
||||||
|
- ctype(f, l) == DIRECTIVE_GLOBL || ctype(f, l) == DIRECTIVE_HIDDEN ||
|
||||||
|
- ctype(f, l) == DIRECTIVE_PROTECTED || ctype(f, l) == DIRECTIVE_INTERNAL ||
|
||||||
|
- (ctype(f, l) == DIRECTIVE_TYPE && !kpstrcmpz(&attr, "@function"))) {
|
||||||
|
- s = cline(f, l);
|
||||||
|
- get_token(&s, &nm2); /* skip command */
|
||||||
|
- get_token(&s, &nm2);
|
||||||
|
- if (nm->l && kpstrcmp(nm, &nm2)) /* verify name matches in all .weak/.globl/.type commands */
|
||||||
|
- return 0;
|
||||||
|
- *nm = nm2;
|
||||||
|
- func = func ? 1 : ctype(f, l) == DIRECTIVE_TYPE;
|
||||||
|
- continue;
|
||||||
|
- }
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
- return func;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
int is_function_end(struct kp_file *f, int l, kpstr_t *nm)
|
||||||
|
{
|
||||||
|
/* Functions should always end by .size directive. Previously used to detect .LFe labels, but they are not generated w/o frame pointers */
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
43
0031-kpatch_common.h-Factor-out-PAGE_SIZE-marco.patch
Normal file
43
0031-kpatch_common.h-Factor-out-PAGE_SIZE-marco.patch
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
From 0430a8354e988a1a72896844d45b1a5c83743d74 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Date: Mon, 12 Oct 2020 14:02:50 +0800
|
||||||
|
Subject: [PATCH 31/89] kpatch_common.h: Factor out PAGE_SIZE marco
|
||||||
|
|
||||||
|
Since page size may be different on OS configuration. Let's make a
|
||||||
|
change it to get PAGE_SIZE dynamicly accquired from syscall.
|
||||||
|
|
||||||
|
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||||
|
---
|
||||||
|
src/include/kpatch_common.h | 17 +++++++++++++++++
|
||||||
|
1 file changed, 17 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/include/kpatch_common.h b/src/include/kpatch_common.h
|
||||||
|
index c160250..775ea14 100644
|
||||||
|
--- a/src/include/kpatch_common.h
|
||||||
|
+++ b/src/include/kpatch_common.h
|
||||||
|
@@ -41,4 +41,21 @@ int kpatch_close_file(struct kp_file *kpatch);
|
||||||
|
# define R_X86_64_GOTPCRELX 0x29
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+static inline int page_shift(int n) {
|
||||||
|
+ int res = -1;
|
||||||
|
+
|
||||||
|
+ while(n) {
|
||||||
|
+ res++;
|
||||||
|
+ n >>= 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return res;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#ifndef PAGE_SIZE
|
||||||
|
+#define PAGE_SIZE getpagesize()
|
||||||
|
+#define PAGE_MASK (~(PAGE_SIZE-1))
|
||||||
|
+#define PAGE_SHIFT page_shift(PAGE_SIZE)
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
#endif
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
196
0032-kpatch_coro-Split-function-_UCORO_access_reg.patch
Normal file
196
0032-kpatch_coro-Split-function-_UCORO_access_reg.patch
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
From ae9e01aefed4105c808301e783d29ddd349dc0f6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Date: Mon, 12 Oct 2020 14:22:45 +0800
|
||||||
|
Subject: [PATCH 32/89] kpatch_coro: Split function _UCORO_access_reg
|
||||||
|
|
||||||
|
The function _UCORO_access_reg is arch related, so make two
|
||||||
|
separate definations in arch/x86/arch_coro.c and arch/aarch64/arch_coro.c
|
||||||
|
|
||||||
|
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||||
|
---
|
||||||
|
src/arch/aarch64/arch_coro.c | 39 ++++++++++++++++++++++++++++++++
|
||||||
|
src/arch/x86/arch_coro.c | 43 ++++++++++++++++++++++++++++++++++++
|
||||||
|
src/include/kpatch_coro.h | 11 +++++++++
|
||||||
|
src/kpatch_coro.c | 37 -------------------------------
|
||||||
|
4 files changed, 93 insertions(+), 37 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/arch/aarch64/arch_coro.c b/src/arch/aarch64/arch_coro.c
|
||||||
|
index e69de29..e6fe3d0 100644
|
||||||
|
--- a/src/arch/aarch64/arch_coro.c
|
||||||
|
+++ b/src/arch/aarch64/arch_coro.c
|
||||||
|
@@ -0,0 +1,39 @@
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <libunwind-ptrace.h>
|
||||||
|
+#include <sys/utsname.h>
|
||||||
|
+
|
||||||
|
+#include "include/kpatch_user.h"
|
||||||
|
+#include "include/kpatch_coro.h"
|
||||||
|
+#include "include/kpatch_common.h"
|
||||||
|
+#include "include/kpatch_elf.h"
|
||||||
|
+#include "include/kpatch_ptrace.h"
|
||||||
|
+#include "include/kpatch_log.h"
|
||||||
|
+
|
||||||
|
+int _UCORO_access_reg(unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val,
|
||||||
|
+ int write, void *arg)
|
||||||
|
+{
|
||||||
|
+ struct UCORO_info *info = (struct UCORO_info *)arg;
|
||||||
|
+ unsigned long *regs = (unsigned long *)info->coro->env[0].__jmpbuf;
|
||||||
|
+
|
||||||
|
+ if (write) {
|
||||||
|
+ kperr("_UCORO_access_reg: write is not implemeneted (%d)\n", reg);
|
||||||
|
+ return -UNW_EINVAL;
|
||||||
|
+ }
|
||||||
|
+ switch (reg) {
|
||||||
|
+ case UNW_AARCH64_X9:
|
||||||
|
+ *val = regs[JB_RBX]; break;
|
||||||
|
+ case UNW_AARCH64_X29:
|
||||||
|
+ *val = regs[JB_RBP]; break;
|
||||||
|
+ case UNW_AARCH64_X12...UNW_AARCH64_X15:
|
||||||
|
+ *val = regs[reg - UNW_AARCH64_X12 + JB_R12]; break;
|
||||||
|
+ case UNW_AARCH64_SP:
|
||||||
|
+ *val = regs[JB_RSP]; break;
|
||||||
|
+ case UNW_AARCH64_PC:
|
||||||
|
+ *val = regs[JB_RIP]; break;
|
||||||
|
+ default:
|
||||||
|
+ return _UPT_access_reg(as, reg, val, write, arg);
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
diff --git a/src/arch/x86/arch_coro.c b/src/arch/x86/arch_coro.c
|
||||||
|
index e69de29..ce889df 100644
|
||||||
|
--- a/src/arch/x86/arch_coro.c
|
||||||
|
+++ b/src/arch/x86/arch_coro.c
|
||||||
|
@@ -0,0 +1,43 @@
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+
|
||||||
|
+#include <libunwind-ptrace.h>
|
||||||
|
+
|
||||||
|
+#include <sys/utsname.h>
|
||||||
|
+
|
||||||
|
+#include <asm/prctl.h>
|
||||||
|
+
|
||||||
|
+#include "include/kpatch_user.h"
|
||||||
|
+#include "include/kpatch_coro.h"
|
||||||
|
+#include "include/kpatch_common.h"
|
||||||
|
+#include "include/kpatch_elf.h"
|
||||||
|
+#include "include/kpatch_ptrace.h"
|
||||||
|
+#include "include/kpatch_log.h"
|
||||||
|
+
|
||||||
|
+int _UCORO_access_reg(unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val,
|
||||||
|
+ int write, void *arg)
|
||||||
|
+{
|
||||||
|
+ struct UCORO_info *info = (struct UCORO_info *)arg;
|
||||||
|
+ unsigned long *regs = (unsigned long *)info->coro->env[0].__jmpbuf;
|
||||||
|
+
|
||||||
|
+ if (write) {
|
||||||
|
+ kperr("_UCORO_access_reg: write is not implemeneted (%d)\n", reg);
|
||||||
|
+ return -UNW_EINVAL;
|
||||||
|
+ }
|
||||||
|
+ switch (reg) {
|
||||||
|
+ case UNW_X86_64_RBX:
|
||||||
|
+ *val = regs[JB_RBX]; break;
|
||||||
|
+ case UNW_X86_64_RBP:
|
||||||
|
+ *val = regs[JB_RBP]; break;
|
||||||
|
+ case UNW_X86_64_R12...UNW_X86_64_R15:
|
||||||
|
+ *val = regs[reg - UNW_X86_64_R12 + JB_R12]; break;
|
||||||
|
+ case UNW_X86_64_RSP:
|
||||||
|
+ *val = regs[JB_RSP]; break;
|
||||||
|
+ case UNW_X86_64_RIP:
|
||||||
|
+ *val = regs[JB_RIP]; break;
|
||||||
|
+ default:
|
||||||
|
+ return _UPT_access_reg(as, reg, val, write, arg);
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
diff --git a/src/include/kpatch_coro.h b/src/include/kpatch_coro.h
|
||||||
|
index 1588b5e..760b1db 100644
|
||||||
|
--- a/src/include/kpatch_coro.h
|
||||||
|
+++ b/src/include/kpatch_coro.h
|
||||||
|
@@ -19,6 +19,17 @@ struct kpatch_coro {
|
||||||
|
void *_UCORO_create(struct kpatch_coro *coro, pid_t pid);
|
||||||
|
void _UCORO_destroy(void *arg);
|
||||||
|
|
||||||
|
+
|
||||||
|
+struct UCORO_info {
|
||||||
|
+ union {
|
||||||
|
+ void *upt;
|
||||||
|
+ char dummy[256];
|
||||||
|
+ };
|
||||||
|
+ struct kpatch_coro *coro;
|
||||||
|
+};
|
||||||
|
+int _UCORO_access_reg(unw_addr_space_t as, unw_regnum_t reg,
|
||||||
|
+ unw_word_t *val, int write, void *arg);
|
||||||
|
+
|
||||||
|
int kpatch_coroutines_init(struct kpatch_process *proc);
|
||||||
|
int kpatch_coroutines_find(struct kpatch_process *proc);
|
||||||
|
void kpatch_coroutines_free(struct kpatch_process *proc);
|
||||||
|
diff --git a/src/kpatch_coro.c b/src/kpatch_coro.c
|
||||||
|
index 02d421b..83d04ce 100644
|
||||||
|
--- a/src/kpatch_coro.c
|
||||||
|
+++ b/src/kpatch_coro.c
|
||||||
|
@@ -6,8 +6,6 @@
|
||||||
|
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
|
||||||
|
-#include <asm/prctl.h>
|
||||||
|
-
|
||||||
|
#include "include/kpatch_user.h"
|
||||||
|
#include "include/kpatch_coro.h"
|
||||||
|
#include "include/kpatch_common.h"
|
||||||
|
@@ -505,13 +503,6 @@ static struct kpatch_coro_ops kpatch_coro_flavours[] = {
|
||||||
|
*
|
||||||
|
* That's why I had to do this hack
|
||||||
|
*/
|
||||||
|
-struct UCORO_info {
|
||||||
|
- union {
|
||||||
|
- void *upt;
|
||||||
|
- char dummy[256];
|
||||||
|
- };
|
||||||
|
- struct kpatch_coro *coro;
|
||||||
|
-};
|
||||||
|
|
||||||
|
void *_UCORO_create(struct kpatch_coro *coro, pid_t pid)
|
||||||
|
{
|
||||||
|
@@ -538,34 +529,6 @@ void _UCORO_destroy(void *arg)
|
||||||
|
_UPT_destroy(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int
|
||||||
|
-_UCORO_access_reg(unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val,
|
||||||
|
- int write, void *arg)
|
||||||
|
-{
|
||||||
|
- struct UCORO_info *info = (struct UCORO_info *)arg;
|
||||||
|
- unsigned long *regs = (unsigned long *)info->coro->env[0].__jmpbuf;
|
||||||
|
-
|
||||||
|
- if (write) {
|
||||||
|
- kperr("_UCORO_access_reg: write is not implemeneted (%d)\n", reg);
|
||||||
|
- return -UNW_EINVAL;
|
||||||
|
- }
|
||||||
|
- switch (reg) {
|
||||||
|
- case UNW_X86_64_RBX:
|
||||||
|
- *val = regs[JB_RBX]; break;
|
||||||
|
- case UNW_X86_64_RBP:
|
||||||
|
- *val = regs[JB_RBP]; break;
|
||||||
|
- case UNW_X86_64_R12...UNW_X86_64_R15:
|
||||||
|
- *val = regs[reg - UNW_X86_64_R12 + JB_R12]; break;
|
||||||
|
- case UNW_X86_64_RSP:
|
||||||
|
- *val = regs[JB_RSP]; break;
|
||||||
|
- case UNW_X86_64_RIP:
|
||||||
|
- *val = regs[JB_RIP]; break;
|
||||||
|
- default:
|
||||||
|
- return _UPT_access_reg(as, reg, val, write, arg);
|
||||||
|
- }
|
||||||
|
- return 0;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static unw_accessors_t _UCORO_accessors = {
|
||||||
|
_UPT_find_proc_info,
|
||||||
|
_UPT_put_unwind_info,
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
148
0033-kpatch_coro-Split-function-get_ptr_guard.patch
Normal file
148
0033-kpatch_coro-Split-function-get_ptr_guard.patch
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
From 612e06f2fc95029c13cfdb684014259fb49f18fe Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Date: Mon, 12 Oct 2020 14:32:51 +0800
|
||||||
|
Subject: [PATCH 33/89] kpatch_coro: Split function get_ptr_guard
|
||||||
|
|
||||||
|
The function get_ptr_guard is arch related, so make two
|
||||||
|
separate definations in arch/x86/arch_coro.c and arch/aarch64/arch_coro.c
|
||||||
|
|
||||||
|
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||||
|
---
|
||||||
|
src/arch/aarch64/arch_coro.c | 24 ++++++++++++++++++++++++
|
||||||
|
src/arch/x86/arch_coro.c | 23 +++++++++++++++++++++++
|
||||||
|
src/include/kpatch_coro.h | 5 +++++
|
||||||
|
src/kpatch_coro.c | 25 -------------------------
|
||||||
|
4 files changed, 52 insertions(+), 25 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/arch/aarch64/arch_coro.c b/src/arch/aarch64/arch_coro.c
|
||||||
|
index e6fe3d0..b93581e 100644
|
||||||
|
--- a/src/arch/aarch64/arch_coro.c
|
||||||
|
+++ b/src/arch/aarch64/arch_coro.c
|
||||||
|
@@ -11,6 +11,30 @@
|
||||||
|
#include "include/kpatch_ptrace.h"
|
||||||
|
#include "include/kpatch_log.h"
|
||||||
|
|
||||||
|
+int get_ptr_guard(struct kpatch_process *proc,
|
||||||
|
+ unsigned long *ptr_guard)
|
||||||
|
+{
|
||||||
|
+ int ret;
|
||||||
|
+ unsigned long tls = 0;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ ret = kpatch_arch_prctl_remote(proc2pctx(proc), ARCH_GET_FS, &tls);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kpdebug("FAIL. Can't get TLS base value\n");
|
||||||
|
+ return -1;
|
||||||
|
+ }*/
|
||||||
|
+ ret = kpatch_process_mem_read(proc,
|
||||||
|
+ tls + GLIBC_TLS_PTR_GUARD,
|
||||||
|
+ ptr_guard,
|
||||||
|
+ sizeof(*ptr_guard));
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kpdebug("FAIL. Can't get pointer guard value\n");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int _UCORO_access_reg(unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val,
|
||||||
|
int write, void *arg)
|
||||||
|
{
|
||||||
|
diff --git a/src/arch/x86/arch_coro.c b/src/arch/x86/arch_coro.c
|
||||||
|
index ce889df..86bf12f 100644
|
||||||
|
--- a/src/arch/x86/arch_coro.c
|
||||||
|
+++ b/src/arch/x86/arch_coro.c
|
||||||
|
@@ -15,6 +15,29 @@
|
||||||
|
#include "include/kpatch_ptrace.h"
|
||||||
|
#include "include/kpatch_log.h"
|
||||||
|
|
||||||
|
+int get_ptr_guard(struct kpatch_process *proc,
|
||||||
|
+ unsigned long *ptr_guard)
|
||||||
|
+{
|
||||||
|
+ int ret;
|
||||||
|
+ unsigned long tls;
|
||||||
|
+
|
||||||
|
+ ret = kpatch_arch_prctl_remote(proc2pctx(proc), ARCH_GET_FS, &tls);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kpdebug("FAIL. Can't get TLS base value\n");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ ret = kpatch_process_mem_read(proc,
|
||||||
|
+ tls + GLIBC_TLS_PTR_GUARD,
|
||||||
|
+ ptr_guard,
|
||||||
|
+ sizeof(*ptr_guard));
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kpdebug("FAIL. Can't get pointer guard value\n");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int _UCORO_access_reg(unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val,
|
||||||
|
int write, void *arg)
|
||||||
|
{
|
||||||
|
diff --git a/src/include/kpatch_coro.h b/src/include/kpatch_coro.h
|
||||||
|
index 760b1db..272855e 100644
|
||||||
|
--- a/src/include/kpatch_coro.h
|
||||||
|
+++ b/src/include/kpatch_coro.h
|
||||||
|
@@ -30,6 +30,11 @@ struct UCORO_info {
|
||||||
|
int _UCORO_access_reg(unw_addr_space_t as, unw_regnum_t reg,
|
||||||
|
unw_word_t *val, int write, void *arg);
|
||||||
|
|
||||||
|
+#define GLIBC_TLS_PTR_GUARD 0x30
|
||||||
|
+int get_ptr_guard(struct kpatch_process *proc,
|
||||||
|
+ unsigned long *ptr_guard);
|
||||||
|
+
|
||||||
|
+
|
||||||
|
int kpatch_coroutines_init(struct kpatch_process *proc);
|
||||||
|
int kpatch_coroutines_find(struct kpatch_process *proc);
|
||||||
|
void kpatch_coroutines_free(struct kpatch_process *proc);
|
||||||
|
diff --git a/src/kpatch_coro.c b/src/kpatch_coro.c
|
||||||
|
index 83d04ce..ea4050f 100644
|
||||||
|
--- a/src/kpatch_coro.c
|
||||||
|
+++ b/src/kpatch_coro.c
|
||||||
|
@@ -105,8 +105,6 @@ kpatch_coro_free(struct kpatch_coro *c)
|
||||||
|
#define JB_RSP 6
|
||||||
|
#define JB_RIP 7
|
||||||
|
|
||||||
|
-#define GLIBC_TLS_PTR_GUARD 0x30
|
||||||
|
-
|
||||||
|
#define STACK_OFFSET_UC_LINK (2 * sizeof(long))
|
||||||
|
#define STACK_OFFSET_START_CONTEXT (3 * sizeof(long))
|
||||||
|
#define STACK_OFFSET_UC_LINK_PTR (4 * sizeof(long))
|
||||||
|
@@ -191,29 +189,6 @@ static int is_test_target(struct kpatch_process *proc,
|
||||||
|
return strcmp(proc->comm, procname) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int get_ptr_guard(struct kpatch_process *proc,
|
||||||
|
- unsigned long *ptr_guard)
|
||||||
|
-{
|
||||||
|
- int ret;
|
||||||
|
- unsigned long tls;
|
||||||
|
-
|
||||||
|
- ret = kpatch_arch_prctl_remote(proc2pctx(proc), ARCH_GET_FS, &tls);
|
||||||
|
- if (ret < 0) {
|
||||||
|
- kpdebug("FAIL. Can't get TLS base value\n");
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
- ret = kpatch_process_mem_read(proc,
|
||||||
|
- tls + GLIBC_TLS_PTR_GUARD,
|
||||||
|
- ptr_guard,
|
||||||
|
- sizeof(*ptr_guard));
|
||||||
|
- if (ret < 0) {
|
||||||
|
- kpdebug("FAIL. Can't get pointer guard value\n");
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- return 0;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
int is_centos7_qemu(struct kpatch_process *proc)
|
||||||
|
{
|
||||||
|
struct utsname uts;
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
307
0034-kpatch_coro-Split-function-locate_start_context_symb.patch
Normal file
307
0034-kpatch_coro-Split-function-locate_start_context_symb.patch
Normal file
@ -0,0 +1,307 @@
|
|||||||
|
From 9ac8822b66bb06a463a29ec86088cfe8adc1e6d4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Date: Mon, 12 Oct 2020 14:45:03 +0800
|
||||||
|
Subject: [PATCH 34/89] kpatch_coro: Split function locate_start_context_symbol
|
||||||
|
|
||||||
|
The function locate_start_context_symbol is arch related, so let's
|
||||||
|
make two separate definations in arch/x86/arch_coro.c and
|
||||||
|
arch/aarch64/arch_coro.c
|
||||||
|
|
||||||
|
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||||
|
---
|
||||||
|
src/arch/aarch64/arch_coro.c | 63 ++++++++++++++++++++++++++
|
||||||
|
src/arch/x86/arch_coro.c | 67 +++++++++++++++++++++++++++
|
||||||
|
src/include/kpatch_coro.h | 21 +++++++++
|
||||||
|
src/kpatch_coro.c | 87 ------------------------------------
|
||||||
|
4 files changed, 151 insertions(+), 87 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/arch/aarch64/arch_coro.c b/src/arch/aarch64/arch_coro.c
|
||||||
|
index b93581e..f485cf9 100644
|
||||||
|
--- a/src/arch/aarch64/arch_coro.c
|
||||||
|
+++ b/src/arch/aarch64/arch_coro.c
|
||||||
|
@@ -11,6 +11,69 @@
|
||||||
|
#include "include/kpatch_ptrace.h"
|
||||||
|
#include "include/kpatch_log.h"
|
||||||
|
|
||||||
|
+asm (
|
||||||
|
+ "makecontext_call:\n"
|
||||||
|
+ "mov x29, sp\n"
|
||||||
|
+ "and x29,x29,#-16\n"
|
||||||
|
+ "sub x29, x29,#0x400\n"
|
||||||
|
+ "ldr x9,[x29,#-128]\n"
|
||||||
|
+ "str x9,[fp,#0x10]\n"
|
||||||
|
+ //"str #128,[fp.#0x20]\n"
|
||||||
|
+ "mov x0,fp\n"
|
||||||
|
+ "mov x1,#0x100\n"
|
||||||
|
+ "mov x2,#0\n"
|
||||||
|
+ "svc #0\n"
|
||||||
|
+ "brk #0\n"
|
||||||
|
+ "makecontext_call_end:"
|
||||||
|
+ );
|
||||||
|
+
|
||||||
|
+extern unsigned char makecontext_call, makecontext_call_end;
|
||||||
|
+
|
||||||
|
+int
|
||||||
|
+locate_start_context_symbol(struct kpatch_process *proc,
|
||||||
|
+ unsigned long *pstart_context)
|
||||||
|
+{
|
||||||
|
+ struct object_file *olibc;
|
||||||
|
+ struct user_regs_struct regs;
|
||||||
|
+ int rv;
|
||||||
|
+ unsigned long makecontext;
|
||||||
|
+
|
||||||
|
+ olibc = kpatch_process_get_obj_by_regex(proc, "^libc-.*\\.so");
|
||||||
|
+ if (olibc == NULL) {
|
||||||
|
+ kpdebug("FAIL. Can't find libc\n");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ rv = kpatch_resolve_undefined_single_dynamic(olibc,
|
||||||
|
+ "makecontext",
|
||||||
|
+ &makecontext);
|
||||||
|
+ makecontext = vaddr2addr(olibc, makecontext);
|
||||||
|
+ if (rv < 0 || makecontext == 0) {
|
||||||
|
+ kpdebug("FAIL. Can't find makecontext\n");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ regs.regs[8] = makecontext;
|
||||||
|
+ rv = kpatch_execute_remote(proc2pctx(proc),
|
||||||
|
+ &makecontext_call,
|
||||||
|
+ &makecontext_call_end - &makecontext_call,
|
||||||
|
+ ®s);
|
||||||
|
+ if (rv < 0) {
|
||||||
|
+ kpdebug("FAIL. Can't execute makecontext\n");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ rv = kpatch_process_mem_read(proc,
|
||||||
|
+ regs.regs[29]- STACK_OFFSET_START_CONTEXT,
|
||||||
|
+ pstart_context,
|
||||||
|
+ sizeof(*pstart_context));
|
||||||
|
+ if (rv < 0) {
|
||||||
|
+ kpdebug("FAIL. Can't peek __start_context address\n");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ return rv;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int get_ptr_guard(struct kpatch_process *proc,
|
||||||
|
unsigned long *ptr_guard)
|
||||||
|
{
|
||||||
|
diff --git a/src/arch/x86/arch_coro.c b/src/arch/x86/arch_coro.c
|
||||||
|
index 86bf12f..27c834b 100644
|
||||||
|
--- a/src/arch/x86/arch_coro.c
|
||||||
|
+++ b/src/arch/x86/arch_coro.c
|
||||||
|
@@ -15,6 +15,73 @@
|
||||||
|
#include "include/kpatch_ptrace.h"
|
||||||
|
#include "include/kpatch_log.h"
|
||||||
|
|
||||||
|
+asm ("makecontext_call:\n"
|
||||||
|
+ "mov %rsp, %rbp\n"
|
||||||
|
+ "and $-16, %rbp\n"
|
||||||
|
+ /* ucontext_t is 0x3a8 bytes */
|
||||||
|
+ "sub $0x400, %rbp\n"
|
||||||
|
+ /* TODO interpolate these from the calculations above */
|
||||||
|
+
|
||||||
|
+ /* set uc_stack.ss_sp and uc_stack.ss_size */
|
||||||
|
+ /* TODO magic -128 is used below as well */
|
||||||
|
+ "lea -128(%rbp), %rbx\n"
|
||||||
|
+ "movq %rbx, 0x10(%rbp)\n"
|
||||||
|
+ "movq $128, 0x20(%rbp)\n"
|
||||||
|
+ "mov %rbp, %rdi\n"
|
||||||
|
+ "mov $0x100, %rsi\n"
|
||||||
|
+ "xor %rdx, %rdx\n"
|
||||||
|
+ /* call `makecontext` */
|
||||||
|
+ "call *%rax\n"
|
||||||
|
+ "int3\n"
|
||||||
|
+ "makecontext_call_end:");
|
||||||
|
+
|
||||||
|
+extern unsigned char makecontext_call, makecontext_call_end;
|
||||||
|
+
|
||||||
|
+int
|
||||||
|
+locate_start_context_symbol(struct kpatch_process *proc,
|
||||||
|
+ unsigned long *pstart_context)
|
||||||
|
+{
|
||||||
|
+ struct object_file *olibc;
|
||||||
|
+ struct user_regs_struct regs;
|
||||||
|
+ int rv;
|
||||||
|
+ unsigned long makecontext;
|
||||||
|
+
|
||||||
|
+ olibc = kpatch_process_get_obj_by_regex(proc, "^libc-.*\\.so");
|
||||||
|
+ if (olibc == NULL) {
|
||||||
|
+ kpdebug("FAIL. Can't find libc\n");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ rv = kpatch_resolve_undefined_single_dynamic(olibc,
|
||||||
|
+ "makecontext",
|
||||||
|
+ &makecontext);
|
||||||
|
+ makecontext = vaddr2addr(olibc, makecontext);
|
||||||
|
+ if (rv < 0 || makecontext == 0) {
|
||||||
|
+ kpdebug("FAIL. Can't find makecontext\n");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ regs.rax = makecontext;
|
||||||
|
+ rv = kpatch_execute_remote(proc2pctx(proc),
|
||||||
|
+ &makecontext_call,
|
||||||
|
+ &makecontext_call_end - &makecontext_call,
|
||||||
|
+ ®s);
|
||||||
|
+ if (rv < 0) {
|
||||||
|
+ kpdebug("FAIL. Can't execute makecontext\n");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ rv = kpatch_process_mem_read(proc,
|
||||||
|
+ regs.rbp - STACK_OFFSET_START_CONTEXT,
|
||||||
|
+ pstart_context,
|
||||||
|
+ sizeof(*pstart_context));
|
||||||
|
+ if (rv < 0) {
|
||||||
|
+ kpdebug("FAIL. Can't peek __start_context address\n");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ return rv;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int get_ptr_guard(struct kpatch_process *proc,
|
||||||
|
unsigned long *ptr_guard)
|
||||||
|
{
|
||||||
|
diff --git a/src/include/kpatch_coro.h b/src/include/kpatch_coro.h
|
||||||
|
index 272855e..0b3a9a1 100644
|
||||||
|
--- a/src/include/kpatch_coro.h
|
||||||
|
+++ b/src/include/kpatch_coro.h
|
||||||
|
@@ -30,10 +30,31 @@ struct UCORO_info {
|
||||||
|
int _UCORO_access_reg(unw_addr_space_t as, unw_regnum_t reg,
|
||||||
|
unw_word_t *val, int write, void *arg);
|
||||||
|
|
||||||
|
+#define PTR_DEMANGLE(ptr, key) ((((ptr) >> 0x11) | ((ptr) << 47)) ^ key)
|
||||||
|
+#define JB_RBX 0
|
||||||
|
+#define JB_RBP 1
|
||||||
|
+#define JB_R12 2
|
||||||
|
+#define JB_R13 3
|
||||||
|
+#define JB_R14 4
|
||||||
|
+#define JB_R15 5
|
||||||
|
+#define JB_RSP 6
|
||||||
|
+#define JB_RIP 7
|
||||||
|
+
|
||||||
|
+#define STACK_OFFSET_UC_LINK (2 * sizeof(long))
|
||||||
|
+#define STACK_OFFSET_START_CONTEXT (3 * sizeof(long))
|
||||||
|
+#define STACK_OFFSET_UC_LINK_PTR (4 * sizeof(long))
|
||||||
|
+#define STACK_OFFSET_COROUTINE_UCONTEXT (7 * sizeof(long))
|
||||||
|
+#define STACK_OFFSET_COROUTINE (8 * sizeof(long))
|
||||||
|
+
|
||||||
|
+#define UCONTEXT_OFFSET_JMPBUF 0x38
|
||||||
|
+
|
||||||
|
#define GLIBC_TLS_PTR_GUARD 0x30
|
||||||
|
int get_ptr_guard(struct kpatch_process *proc,
|
||||||
|
unsigned long *ptr_guard);
|
||||||
|
|
||||||
|
+int locate_start_context_symbol(struct kpatch_process *proc,
|
||||||
|
+ unsigned long *pstart_context);
|
||||||
|
+
|
||||||
|
|
||||||
|
int kpatch_coroutines_init(struct kpatch_process *proc);
|
||||||
|
int kpatch_coroutines_find(struct kpatch_process *proc);
|
||||||
|
diff --git a/src/kpatch_coro.c b/src/kpatch_coro.c
|
||||||
|
index ea4050f..8457800 100644
|
||||||
|
--- a/src/kpatch_coro.c
|
||||||
|
+++ b/src/kpatch_coro.c
|
||||||
|
@@ -95,93 +95,6 @@ kpatch_coro_free(struct kpatch_coro *c)
|
||||||
|
* some kind of persistency (to allow kernelcare updates). This
|
||||||
|
* service also can listen to netlink events about new processes.
|
||||||
|
*/
|
||||||
|
-#define PTR_DEMANGLE(ptr, key) ((((ptr) >> 0x11) | ((ptr) << 47)) ^ key)
|
||||||
|
-#define JB_RBX 0
|
||||||
|
-#define JB_RBP 1
|
||||||
|
-#define JB_R12 2
|
||||||
|
-#define JB_R13 3
|
||||||
|
-#define JB_R14 4
|
||||||
|
-#define JB_R15 5
|
||||||
|
-#define JB_RSP 6
|
||||||
|
-#define JB_RIP 7
|
||||||
|
-
|
||||||
|
-#define STACK_OFFSET_UC_LINK (2 * sizeof(long))
|
||||||
|
-#define STACK_OFFSET_START_CONTEXT (3 * sizeof(long))
|
||||||
|
-#define STACK_OFFSET_UC_LINK_PTR (4 * sizeof(long))
|
||||||
|
-#define STACK_OFFSET_COROUTINE_UCONTEXT (7 * sizeof(long))
|
||||||
|
-#define STACK_OFFSET_COROUTINE (8 * sizeof(long))
|
||||||
|
-
|
||||||
|
-#define UCONTEXT_OFFSET_JMPBUF 0x38
|
||||||
|
-
|
||||||
|
-#define UCONTEXT_OFFSET_UC_STACK_SS_SP offsetof(ucontext_t, uc_stack.ss_sp)
|
||||||
|
-#define UCONTEXT_OFFSET_UC_STACK_SS_SIZE offsetof(ucontext_t, uc_stack.ss_size)
|
||||||
|
-
|
||||||
|
-asm ("makecontext_call:\n"
|
||||||
|
- "mov %rsp, %rbp\n"
|
||||||
|
- "and $-16, %rbp\n"
|
||||||
|
- /* ucontext_t is 0x3a8 bytes */
|
||||||
|
- "sub $0x400, %rbp\n"
|
||||||
|
- /* TODO interpolate these from the calculations above */
|
||||||
|
-
|
||||||
|
- /* set uc_stack.ss_sp and uc_stack.ss_size */
|
||||||
|
- /* TODO magic -128 is used below as well */
|
||||||
|
- "lea -128(%rbp), %rbx\n"
|
||||||
|
- "movq %rbx, 0x10(%rbp)\n"
|
||||||
|
- "movq $128, 0x20(%rbp)\n"
|
||||||
|
- "mov %rbp, %rdi\n"
|
||||||
|
- "mov $0x100, %rsi\n"
|
||||||
|
- "xor %rdx, %rdx\n"
|
||||||
|
- /* call `makecontext` */
|
||||||
|
- "call *%rax\n"
|
||||||
|
- "int3\n"
|
||||||
|
- "makecontext_call_end:");
|
||||||
|
-
|
||||||
|
-extern unsigned char makecontext_call, makecontext_call_end;
|
||||||
|
-
|
||||||
|
-static int
|
||||||
|
-locate_start_context_symbol(struct kpatch_process *proc,
|
||||||
|
- unsigned long *pstart_context)
|
||||||
|
-{
|
||||||
|
- struct object_file *olibc;
|
||||||
|
- struct user_regs_struct regs;
|
||||||
|
- int rv;
|
||||||
|
- unsigned long makecontext;
|
||||||
|
-
|
||||||
|
- olibc = kpatch_process_get_obj_by_regex(proc, "^libc-.*\\.so");
|
||||||
|
- if (olibc == NULL) {
|
||||||
|
- kpdebug("FAIL. Can't find libc\n");
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- rv = kpatch_resolve_undefined_single_dynamic(olibc,
|
||||||
|
- "makecontext",
|
||||||
|
- &makecontext);
|
||||||
|
- makecontext = vaddr2addr(olibc, makecontext);
|
||||||
|
- if (rv < 0 || makecontext == 0) {
|
||||||
|
- kpdebug("FAIL. Can't find makecontext\n");
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- regs.rax = makecontext;
|
||||||
|
- rv = kpatch_execute_remote(proc2pctx(proc),
|
||||||
|
- &makecontext_call,
|
||||||
|
- &makecontext_call_end - &makecontext_call,
|
||||||
|
- ®s);
|
||||||
|
- if (rv < 0) {
|
||||||
|
- kpdebug("FAIL. Can't execute makecontext\n");
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- rv = kpatch_process_mem_read(proc,
|
||||||
|
- regs.rbp - STACK_OFFSET_START_CONTEXT,
|
||||||
|
- pstart_context,
|
||||||
|
- sizeof(*pstart_context));
|
||||||
|
- if (rv < 0) {
|
||||||
|
- kpdebug("FAIL. Can't peek __start_context address\n");
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
- return rv;
|
||||||
|
-}
|
||||||
|
|
||||||
|
static int is_test_target(struct kpatch_process *proc,
|
||||||
|
const char *procname)
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
237
0035-kpatch_patch-Split-function-patch_apply_hunk.patch
Normal file
237
0035-kpatch_patch-Split-function-patch_apply_hunk.patch
Normal file
@ -0,0 +1,237 @@
|
|||||||
|
From 4f165eacd6d1d64cc43a58dd54e35017663d99e2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Date: Mon, 12 Oct 2020 14:58:18 +0800
|
||||||
|
Subject: [PATCH 35/89] kpatch_patch: Split function patch_apply_hunk
|
||||||
|
|
||||||
|
The function patch_apply_hunk is arch related, so make two
|
||||||
|
separate definations in arch/x86/arch_patch.c and arch/aarch64/arch_patch.c
|
||||||
|
|
||||||
|
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||||
|
---
|
||||||
|
src/arch/aarch64/arch_patch.c | 68 +++++++++++++++++++++++++++++++++++
|
||||||
|
src/arch/x86/arch_patch.c | 66 ++++++++++++++++++++++++++++++++++
|
||||||
|
src/include/kpatch_patch.h | 2 ++
|
||||||
|
src/kpatch_patch.c | 44 ++---------------------
|
||||||
|
4 files changed, 139 insertions(+), 41 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/arch/aarch64/arch_patch.c b/src/arch/aarch64/arch_patch.c
|
||||||
|
index e69de29..9102621 100644
|
||||||
|
--- a/src/arch/aarch64/arch_patch.c
|
||||||
|
+++ b/src/arch/aarch64/arch_patch.c
|
||||||
|
@@ -0,0 +1,68 @@
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <ctype.h>
|
||||||
|
+#include <unistd.h>
|
||||||
|
+#include <errno.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <sys/fcntl.h>
|
||||||
|
+#include <gelf.h>
|
||||||
|
+#include <libunwind.h>
|
||||||
|
+#include <libunwind-ptrace.h>
|
||||||
|
+#include "include/kpatch_patch.h"
|
||||||
|
+#include "include/kpatch_user.h"
|
||||||
|
+#include "include/kpatch_storage.h"
|
||||||
|
+#include "include/kpatch_process.h"
|
||||||
|
+#include "include/kpatch_file.h"
|
||||||
|
+#include "include/kpatch_common.h"
|
||||||
|
+#include "include/kpatch_elf.h"
|
||||||
|
+#include "include/kpatch_ptrace.h"
|
||||||
|
+#include "include/list.h"
|
||||||
|
+#include "include/kpatch_log.h"
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * Patch application subroutines
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+/*
|
||||||
|
+ * This flag is local, i.e. it is never stored to the
|
||||||
|
+ * patch applied to patient's memory.
|
||||||
|
+ */
|
||||||
|
+int PATCH_APPLIED = (1 << 31);
|
||||||
|
+int HUNK_SIZE = 4;
|
||||||
|
+
|
||||||
|
+int patch_apply_hunk(struct object_file *o, size_t nhunk)
|
||||||
|
+{
|
||||||
|
+ int ret;
|
||||||
|
+ unsigned char code[] = {0x00, 0x00, 0x00, 0x00}; /* ins: b IMM */
|
||||||
|
+ struct kpatch_info *info = &o->info[nhunk];
|
||||||
|
+ unsigned long pundo;
|
||||||
|
+
|
||||||
|
+ if (is_new_func(info))
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ pundo = o->kpta + o->kpfile.patch->user_undo + nhunk * HUNK_SIZE;
|
||||||
|
+ kpinfo("%s origcode from 0x%lx+0x%x to 0x%lx\n",
|
||||||
|
+ o->name, info->daddr, HUNK_SIZE, pundo);
|
||||||
|
+ ret = kpatch_process_memcpy(o->proc, pundo,
|
||||||
|
+ info->daddr, HUNK_SIZE);
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ kpinfo("%s hunk 0x%lx+0x%x -> 0x%lx+0x%x\n",
|
||||||
|
+ o->name, info->daddr, info->dlen, info->saddr, info->slen);
|
||||||
|
+
|
||||||
|
+ *(unsigned int *)(code) = (unsigned int)(info->saddr - info->daddr) / 4;
|
||||||
|
+ code[3] &= 0x3;
|
||||||
|
+ code[3] |= 0x14;
|
||||||
|
+
|
||||||
|
+ ret = kpatch_process_mem_write(o->proc,
|
||||||
|
+ code,
|
||||||
|
+ info->daddr,
|
||||||
|
+ sizeof(code));
|
||||||
|
+ /*
|
||||||
|
+ * NOTE(pboldin): This is only stored locally, as information have
|
||||||
|
+ * been copied to patient's memory already.
|
||||||
|
+ */
|
||||||
|
+ info->flags |= PATCH_APPLIED;
|
||||||
|
+ return ret ? -1 : 0;
|
||||||
|
+}
|
||||||
|
diff --git a/src/arch/x86/arch_patch.c b/src/arch/x86/arch_patch.c
|
||||||
|
index e69de29..a6e794d 100644
|
||||||
|
--- a/src/arch/x86/arch_patch.c
|
||||||
|
+++ b/src/arch/x86/arch_patch.c
|
||||||
|
@@ -0,0 +1,66 @@
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <ctype.h>
|
||||||
|
+#include <unistd.h>
|
||||||
|
+#include <errno.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <sys/fcntl.h>
|
||||||
|
+
|
||||||
|
+#include <gelf.h>
|
||||||
|
+#include <libunwind.h>
|
||||||
|
+#include <libunwind-ptrace.h>
|
||||||
|
+
|
||||||
|
+#include "include/kpatch_patch.h"
|
||||||
|
+#include "include/kpatch_user.h"
|
||||||
|
+#include "include/kpatch_storage.h"
|
||||||
|
+#include "include/kpatch_process.h"
|
||||||
|
+#include "include/kpatch_file.h"
|
||||||
|
+#include "include/kpatch_common.h"
|
||||||
|
+#include "include/kpatch_elf.h"
|
||||||
|
+#include "include/kpatch_ptrace.h"
|
||||||
|
+#include "include/list.h"
|
||||||
|
+#include "include/kpatch_log.h"
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * Patch application subroutines
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+/*
|
||||||
|
+ * This flag is local, i.e. it is never stored to the
|
||||||
|
+ * patch applied to patient's memory.
|
||||||
|
+ */
|
||||||
|
+int PATCH_APPLIED = (1 << 31);
|
||||||
|
+int HUNK_SIZE = 5;
|
||||||
|
+
|
||||||
|
+int patch_apply_hunk(struct object_file *o, size_t nhunk)
|
||||||
|
+{
|
||||||
|
+ int ret;
|
||||||
|
+ char code[] = {0xe9, 0x00, 0x00, 0x00, 0x00}; /* jmp IMM */
|
||||||
|
+ struct kpatch_info *info = &o->info[nhunk];
|
||||||
|
+ unsigned long pundo;
|
||||||
|
+
|
||||||
|
+ if (is_new_func(info))
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ pundo = o->kpta + o->kpfile.patch->user_undo + nhunk * HUNK_SIZE;
|
||||||
|
+ kpinfo("%s origcode from 0x%lx+0x%x to 0x%lx\n",
|
||||||
|
+ o->name, info->daddr, HUNK_SIZE, pundo);
|
||||||
|
+ ret = kpatch_process_memcpy(o->proc, pundo,
|
||||||
|
+ info->daddr, HUNK_SIZE);
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ kpinfo("%s hunk 0x%lx+0x%x -> 0x%lx+0x%x\n",
|
||||||
|
+ o->name, info->daddr, info->dlen, info->saddr, info->slen);
|
||||||
|
+ *(unsigned int *)(code + 1) = (unsigned int)(info->saddr - info->daddr - 5);
|
||||||
|
+ ret = kpatch_process_mem_write(o->proc,
|
||||||
|
+ code,
|
||||||
|
+ info->daddr,
|
||||||
|
+ sizeof(code));
|
||||||
|
+ /*
|
||||||
|
+ * NOTE(pboldin): This is only stored locally, as information have
|
||||||
|
+ * been copied to patient's memory already.
|
||||||
|
+ */
|
||||||
|
+ info->flags |= PATCH_APPLIED;
|
||||||
|
+ return ret ? -1 : 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
diff --git a/src/include/kpatch_patch.h b/src/include/kpatch_patch.h
|
||||||
|
index 44806ab..fa96b08 100644
|
||||||
|
--- a/src/include/kpatch_patch.h
|
||||||
|
+++ b/src/include/kpatch_patch.h
|
||||||
|
@@ -25,4 +25,6 @@ struct unpatch_data {
|
||||||
|
int process_patch(int pid, void *_data);
|
||||||
|
int process_unpatch(int pid, void *_data);
|
||||||
|
|
||||||
|
+int patch_apply_hunk(struct object_file *o, size_t nhunk);
|
||||||
|
+
|
||||||
|
#endif
|
||||||
|
diff --git a/src/kpatch_patch.c b/src/kpatch_patch.c
|
||||||
|
index 21a160a..4a1d149 100644
|
||||||
|
--- a/src/kpatch_patch.c
|
||||||
|
+++ b/src/kpatch_patch.c
|
||||||
|
@@ -270,47 +270,6 @@ patch_ensure_safety(struct object_file *o,
|
||||||
|
/*****************************************************************************
|
||||||
|
* Patch application subroutines
|
||||||
|
****************************************************************************/
|
||||||
|
-/*
|
||||||
|
- * This flag is local, i.e. it is never stored to the
|
||||||
|
- * patch applied to patient's memory.
|
||||||
|
- */
|
||||||
|
-#define PATCH_APPLIED (1 << 31)
|
||||||
|
-
|
||||||
|
-#define HUNK_SIZE 5
|
||||||
|
-
|
||||||
|
-static int
|
||||||
|
-patch_apply_hunk(struct object_file *o, size_t nhunk)
|
||||||
|
-{
|
||||||
|
- int ret;
|
||||||
|
- char code[HUNK_SIZE] = {0xe9, 0x00, 0x00, 0x00, 0x00}; /* jmp IMM */
|
||||||
|
- struct kpatch_info *info = &o->info[nhunk];
|
||||||
|
- unsigned long pundo;
|
||||||
|
-
|
||||||
|
- if (is_new_func(info))
|
||||||
|
- return 0;
|
||||||
|
-
|
||||||
|
- pundo = o->kpta + o->kpfile.patch->user_undo + nhunk * HUNK_SIZE;
|
||||||
|
- kpinfo("%s origcode from 0x%lx+0x%x to 0x%lx\n",
|
||||||
|
- o->name, info->daddr, HUNK_SIZE, pundo);
|
||||||
|
- ret = kpatch_process_memcpy(o->proc, pundo,
|
||||||
|
- info->daddr, HUNK_SIZE);
|
||||||
|
- if (ret < 0)
|
||||||
|
- return ret;
|
||||||
|
-
|
||||||
|
- kpinfo("%s hunk 0x%lx+0x%x -> 0x%lx+0x%x\n",
|
||||||
|
- o->name, info->daddr, info->dlen, info->saddr, info->slen);
|
||||||
|
- *(unsigned int *)(code + 1) = (unsigned int)(info->saddr - info->daddr - 5);
|
||||||
|
- ret = kpatch_process_mem_write(o->proc,
|
||||||
|
- code,
|
||||||
|
- info->daddr,
|
||||||
|
- sizeof(code));
|
||||||
|
- /*
|
||||||
|
- * NOTE(pboldin): This is only stored locally, as information have
|
||||||
|
- * been copied to patient's memory already.
|
||||||
|
- */
|
||||||
|
- info->flags |= PATCH_APPLIED;
|
||||||
|
- return ret ? -1 : 0;
|
||||||
|
-}
|
||||||
|
|
||||||
|
static int
|
||||||
|
duplicate_kp_file(struct object_file *o)
|
||||||
|
@@ -328,6 +287,9 @@ duplicate_kp_file(struct object_file *o)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+extern int PATCH_APPLIED;
|
||||||
|
+extern int HUNK_SIZE;
|
||||||
|
+
|
||||||
|
static int
|
||||||
|
object_apply_patch(struct object_file *o)
|
||||||
|
{
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
151
0036-kpatch_elf-Split-function-kpatch_add_jmp_entry.patch
Normal file
151
0036-kpatch_elf-Split-function-kpatch_add_jmp_entry.patch
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
From 3352c27078a63b5bfc6ff4df639489fdabfd4dbe Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Date: Mon, 12 Oct 2020 15:11:05 +0800
|
||||||
|
Subject: [PATCH 36/89] kpatch_elf: Split function kpatch_add_jmp_entry
|
||||||
|
|
||||||
|
The function kpatch_add_jmp_entry is arch related. To support multi-arch
|
||||||
|
let's rename it with kpatch_arch_add_jmp_entry, and make the defination in
|
||||||
|
arch/x86/arch_elf.c and arch/aarch64/arch_elf.c
|
||||||
|
|
||||||
|
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||||
|
---
|
||||||
|
src/arch/aarch64/arch_elf.c | 35 +++++++++++++++++++++++++++++++++++
|
||||||
|
src/arch/x86/arch_elf.c | 35 +++++++++++++++++++++++++++++++++++
|
||||||
|
src/include/kpatch_elf.h | 2 ++
|
||||||
|
src/kpatch_elf.c | 21 +--------------------
|
||||||
|
4 files changed, 73 insertions(+), 20 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/arch/aarch64/arch_elf.c b/src/arch/aarch64/arch_elf.c
|
||||||
|
index e69de29..b977489 100644
|
||||||
|
--- a/src/arch/aarch64/arch_elf.c
|
||||||
|
+++ b/src/arch/aarch64/arch_elf.c
|
||||||
|
@@ -0,0 +1,35 @@
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <unistd.h>
|
||||||
|
+#include <sys/mman.h>
|
||||||
|
+#include <limits.h>
|
||||||
|
+
|
||||||
|
+#include <gelf.h>
|
||||||
|
+
|
||||||
|
+#include "include/kpatch_common.h"
|
||||||
|
+#include "include/kpatch_user.h"
|
||||||
|
+#include "include/kpatch_process.h"
|
||||||
|
+#include "include/kpatch_elf.h"
|
||||||
|
+#include "include/kpatch_file.h"
|
||||||
|
+#include "include/kpatch_ptrace.h"
|
||||||
|
+#include "include/kpatch_log.h"
|
||||||
|
+
|
||||||
|
+#define JMP_TABLE_JUMP 0xd61f022058000051 /* ldr x17 #8; br x17 */
|
||||||
|
+unsigned long kpatch_arch_add_jmp_entry(struct object_file *o, unsigned long addr)
|
||||||
|
+{
|
||||||
|
+ struct kpatch_jmp_table_entry entry = {JMP_TABLE_JUMP, addr};
|
||||||
|
+ int e;
|
||||||
|
+
|
||||||
|
+ if (o->jmp_table == NULL) {
|
||||||
|
+ kpfatalerror("JMP TABLE not found\n");
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (o->jmp_table->cur_entry >= o->jmp_table->max_entry)
|
||||||
|
+ return 0;
|
||||||
|
+ e = o->jmp_table->cur_entry++;
|
||||||
|
+ o->jmp_table->entries[e] = entry;
|
||||||
|
+ return (unsigned long)(o->kpta + o->kpfile.patch->jmp_offset + \
|
||||||
|
+ ((void *)&o->jmp_table->entries[e] - (void *)o->jmp_table));
|
||||||
|
+}
|
||||||
|
diff --git a/src/arch/x86/arch_elf.c b/src/arch/x86/arch_elf.c
|
||||||
|
index e69de29..ef5564e 100644
|
||||||
|
--- a/src/arch/x86/arch_elf.c
|
||||||
|
+++ b/src/arch/x86/arch_elf.c
|
||||||
|
@@ -0,0 +1,35 @@
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <unistd.h>
|
||||||
|
+#include <sys/mman.h>
|
||||||
|
+#include <limits.h>
|
||||||
|
+
|
||||||
|
+#include <gelf.h>
|
||||||
|
+
|
||||||
|
+#include "include/kpatch_common.h"
|
||||||
|
+#include "include/kpatch_user.h"
|
||||||
|
+#include "include/kpatch_process.h"
|
||||||
|
+#include "include/kpatch_elf.h"
|
||||||
|
+#include "include/kpatch_file.h"
|
||||||
|
+#include "include/kpatch_ptrace.h"
|
||||||
|
+#include "include/kpatch_log.h"
|
||||||
|
+
|
||||||
|
+#define JMP_TABLE_JUMP 0x90900000000225ff /* jmp [rip+2]; nop; nop */
|
||||||
|
+unsigned long kpatch_arch_add_jmp_entry(struct object_file *o, unsigned long addr)
|
||||||
|
+{
|
||||||
|
+ struct kpatch_jmp_table_entry entry = {JMP_TABLE_JUMP, addr};
|
||||||
|
+ int e;
|
||||||
|
+
|
||||||
|
+ if (o->jmp_table == NULL) {
|
||||||
|
+ kpfatalerror("JMP TABLE not found\n");
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (o->jmp_table->cur_entry >= o->jmp_table->max_entry)
|
||||||
|
+ return 0;
|
||||||
|
+ e = o->jmp_table->cur_entry++;
|
||||||
|
+ o->jmp_table->entries[e] = entry;
|
||||||
|
+ return (unsigned long)(o->kpta + o->kpfile.patch->jmp_offset + \
|
||||||
|
+ ((void *)&o->jmp_table->entries[e] - (void *)o->jmp_table));
|
||||||
|
+}
|
||||||
|
diff --git a/src/include/kpatch_elf.h b/src/include/kpatch_elf.h
|
||||||
|
index 8c0a4a4..7e5d8c3 100644
|
||||||
|
--- a/src/include/kpatch_elf.h
|
||||||
|
+++ b/src/include/kpatch_elf.h
|
||||||
|
@@ -43,4 +43,6 @@ struct kpatch_jmp_table {
|
||||||
|
struct kpatch_jmp_table_entry entries[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
+unsigned long kpatch_arch_add_jmp_entry(struct object_file *o, unsigned long addr);
|
||||||
|
+
|
||||||
|
#endif
|
||||||
|
diff --git a/src/kpatch_elf.c b/src/kpatch_elf.c
|
||||||
|
index b1dfed0..21ba496 100644
|
||||||
|
--- a/src/kpatch_elf.c
|
||||||
|
+++ b/src/kpatch_elf.c
|
||||||
|
@@ -686,25 +686,6 @@ kpatch_resolve_undefined(struct object_file *obj,
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
-#define JMP_TABLE_JUMP 0x90900000000225ff /* jmp [rip+2]; nop; nop */
|
||||||
|
-static unsigned long kpatch_add_jmp_entry(struct object_file *o, unsigned long addr)
|
||||||
|
-{
|
||||||
|
- struct kpatch_jmp_table_entry entry = {JMP_TABLE_JUMP, addr};
|
||||||
|
- int e;
|
||||||
|
-
|
||||||
|
- if (o->jmp_table == NULL) {
|
||||||
|
- kpfatalerror("JMP TABLE not found\n");
|
||||||
|
- return 0;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (o->jmp_table->cur_entry >= o->jmp_table->max_entry)
|
||||||
|
- return 0;
|
||||||
|
- e = o->jmp_table->cur_entry++;
|
||||||
|
- o->jmp_table->entries[e] = entry;
|
||||||
|
- return (unsigned long)(o->kpta + o->kpfile.patch->jmp_offset + \
|
||||||
|
- ((void *)&o->jmp_table->entries[e] - (void *)o->jmp_table));
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static inline int
|
||||||
|
symbol_resolve(struct object_file *o,
|
||||||
|
GElf_Shdr *shdr,
|
||||||
|
@@ -737,7 +718,7 @@ symbol_resolve(struct object_file *o,
|
||||||
|
}
|
||||||
|
/* OK, we overuse st_size to store original offset */
|
||||||
|
s->st_size = uaddr;
|
||||||
|
- s->st_value = kpatch_add_jmp_entry(o, uaddr);
|
||||||
|
+ s->st_value = kpatch_arch_add_jmp_entry(o, uaddr);
|
||||||
|
|
||||||
|
kpdebug("symbol '%s' = 0x%lx\n",
|
||||||
|
symname, uaddr);
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
414
0037-kpatch_elf-Split-function-kpatch_apply_relocate_add.patch
Normal file
414
0037-kpatch_elf-Split-function-kpatch_apply_relocate_add.patch
Normal file
@ -0,0 +1,414 @@
|
|||||||
|
From 69837926282fc65d41be15390d9a125da97adc54 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Date: Mon, 12 Oct 2020 15:37:08 +0800
|
||||||
|
Subject: [PATCH 37/89] kpatch_elf: Split function kpatch_apply_relocate_add
|
||||||
|
|
||||||
|
The function kpatch_apply_relocate_add is arch related. To support multi-arch
|
||||||
|
let's rename it with kpatch_arch_apply_relocate_add, and make the defination
|
||||||
|
in arch/x86/arch_elf.c and arch/aarch64/arch_elf.c
|
||||||
|
|
||||||
|
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||||
|
---
|
||||||
|
src/arch/aarch64/arch_elf.c | 100 ++++++++++++++++++++++++++++++++++++
|
||||||
|
src/arch/x86/arch_elf.c | 89 ++++++++++++++++++++++++++++++++
|
||||||
|
src/include/bitops.h | 27 ++++++++++
|
||||||
|
src/include/kpatch_elf.h | 5 ++
|
||||||
|
src/kpatch_elf.c | 94 ++-------------------------------
|
||||||
|
5 files changed, 224 insertions(+), 91 deletions(-)
|
||||||
|
create mode 100644 src/include/bitops.h
|
||||||
|
|
||||||
|
diff --git a/src/arch/aarch64/arch_elf.c b/src/arch/aarch64/arch_elf.c
|
||||||
|
index b977489..deacb6f 100644
|
||||||
|
--- a/src/arch/aarch64/arch_elf.c
|
||||||
|
+++ b/src/arch/aarch64/arch_elf.c
|
||||||
|
@@ -14,6 +14,106 @@
|
||||||
|
#include "include/kpatch_file.h"
|
||||||
|
#include "include/kpatch_ptrace.h"
|
||||||
|
#include "include/kpatch_log.h"
|
||||||
|
+#include "include/bitops.h"
|
||||||
|
+
|
||||||
|
+static int kpatch_arch_apply_relocate(GElf_Rela *r, GElf_Sym *s,
|
||||||
|
+ void *loc, void *loc2, unsigned long val)
|
||||||
|
+{
|
||||||
|
+ switch (GELF_R_TYPE(r->r_info)) {
|
||||||
|
+ case R_AARCH64_ABS64:
|
||||||
|
+ *(unsigned long *)loc = val;
|
||||||
|
+ kpdebug("R_AARCH64_ABS64: loc=0x%x, val =0x%lx\n",*(unsigned int*)loc,val);
|
||||||
|
+ break;
|
||||||
|
+ case R_AARCH64_ADD_ABS_LO12_NC: {
|
||||||
|
+ //ADD ins
|
||||||
|
+ kpdebug("R_AARCH64_ADD_ABS_LO12_NC: val=0x%lx\n", val);
|
||||||
|
+ val = val & 0xfff;
|
||||||
|
+ uint32_t mask = 0xfff << 10;
|
||||||
|
+ *(unsigned int*)loc &= ~mask;
|
||||||
|
+ or_32(loc, (val & 0xfff) << 10);
|
||||||
|
+ kpdebug("R_AARCH64_ADD_ABS_LO12_NC: loc=0x%x, val =0x%lx\n",*(unsigned int*)loc,val);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ case R_AARCH64_CALL26: {
|
||||||
|
+ // TODO bl ins
|
||||||
|
+ kpdebug("R_AARCH64_CALL26: val=0x%lx\n", val);
|
||||||
|
+ val -= (unsigned long)loc2;
|
||||||
|
+ uint32_t mask = 0x03FFFFFF;;
|
||||||
|
+ *(unsigned int*)loc &= ~mask;
|
||||||
|
+ or_32(loc, (val >> 2) & mask);
|
||||||
|
+ kpdebug("R_AARCH64_CALL26: loc=0x%x, val =0x%lx\n",*(unsigned int*)loc, val);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ case R_AARCH64_ADR_PREL_PG_HI21: {
|
||||||
|
+ // TODO ADRP ins
|
||||||
|
+ kpdebug("RR_AARCH64_ADR_PREL_PG_HI21: val=0x%lx\n", val);
|
||||||
|
+ val = (val >> 12) - ((unsigned long)loc2 >> 12);
|
||||||
|
+ kpdebug("val=0x%lx\n",val);
|
||||||
|
+ uint32_t immLo = (val & 0x3) << 29;
|
||||||
|
+ uint32_t immHi = (val & 0x1FFFFC) << 3;
|
||||||
|
+ uint64_t mask = (0x3 << 29) | (0x1FFFFC << 3);
|
||||||
|
+ *(unsigned int*)loc = (*(unsigned int*)loc & ~mask) | immLo | immHi;
|
||||||
|
+ //*(unsigned int*)loc &= 0x7fffffff;
|
||||||
|
+ kpdebug("lo=0x%x hi=0x%x\n",immLo,immHi);
|
||||||
|
+ kpdebug("R_AARCH64_ADR_PREL_PG_HI21: loc=0x%x, val=0x%lx\n", *(unsigned int *)loc, val);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ default:
|
||||||
|
+ kperr("unknown relocation type: %lx\n", r->r_info);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int kpatch_arch_apply_relocate_add(struct object_file *o, GElf_Shdr *relsec)
|
||||||
|
+{
|
||||||
|
+ struct kpatch_file *kp = o->kpfile.patch;
|
||||||
|
+ GElf_Ehdr *ehdr = (void *)kp + kp->kpatch_offset;
|
||||||
|
+ GElf_Shdr *shdr = (void *)ehdr + ehdr->e_shoff, *symhdr;
|
||||||
|
+ GElf_Rela *relocs = (void *)ehdr + relsec->sh_offset;
|
||||||
|
+ GElf_Shdr *tshdr = shdr + relsec->sh_info;
|
||||||
|
+ void *t = (void *)ehdr + shdr[relsec->sh_info].sh_offset;
|
||||||
|
+ void *tshdr2 = (void *)shdr[relsec->sh_info].sh_addr;
|
||||||
|
+ int i, is_kpatch_info;
|
||||||
|
+ const char *scnname;
|
||||||
|
+
|
||||||
|
+ for (i = 1; i < ehdr->e_shnum; i++) {
|
||||||
|
+ if (shdr[i].sh_type == SHT_SYMTAB)
|
||||||
|
+ symhdr = &shdr[i];
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ scnname = secname(ehdr, shdr + relsec->sh_info);
|
||||||
|
+ kpdebug("applying relocations to '%s'\n", scnname);
|
||||||
|
+ is_kpatch_info = strcmp(scnname, ".kpatch.info") == 0;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < relsec->sh_size / sizeof(*relocs); i++) {
|
||||||
|
+ GElf_Rela *r = relocs + i;
|
||||||
|
+ GElf_Sym *s;
|
||||||
|
+ unsigned long val;
|
||||||
|
+ void *loc, *loc2;
|
||||||
|
+
|
||||||
|
+ if (r->r_offset < 0 || r->r_offset >= tshdr->sh_size)
|
||||||
|
+ kpfatalerror("Relocation offset for section '%s'"
|
||||||
|
+ " is at 0x%lx beyond the section size 0x%lx\n",
|
||||||
|
+ scnname, r->r_offset, tshdr->sh_size);
|
||||||
|
+
|
||||||
|
+ /* Location in our address space */
|
||||||
|
+ loc = t + r->r_offset;
|
||||||
|
+ /* Location in target process address space (for relative addressing) */
|
||||||
|
+ loc2 = tshdr2 + r->r_offset;
|
||||||
|
+ s = (GElf_Sym *)((void *)ehdr + symhdr->sh_offset) + GELF_R_SYM(r->r_info);
|
||||||
|
+ val = s->st_value + r->r_addend;
|
||||||
|
+
|
||||||
|
+ if (is_kpatch_info && is_undef_symbol(s)) {
|
||||||
|
+ val = s->st_size;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ kpatch_arch_apply_relocate(r, s, loc, loc2, val);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
|
||||||
|
#define JMP_TABLE_JUMP 0xd61f022058000051 /* ldr x17 #8; br x17 */
|
||||||
|
unsigned long kpatch_arch_add_jmp_entry(struct object_file *o, unsigned long addr)
|
||||||
|
diff --git a/src/arch/x86/arch_elf.c b/src/arch/x86/arch_elf.c
|
||||||
|
index ef5564e..52de117 100644
|
||||||
|
--- a/src/arch/x86/arch_elf.c
|
||||||
|
+++ b/src/arch/x86/arch_elf.c
|
||||||
|
@@ -15,6 +15,95 @@
|
||||||
|
#include "include/kpatch_ptrace.h"
|
||||||
|
#include "include/kpatch_log.h"
|
||||||
|
|
||||||
|
+int kpatch_arch_apply_relocate_add(struct object_file *o, GElf_Shdr *relsec)
|
||||||
|
+{
|
||||||
|
+ struct kpatch_file *kp = o->kpfile.patch;
|
||||||
|
+ GElf_Ehdr *ehdr = (void *)kp + kp->kpatch_offset;
|
||||||
|
+ GElf_Shdr *shdr = (void *)ehdr + ehdr->e_shoff, *symhdr;
|
||||||
|
+ GElf_Rela *relocs = (void *)ehdr + relsec->sh_offset;
|
||||||
|
+ GElf_Shdr *tshdr = shdr + relsec->sh_info;
|
||||||
|
+ void *t = (void *)ehdr + shdr[relsec->sh_info].sh_offset;
|
||||||
|
+ void *tshdr2 = (void *)shdr[relsec->sh_info].sh_addr;
|
||||||
|
+ int i, is_kpatch_info;
|
||||||
|
+ const char *scnname;
|
||||||
|
+
|
||||||
|
+ for (i = 1; i < ehdr->e_shnum; i++) {
|
||||||
|
+ if (shdr[i].sh_type == SHT_SYMTAB)
|
||||||
|
+ symhdr = &shdr[i];
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ scnname = secname(ehdr, shdr + relsec->sh_info);
|
||||||
|
+ kpdebug("applying relocations to '%s'\n", scnname);
|
||||||
|
+ is_kpatch_info = strcmp(scnname, ".kpatch.info") == 0;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < relsec->sh_size / sizeof(*relocs); i++) {
|
||||||
|
+ GElf_Rela *r = relocs + i;
|
||||||
|
+ GElf_Sym *s;
|
||||||
|
+ unsigned long val;
|
||||||
|
+ void *loc, *loc2;
|
||||||
|
+
|
||||||
|
+ if (r->r_offset < 0 || r->r_offset >= tshdr->sh_size)
|
||||||
|
+ kpfatalerror("Relocation offset for section '%s'"
|
||||||
|
+ " is at 0x%lx beyond the section size 0x%lx\n",
|
||||||
|
+ scnname, r->r_offset, tshdr->sh_size);
|
||||||
|
+
|
||||||
|
+ /* Location in our address space */
|
||||||
|
+ loc = t + r->r_offset;
|
||||||
|
+ /* Location in target process address space (for relative addressing) */
|
||||||
|
+ loc2 = tshdr2 + r->r_offset;
|
||||||
|
+ s = (GElf_Sym *)((void *)ehdr + symhdr->sh_offset) + GELF_R_SYM(r->r_info);
|
||||||
|
+ val = s->st_value + r->r_addend;
|
||||||
|
+
|
||||||
|
+ if (is_kpatch_info && is_undef_symbol(s)) {
|
||||||
|
+ val = s->st_size;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ switch (GELF_R_TYPE(r->r_info)) {
|
||||||
|
+ case R_X86_64_NONE:
|
||||||
|
+ break;
|
||||||
|
+ case R_X86_64_64:
|
||||||
|
+ *(unsigned long *)loc = val;
|
||||||
|
+ break;
|
||||||
|
+ case R_X86_64_32:
|
||||||
|
+ *(unsigned int *)loc = val;
|
||||||
|
+ break;
|
||||||
|
+ case R_X86_64_32S:
|
||||||
|
+ *(signed int *)loc = val;
|
||||||
|
+ break;
|
||||||
|
+ case R_X86_64_GOTTPOFF:
|
||||||
|
+ case R_X86_64_GOTPCREL:
|
||||||
|
+ case R_X86_64_REX_GOTPCRELX:
|
||||||
|
+ case R_X86_64_GOTPCRELX:
|
||||||
|
+ if (is_undef_symbol(s)) {
|
||||||
|
+ /* This is an undefined symbol,
|
||||||
|
+ * use jmp table as the GOT */
|
||||||
|
+ val += sizeof(unsigned long);
|
||||||
|
+ } else if (GELF_ST_TYPE(s->st_info) == STT_TLS) {
|
||||||
|
+ /* This is GOTTPOFF that already points
|
||||||
|
+ * to an appropriate GOT entry in the
|
||||||
|
+ * patient's memory.
|
||||||
|
+ */
|
||||||
|
+ val = r->r_addend + o->load_offset - 4;
|
||||||
|
+ }
|
||||||
|
+ /* FALLTHROUGH */
|
||||||
|
+ case R_X86_64_PC32:
|
||||||
|
+ val -= (unsigned long)loc2;
|
||||||
|
+ *(unsigned int *)loc = val;
|
||||||
|
+ break;
|
||||||
|
+ case R_X86_64_TPOFF64:
|
||||||
|
+ case R_X86_64_TPOFF32:
|
||||||
|
+ kperr("TPOFF32/TPOFF64 should not be present\n");
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ kperr("unknown relocation type: %lx\n", r->r_info);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
#define JMP_TABLE_JUMP 0x90900000000225ff /* jmp [rip+2]; nop; nop */
|
||||||
|
unsigned long kpatch_arch_add_jmp_entry(struct object_file *o, unsigned long addr)
|
||||||
|
{
|
||||||
|
diff --git a/src/include/bitops.h b/src/include/bitops.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..aab1679
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/include/bitops.h
|
||||||
|
@@ -0,0 +1,27 @@
|
||||||
|
+#ifndef BITOPS_H
|
||||||
|
+#define BITOPS_H
|
||||||
|
+
|
||||||
|
+#define BITS_PER_BYTE CHAR_BIT
|
||||||
|
+#define BITS_PER_LONG (sizeof (unsigned long) * BITS_PER_BYTE)
|
||||||
|
+
|
||||||
|
+#define BIT(nr) (1UL << (nr))
|
||||||
|
+#define BIT_ULL(nr) (1ULL << (nr))
|
||||||
|
+#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
|
||||||
|
+#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
|
||||||
|
+#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
|
||||||
|
+
|
||||||
|
+static inline void or_32(void *addr, unsigned int val)
|
||||||
|
+{
|
||||||
|
+ *(unsigned int*) addr = *(unsigned int*)addr | val;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline void or_64(void *addr, unsigned long val)
|
||||||
|
+{
|
||||||
|
+ *(unsigned long*) addr = *(unsigned long*)addr | val;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline void and_32(void *addr, unsigned int val)
|
||||||
|
+{
|
||||||
|
+ *(unsigned int*) addr = *(unsigned int*)addr & val;
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
diff --git a/src/include/kpatch_elf.h b/src/include/kpatch_elf.h
|
||||||
|
index 7e5d8c3..74efe04 100644
|
||||||
|
--- a/src/include/kpatch_elf.h
|
||||||
|
+++ b/src/include/kpatch_elf.h
|
||||||
|
@@ -1,6 +1,7 @@
|
||||||
|
#ifndef __KPATCH_ELF__
|
||||||
|
#define __KPATCH_ELF__
|
||||||
|
|
||||||
|
+#include <gelf.h>
|
||||||
|
#include "kpatch_process.h"
|
||||||
|
|
||||||
|
const char *kpatch_get_buildid(struct object_file *o);
|
||||||
|
@@ -45,4 +46,8 @@ struct kpatch_jmp_table {
|
||||||
|
|
||||||
|
unsigned long kpatch_arch_add_jmp_entry(struct object_file *o, unsigned long addr);
|
||||||
|
|
||||||
|
+char *secname(GElf_Ehdr *ehdr, GElf_Shdr *s);
|
||||||
|
+int is_undef_symbol(const Elf64_Sym *sym);
|
||||||
|
+int kpatch_arch_apply_relocate_add(struct object_file *o, GElf_Shdr *relsec);
|
||||||
|
+
|
||||||
|
#endif
|
||||||
|
diff --git a/src/kpatch_elf.c b/src/kpatch_elf.c
|
||||||
|
index 21ba496..5506292 100644
|
||||||
|
--- a/src/kpatch_elf.c
|
||||||
|
+++ b/src/kpatch_elf.c
|
||||||
|
@@ -410,7 +410,7 @@ out:
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static char *secname(GElf_Ehdr *ehdr, GElf_Shdr *s)
|
||||||
|
+char *secname(GElf_Ehdr *ehdr, GElf_Shdr *s)
|
||||||
|
{
|
||||||
|
GElf_Shdr *shdr = (void *)ehdr + ehdr->e_shoff;
|
||||||
|
char *str = (void *)ehdr + shdr[ehdr->e_shstrndx].sh_offset;
|
||||||
|
@@ -450,7 +450,7 @@ struct kpatch_jmp_table *kpatch_new_jmp_table(int entries)
|
||||||
|
return jtbl;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static inline int
|
||||||
|
+inline int
|
||||||
|
is_undef_symbol(const Elf64_Sym *sym)
|
||||||
|
{
|
||||||
|
return sym->st_shndx == SHN_UNDEF || sym->st_shndx >= SHN_LORESERVE;
|
||||||
|
@@ -805,94 +805,6 @@ int kpatch_resolve(struct object_file *o)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int kpatch_apply_relocate_add(struct object_file *o, GElf_Shdr *relsec)
|
||||||
|
-{
|
||||||
|
- struct kpatch_file *kp = o->kpfile.patch;
|
||||||
|
- GElf_Ehdr *ehdr = (void *)kp + kp->kpatch_offset;
|
||||||
|
- GElf_Shdr *shdr = (void *)ehdr + ehdr->e_shoff, *symhdr;
|
||||||
|
- GElf_Rela *relocs = (void *)ehdr + relsec->sh_offset;
|
||||||
|
- GElf_Shdr *tshdr = shdr + relsec->sh_info;
|
||||||
|
- void *t = (void *)ehdr + shdr[relsec->sh_info].sh_offset;
|
||||||
|
- void *tshdr2 = (void *)shdr[relsec->sh_info].sh_addr;
|
||||||
|
- int i, is_kpatch_info;
|
||||||
|
- const char *scnname;
|
||||||
|
-
|
||||||
|
- for (i = 1; i < ehdr->e_shnum; i++) {
|
||||||
|
- if (shdr[i].sh_type == SHT_SYMTAB)
|
||||||
|
- symhdr = &shdr[i];
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- scnname = secname(ehdr, shdr + relsec->sh_info);
|
||||||
|
- kpdebug("applying relocations to '%s'\n", scnname);
|
||||||
|
- is_kpatch_info = strcmp(scnname, ".kpatch.info") == 0;
|
||||||
|
-
|
||||||
|
- for (i = 0; i < relsec->sh_size / sizeof(*relocs); i++) {
|
||||||
|
- GElf_Rela *r = relocs + i;
|
||||||
|
- GElf_Sym *s;
|
||||||
|
- unsigned long val;
|
||||||
|
- void *loc, *loc2;
|
||||||
|
-
|
||||||
|
- if (r->r_offset < 0 || r->r_offset >= tshdr->sh_size)
|
||||||
|
- kpfatalerror("Relocation offset for section '%s'"
|
||||||
|
- " is at 0x%lx beyond the section size 0x%lx\n",
|
||||||
|
- scnname, r->r_offset, tshdr->sh_size);
|
||||||
|
-
|
||||||
|
- /* Location in our address space */
|
||||||
|
- loc = t + r->r_offset;
|
||||||
|
- /* Location in target process address space (for relative addressing) */
|
||||||
|
- loc2 = tshdr2 + r->r_offset;
|
||||||
|
- s = (GElf_Sym *)((void *)ehdr + symhdr->sh_offset) + GELF_R_SYM(r->r_info);
|
||||||
|
- val = s->st_value + r->r_addend;
|
||||||
|
-
|
||||||
|
- if (is_kpatch_info && is_undef_symbol(s)) {
|
||||||
|
- val = s->st_size;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- switch (GELF_R_TYPE(r->r_info)) {
|
||||||
|
- case R_X86_64_NONE:
|
||||||
|
- break;
|
||||||
|
- case R_X86_64_64:
|
||||||
|
- *(unsigned long *)loc = val;
|
||||||
|
- break;
|
||||||
|
- case R_X86_64_32:
|
||||||
|
- *(unsigned int *)loc = val;
|
||||||
|
- break;
|
||||||
|
- case R_X86_64_32S:
|
||||||
|
- *(signed int *)loc = val;
|
||||||
|
- break;
|
||||||
|
- case R_X86_64_GOTTPOFF:
|
||||||
|
- case R_X86_64_GOTPCREL:
|
||||||
|
- case R_X86_64_REX_GOTPCRELX:
|
||||||
|
- case R_X86_64_GOTPCRELX:
|
||||||
|
- if (is_undef_symbol(s)) {
|
||||||
|
- /* This is an undefined symbol,
|
||||||
|
- * use jmp table as the GOT */
|
||||||
|
- val += sizeof(unsigned long);
|
||||||
|
- } else if (GELF_ST_TYPE(s->st_info) == STT_TLS) {
|
||||||
|
- /* This is GOTTPOFF that already points
|
||||||
|
- * to an appropriate GOT entry in the
|
||||||
|
- * patient's memory.
|
||||||
|
- */
|
||||||
|
- val = r->r_addend + o->load_offset - 4;
|
||||||
|
- }
|
||||||
|
- /* FALLTHROUGH */
|
||||||
|
- case R_X86_64_PC32:
|
||||||
|
- val -= (unsigned long)loc2;
|
||||||
|
- *(unsigned int *)loc = val;
|
||||||
|
- break;
|
||||||
|
- case R_X86_64_TPOFF64:
|
||||||
|
- case R_X86_64_TPOFF32:
|
||||||
|
- kperr("TPOFF32/TPOFF64 should not be present\n");
|
||||||
|
- break;
|
||||||
|
- default:
|
||||||
|
- kperr("unknown relocation type: %lx\n", r->r_info);
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- return 0;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
int kpatch_relocate(struct object_file *o)
|
||||||
|
{
|
||||||
|
GElf_Ehdr *ehdr;
|
||||||
|
@@ -907,7 +819,7 @@ int kpatch_relocate(struct object_file *o)
|
||||||
|
GElf_Shdr *s = shdr + i;
|
||||||
|
|
||||||
|
if (s->sh_type == SHT_RELA)
|
||||||
|
- ret = kpatch_apply_relocate_add(o, s);
|
||||||
|
+ ret = kpatch_arch_apply_relocate_add(o, s);
|
||||||
|
else if (shdr->sh_type == SHT_REL) {
|
||||||
|
kperr("TODO: handle SHT_REL\n");
|
||||||
|
return -1;
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
416
0038-kpatch_process-Split-function-object_find_patch_regi.patch
Normal file
416
0038-kpatch_process-Split-function-object_find_patch_regi.patch
Normal file
@ -0,0 +1,416 @@
|
|||||||
|
From 80c479726361710a9ac4f328687796a183cf780f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Date: Mon, 12 Oct 2020 15:56:42 +0800
|
||||||
|
Subject: [PATCH 38/89] kpatch_process: Split function object_find_patch_region
|
||||||
|
|
||||||
|
The function object_find_patch_region is arch related. Since process
|
||||||
|
virtual address layout may be different between x86 and aarch64,
|
||||||
|
let's make two separate definations in arch/x86/arch_process.c and
|
||||||
|
arch/aarch64/arch_process.c
|
||||||
|
|
||||||
|
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||||
|
---
|
||||||
|
src/arch.desc | 1 +
|
||||||
|
src/arch/aarch64/arch_process.c | 120 ++++++++++++++++++++++++++++++++
|
||||||
|
src/arch/x86/arch_process.c | 108 ++++++++++++++++++++++++++++
|
||||||
|
src/include/kpatch_process.h | 9 +++
|
||||||
|
src/kpatch_process.c | 87 ++---------------------
|
||||||
|
5 files changed, 242 insertions(+), 83 deletions(-)
|
||||||
|
create mode 100644 src/arch.desc
|
||||||
|
create mode 100644 src/arch/aarch64/arch_process.c
|
||||||
|
create mode 100644 src/arch/x86/arch_process.c
|
||||||
|
|
||||||
|
diff --git a/src/arch.desc b/src/arch.desc
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..9647742
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/arch.desc
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+aarch64
|
||||||
|
diff --git a/src/arch/aarch64/arch_process.c b/src/arch/aarch64/arch_process.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..3a64d77
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/arch/aarch64/arch_process.c
|
||||||
|
@@ -0,0 +1,120 @@
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <ctype.h>
|
||||||
|
+#include <unistd.h>
|
||||||
|
+#include <errno.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <dirent.h>
|
||||||
|
+#include <regex.h>
|
||||||
|
+#include <sys/fcntl.h>
|
||||||
|
+#include <sys/mman.h>
|
||||||
|
+#include <sys/vfs.h>
|
||||||
|
+#include <sys/stat.h>
|
||||||
|
+#include <sys/sysmacros.h>
|
||||||
|
+
|
||||||
|
+#include <sys/syscall.h>
|
||||||
|
+#include <sys/types.h>
|
||||||
|
+#include <sys/wait.h>
|
||||||
|
+#include <sys/ptrace.h>
|
||||||
|
+
|
||||||
|
+#include <gelf.h>
|
||||||
|
+#include <libunwind.h>
|
||||||
|
+#include <libunwind-ptrace.h>
|
||||||
|
+
|
||||||
|
+#include <sys/socket.h>
|
||||||
|
+
|
||||||
|
+#include "include/kpatch_process.h"
|
||||||
|
+#include "include/kpatch_file.h"
|
||||||
|
+#include "include/kpatch_common.h"
|
||||||
|
+#include "include/kpatch_elf.h"
|
||||||
|
+#include "include/kpatch_ptrace.h"
|
||||||
|
+#include "include/list.h"
|
||||||
|
+#include "include/kpatch_log.h"
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Find region for a patch. Take object's `previous_hole` as a left candidate
|
||||||
|
+ * and the next hole as a right candidate. Pace through them until there is
|
||||||
|
+ * enough space in the hole for the patch.
|
||||||
|
+ *
|
||||||
|
+ * Since holes can be much larger than 2GiB take extra caution to allocate
|
||||||
|
+ * patch region inside the (-2GiB, +2GiB) range from the original object.
|
||||||
|
+ */
|
||||||
|
+unsigned long
|
||||||
|
+object_find_patch_region(struct object_file *obj,
|
||||||
|
+ size_t memsize,
|
||||||
|
+ struct vm_hole **hole)
|
||||||
|
+{
|
||||||
|
+ struct list_head *head = &obj->proc->vmaholes;
|
||||||
|
+ struct vm_hole *left_hole = obj->previous_hole,
|
||||||
|
+ *right_hole = next_hole(left_hole, head);
|
||||||
|
+ unsigned long max_distance = 0x80000000;
|
||||||
|
+ struct obj_vm_area *sovma;
|
||||||
|
+
|
||||||
|
+ unsigned long obj_start, obj_end;
|
||||||
|
+ unsigned long region_start = 0, region_end = 0;
|
||||||
|
+
|
||||||
|
+ kpdebug("Looking for patch region for '%s'...\n", obj->name);
|
||||||
|
+
|
||||||
|
+ sovma = list_first_entry(&obj->vma, struct obj_vm_area, list);
|
||||||
|
+ obj_start = sovma->inmem.start;
|
||||||
|
+ sovma = list_entry(obj->vma.prev, struct obj_vm_area, list);
|
||||||
|
+ obj_end = sovma->inmem.end;
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ max_distance -= memsize;
|
||||||
|
+
|
||||||
|
+ /* TODO carefully check for the holes laying between obj_start and
|
||||||
|
+ * obj_end, i.e. just after the executable segment of an executable
|
||||||
|
+ */
|
||||||
|
+ while (left_hole != NULL && right_hole != NULL) {
|
||||||
|
+ if (right_hole != NULL &&
|
||||||
|
+ right_hole->start - obj_start > max_distance)
|
||||||
|
+ right_hole = NULL;
|
||||||
|
+ else if (hole_size(right_hole) > memsize) {
|
||||||
|
+ region_start = right_hole->start;
|
||||||
|
+ region_end =
|
||||||
|
+ (right_hole->end - obj_start) <= max_distance ?
|
||||||
|
+ right_hole->end - memsize :
|
||||||
|
+ obj_start + max_distance;
|
||||||
|
+ *hole = right_hole;
|
||||||
|
+ break;
|
||||||
|
+ } else
|
||||||
|
+ right_hole = next_hole(right_hole, head);
|
||||||
|
+
|
||||||
|
+ if (left_hole != NULL &&
|
||||||
|
+ obj_end - left_hole->end > max_distance)
|
||||||
|
+ left_hole = NULL;
|
||||||
|
+ else if (hole_size(left_hole) > memsize) {
|
||||||
|
+ region_start =
|
||||||
|
+ (left_hole->start - obj_end) <= max_distance ?
|
||||||
|
+ left_hole->start : obj_end > max_distance ?
|
||||||
|
+ obj_end - max_distance : 0;
|
||||||
|
+ region_end = left_hole->end - memsize;
|
||||||
|
+ *hole = left_hole;
|
||||||
|
+ break;
|
||||||
|
+ } else
|
||||||
|
+ left_hole = prev_hole(left_hole, head);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (region_start == region_end) {
|
||||||
|
+ kperr("can't find suitable region for patch on '%s'\n",
|
||||||
|
+ obj->name);
|
||||||
|
+ return -1UL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * On aarch64, virtual address of text and data segments may be continuous,
|
||||||
|
+ * gap between data segment and process heap may be huge. Need to have
|
||||||
|
+ * region_end fixed. Here goes the trick:
|
||||||
|
+ * The branch instruction jump size is in the range of +/-128MB.
|
||||||
|
+ * So we need to put limitation to the region_end.
|
||||||
|
+ */
|
||||||
|
+ region_end = region_start + (0x1<<25);
|
||||||
|
+ region_start = random_from_range(region_start >> PAGE_SHIFT,
|
||||||
|
+ region_end >> PAGE_SHIFT);
|
||||||
|
+ region_start <<= PAGE_SHIFT;
|
||||||
|
+ kpdebug("Found patch region for '%s' at %lx\n", obj->name, region_start);
|
||||||
|
+
|
||||||
|
+ return region_start;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
diff --git a/src/arch/x86/arch_process.c b/src/arch/x86/arch_process.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..ba66134
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/arch/x86/arch_process.c
|
||||||
|
@@ -0,0 +1,108 @@
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <ctype.h>
|
||||||
|
+#include <unistd.h>
|
||||||
|
+#include <errno.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <dirent.h>
|
||||||
|
+#include <regex.h>
|
||||||
|
+#include <sys/fcntl.h>
|
||||||
|
+#include <sys/mman.h>
|
||||||
|
+#include <sys/vfs.h>
|
||||||
|
+#include <sys/stat.h>
|
||||||
|
+#include <sys/sysmacros.h>
|
||||||
|
+
|
||||||
|
+#include <sys/syscall.h>
|
||||||
|
+#include <sys/types.h>
|
||||||
|
+#include <sys/wait.h>
|
||||||
|
+#include <sys/ptrace.h>
|
||||||
|
+
|
||||||
|
+#include <gelf.h>
|
||||||
|
+#include <libunwind.h>
|
||||||
|
+#include <libunwind-ptrace.h>
|
||||||
|
+
|
||||||
|
+#include <sys/socket.h>
|
||||||
|
+
|
||||||
|
+#include "include/kpatch_process.h"
|
||||||
|
+#include "include/kpatch_file.h"
|
||||||
|
+#include "include/kpatch_common.h"
|
||||||
|
+#include "include/kpatch_elf.h"
|
||||||
|
+#include "include/kpatch_ptrace.h"
|
||||||
|
+#include "include/list.h"
|
||||||
|
+#include "include/kpatch_log.h"
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Find region for a patch. Take object's `previous_hole` as a left candidate
|
||||||
|
+ * and the next hole as a right candidate. Pace through them until there is
|
||||||
|
+ * enough space in the hole for the patch.
|
||||||
|
+ *
|
||||||
|
+ * Since holes can be much larger than 2GiB take extra caution to allocate
|
||||||
|
+ * patch region inside the (-2GiB, +2GiB) range from the original object.
|
||||||
|
+ */
|
||||||
|
+unsigned long object_find_patch_region(struct object_file *obj,
|
||||||
|
+ size_t memsize,
|
||||||
|
+ struct vm_hole **hole)
|
||||||
|
+{
|
||||||
|
+ struct list_head *head = &obj->proc->vmaholes;
|
||||||
|
+ struct vm_hole *left_hole = obj->previous_hole,
|
||||||
|
+ *right_hole = next_hole(left_hole, head);
|
||||||
|
+ unsigned long max_distance = 0x80000000;
|
||||||
|
+ struct obj_vm_area *sovma;
|
||||||
|
+
|
||||||
|
+ unsigned long obj_start, obj_end;
|
||||||
|
+ unsigned long region_start = 0, region_end = 0;
|
||||||
|
+
|
||||||
|
+ kpdebug("Looking for patch region for '%s'...\n", obj->name);
|
||||||
|
+
|
||||||
|
+ sovma = list_first_entry(&obj->vma, struct obj_vm_area, list);
|
||||||
|
+ obj_start = sovma->inmem.start;
|
||||||
|
+ sovma = list_entry(obj->vma.prev, struct obj_vm_area, list);
|
||||||
|
+ obj_end = sovma->inmem.end;
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ max_distance -= memsize;
|
||||||
|
+
|
||||||
|
+ /* TODO carefully check for the holes laying between obj_start and
|
||||||
|
+ * obj_end, i.e. just after the executable segment of an executable
|
||||||
|
+ */
|
||||||
|
+ while (left_hole != NULL && right_hole != NULL) {
|
||||||
|
+ if (right_hole != NULL &&
|
||||||
|
+ right_hole->start - obj_start > max_distance)
|
||||||
|
+ right_hole = NULL;
|
||||||
|
+ else if (hole_size(right_hole) > memsize) {
|
||||||
|
+ region_start = right_hole->start;
|
||||||
|
+ region_end =
|
||||||
|
+ (right_hole->end - obj_start) <= max_distance ?
|
||||||
|
+ right_hole->end - memsize :
|
||||||
|
+ obj_start + max_distance;
|
||||||
|
+ *hole = right_hole;
|
||||||
|
+ break;
|
||||||
|
+ } else
|
||||||
|
+ right_hole = next_hole(right_hole, head);
|
||||||
|
+
|
||||||
|
+ if (left_hole != NULL &&
|
||||||
|
+ obj_end - left_hole->end > max_distance)
|
||||||
|
+ left_hole = NULL;
|
||||||
|
+ else if (hole_size(left_hole) > memsize) {
|
||||||
|
+ region_start =
|
||||||
|
+ (left_hole->start - obj_end) <= max_distance ?
|
||||||
|
+ left_hole->start : obj_end > max_distance ?
|
||||||
|
+ obj_end - max_distance : 0;
|
||||||
|
+ region_end = left_hole->end - memsize;
|
||||||
|
+ *hole = left_hole;
|
||||||
|
+ break;
|
||||||
|
+ } else
|
||||||
|
+ left_hole = prev_hole(left_hole, head);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (region_start == region_end) {
|
||||||
|
+ kperr("can't find suitable region for patch on '%s'\n",
|
||||||
|
+ obj->name);
|
||||||
|
+ return -1UL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ region_start += PAGE_SIZE;
|
||||||
|
+ kpdebug("Found patch region for '%s' at %lx\n", obj->name, region_start);
|
||||||
|
+
|
||||||
|
+ return region_start;
|
||||||
|
+}
|
||||||
|
diff --git a/src/include/kpatch_process.h b/src/include/kpatch_process.h
|
||||||
|
index abbb1af..b96a6da 100644
|
||||||
|
--- a/src/include/kpatch_process.h
|
||||||
|
+++ b/src/include/kpatch_process.h
|
||||||
|
@@ -211,4 +211,13 @@ is_kernel_object_name(char *name)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+struct vm_hole *next_hole(struct vm_hole *hole, struct list_head *head);
|
||||||
|
+struct vm_hole *prev_hole(struct vm_hole *hole, struct list_head *head);
|
||||||
|
+unsigned long hole_size(struct vm_hole *hole);
|
||||||
|
+
|
||||||
|
+unsigned long random_from_range(unsigned long min, unsigned long max);
|
||||||
|
+unsigned long object_find_patch_region(struct object_file *obj,
|
||||||
|
+ size_t memsize,
|
||||||
|
+ struct vm_hole **hole);
|
||||||
|
+
|
||||||
|
#endif /* ifndef __KPATCH_PROCESS__ */
|
||||||
|
diff --git a/src/kpatch_process.c b/src/kpatch_process.c
|
||||||
|
index 3f7f2f6..9561962 100644
|
||||||
|
--- a/src/kpatch_process.c
|
||||||
|
+++ b/src/kpatch_process.c
|
||||||
|
@@ -965,7 +965,7 @@ vm_hole_split(struct vm_hole *hole,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static inline struct vm_hole *
|
||||||
|
+inline struct vm_hole *
|
||||||
|
next_hole(struct vm_hole *hole, struct list_head *head)
|
||||||
|
{
|
||||||
|
if (hole == NULL || hole->list.next == head)
|
||||||
|
@@ -974,7 +974,7 @@ next_hole(struct vm_hole *hole, struct list_head *head)
|
||||||
|
return list_entry(hole->list.next, struct vm_hole, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static inline struct vm_hole *
|
||||||
|
+inline struct vm_hole *
|
||||||
|
prev_hole(struct vm_hole *hole, struct list_head *head)
|
||||||
|
{
|
||||||
|
if (hole == NULL || hole->list.prev == head)
|
||||||
|
@@ -983,7 +983,7 @@ prev_hole(struct vm_hole *hole, struct list_head *head)
|
||||||
|
return list_entry(hole->list.prev, struct vm_hole, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static inline unsigned long
|
||||||
|
+inline unsigned long
|
||||||
|
hole_size(struct vm_hole *hole)
|
||||||
|
{
|
||||||
|
if (hole == NULL)
|
||||||
|
@@ -991,92 +991,13 @@ hole_size(struct vm_hole *hole)
|
||||||
|
return hole->end - hole->start;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static unsigned long
|
||||||
|
+unsigned long
|
||||||
|
random_from_range(unsigned long min, unsigned long max)
|
||||||
|
{
|
||||||
|
/* TODO this is not uniform nor safe */
|
||||||
|
return min + random() % (max - min);
|
||||||
|
}
|
||||||
|
|
||||||
|
-/*
|
||||||
|
- * Find region for a patch. Take object's `previous_hole` as a left candidate
|
||||||
|
- * and the next hole as a right candidate. Pace through them until there is
|
||||||
|
- * enough space in the hole for the patch.
|
||||||
|
- *
|
||||||
|
- * Since holes can be much larger than 2GiB take extra caution to allocate
|
||||||
|
- * patch region inside the (-2GiB, +2GiB) range from the original object.
|
||||||
|
- */
|
||||||
|
-static unsigned long
|
||||||
|
-object_find_patch_region(struct object_file *obj,
|
||||||
|
- size_t memsize,
|
||||||
|
- struct vm_hole **hole)
|
||||||
|
-{
|
||||||
|
- struct list_head *head = &obj->proc->vmaholes;
|
||||||
|
- struct vm_hole *left_hole = obj->previous_hole,
|
||||||
|
- *right_hole = next_hole(left_hole, head);
|
||||||
|
- unsigned long max_distance = 0x80000000;
|
||||||
|
- struct obj_vm_area *sovma;
|
||||||
|
-
|
||||||
|
- unsigned long obj_start, obj_end;
|
||||||
|
- unsigned long region_start = 0, region_end = 0;
|
||||||
|
-
|
||||||
|
- kpdebug("Looking for patch region for '%s'...\n", obj->name);
|
||||||
|
-
|
||||||
|
- sovma = list_first_entry(&obj->vma, struct obj_vm_area, list);
|
||||||
|
- obj_start = sovma->inmem.start;
|
||||||
|
- sovma = list_entry(obj->vma.prev, struct obj_vm_area, list);
|
||||||
|
- obj_end = sovma->inmem.end;
|
||||||
|
-
|
||||||
|
-
|
||||||
|
- max_distance -= memsize;
|
||||||
|
-
|
||||||
|
- /* TODO carefully check for the holes laying between obj_start and
|
||||||
|
- * obj_end, i.e. just after the executable segment of an executable
|
||||||
|
- */
|
||||||
|
- while (left_hole != NULL && right_hole != NULL) {
|
||||||
|
- if (right_hole != NULL &&
|
||||||
|
- right_hole->start - obj_start > max_distance)
|
||||||
|
- right_hole = NULL;
|
||||||
|
- else if (hole_size(right_hole) > memsize) {
|
||||||
|
- region_start = right_hole->start;
|
||||||
|
- region_end =
|
||||||
|
- (right_hole->end - obj_start) <= max_distance ?
|
||||||
|
- right_hole->end - memsize :
|
||||||
|
- obj_start + max_distance;
|
||||||
|
- *hole = right_hole;
|
||||||
|
- break;
|
||||||
|
- } else
|
||||||
|
- right_hole = next_hole(right_hole, head);
|
||||||
|
-
|
||||||
|
- if (left_hole != NULL &&
|
||||||
|
- obj_end - left_hole->end > max_distance)
|
||||||
|
- left_hole = NULL;
|
||||||
|
- else if (hole_size(left_hole) > memsize) {
|
||||||
|
- region_start =
|
||||||
|
- (left_hole->start - obj_end) <= max_distance ?
|
||||||
|
- left_hole->start : obj_end > max_distance ?
|
||||||
|
- obj_end - max_distance : 0;
|
||||||
|
- region_end = left_hole->end - memsize;
|
||||||
|
- *hole = left_hole;
|
||||||
|
- break;
|
||||||
|
- } else
|
||||||
|
- left_hole = prev_hole(left_hole, head);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (region_start == region_end) {
|
||||||
|
- kperr("can't find suitable region for patch on '%s'\n",
|
||||||
|
- obj->name);
|
||||||
|
- return -1UL;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- region_start = random_from_range(region_start >> PAGE_SHIFT,
|
||||||
|
- region_end >> PAGE_SHIFT);
|
||||||
|
- region_start <<= PAGE_SHIFT;
|
||||||
|
- kpdebug("Found patch region for '%s' at %lx\n", obj->name, region_start);
|
||||||
|
-
|
||||||
|
- return region_start;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
int
|
||||||
|
kpatch_object_allocate_patch(struct object_file *o,
|
||||||
|
size_t sz)
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
501
0039-kpatch_ptrace-Split-function-kpatch_ptrace_waitpid.patch
Normal file
501
0039-kpatch_ptrace-Split-function-kpatch_ptrace_waitpid.patch
Normal file
@ -0,0 +1,501 @@
|
|||||||
|
From 35b9c6934fc5c1e2ea4cf7e30b91b3b91e48074d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Date: Mon, 12 Oct 2020 16:16:57 +0800
|
||||||
|
Subject: [PATCH 39/89] kpatch_ptrace: Split function kpatch_ptrace_waitpid
|
||||||
|
|
||||||
|
The function kpatch_ptrace_waitpid is arch related, let's
|
||||||
|
rename it with kpatch_arch_ptrace_waitpid, and make the
|
||||||
|
defination in arch/x86/arch_ptrace.c and arch/aarch64/arch_ptrace.c
|
||||||
|
|
||||||
|
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||||
|
---
|
||||||
|
src/arch/aarch64/arch_ptrace.c | 145 +++++++++++++++++++++++++++++++++
|
||||||
|
src/arch/x86/arch_ptrace.c | 140 +++++++++++++++++++++++++++++++
|
||||||
|
src/include/kpatch_ptrace.h | 20 +++++
|
||||||
|
src/kpatch_ptrace.c | 130 +----------------------------
|
||||||
|
4 files changed, 307 insertions(+), 128 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/arch/aarch64/arch_ptrace.c b/src/arch/aarch64/arch_ptrace.c
|
||||||
|
index e69de29..fb19e86 100644
|
||||||
|
--- a/src/arch/aarch64/arch_ptrace.c
|
||||||
|
+++ b/src/arch/aarch64/arch_ptrace.c
|
||||||
|
@@ -0,0 +1,145 @@
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <errno.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <time.h>
|
||||||
|
+#include <fcntl.h>
|
||||||
|
+#include <sys/ptrace.h>
|
||||||
|
+#include <sys/wait.h>
|
||||||
|
+#include <asm/unistd.h>
|
||||||
|
+
|
||||||
|
+#include <unistd.h>
|
||||||
|
+#include <sys/syscall.h>
|
||||||
|
+#include <linux/auxvec.h>
|
||||||
|
+
|
||||||
|
+#include <sys/types.h>
|
||||||
|
+#include <sys/socket.h>
|
||||||
|
+
|
||||||
|
+#include "include/kpatch_process.h"
|
||||||
|
+#include "include/kpatch_common.h"
|
||||||
|
+#include "include/kpatch_ptrace.h"
|
||||||
|
+#include "include/kpatch_log.h"
|
||||||
|
+
|
||||||
|
+#include <gelf.h>
|
||||||
|
+
|
||||||
|
+int
|
||||||
|
+kpatch_arch_ptrace_waitpid(kpatch_process_t *proc,
|
||||||
|
+ struct timespec *timeout,
|
||||||
|
+ const sigset_t *sigset)
|
||||||
|
+{
|
||||||
|
+ struct kpatch_ptrace_ctx *pctx;
|
||||||
|
+ siginfo_t siginfo;
|
||||||
|
+ int ret, status;
|
||||||
|
+ pid_t pid;
|
||||||
|
+ struct user_regs_struct regs;
|
||||||
|
+ struct iovec regs_iov;
|
||||||
|
+
|
||||||
|
+ regs_iov.iov_base = ®s;
|
||||||
|
+ regs_iov.iov_len = sizeof(regs);
|
||||||
|
+
|
||||||
|
+ /* Immediately reap one attached thread */
|
||||||
|
+ pid = waitpid(-1, &status, __WALL | WNOHANG);
|
||||||
|
+
|
||||||
|
+ if (pid < 0) {
|
||||||
|
+ kplogerror("can't wait for tracees\n");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* There is none ready, wait for notification via signal */
|
||||||
|
+ if (pid == 0) {
|
||||||
|
+ ret = sigtimedwait(sigset, &siginfo, timeout);
|
||||||
|
+ if (ret == -1 && errno == EAGAIN) {
|
||||||
|
+ /* We have timeouted */
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (ret == -1 && errno == EINVAL) {
|
||||||
|
+ kperr("invalid timeout\n");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* We have got EINTR and must restart */
|
||||||
|
+ if (ret == -1 && errno == EINTR)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Kernel stacks signals that follow too quickly.
|
||||||
|
+ * Deal with it by waiting for any child, not just
|
||||||
|
+ * one that is specified in signal
|
||||||
|
+ */
|
||||||
|
+ pid = waitpid(-1, &status, __WALL | WNOHANG);
|
||||||
|
+
|
||||||
|
+ if (pid == 0) {
|
||||||
|
+ kperr("missing waitpid for %d\n", siginfo.si_pid);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (pid < 0) {
|
||||||
|
+ kplogerror("can't wait for tracee %d\n", siginfo.si_pid);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!WIFSTOPPED(status) && WIFSIGNALED(status)) {
|
||||||
|
+ /* Continue, resending the signal */
|
||||||
|
+ ret = ptrace(PTRACE_CONT, pid, NULL,
|
||||||
|
+ (void *)(uintptr_t)WTERMSIG(status));
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kplogerror("can't start tracee %d\n", pid);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (WIFEXITED(status)) {
|
||||||
|
+ pctx = kpatch_ptrace_find_thread(proc, pid, 0UL);
|
||||||
|
+ if (pctx == NULL) {
|
||||||
|
+ kperr("got unexpected child '%d' exit\n", pid);
|
||||||
|
+ } else {
|
||||||
|
+ /* It's dead */
|
||||||
|
+ pctx->pid = pctx->running = 0;
|
||||||
|
+ }
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = ptrace(PTRACE_GETREGSET, pid, (void *)NT_PRSTATUS, (void *)®s_iov);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kplogerror("can't get regs %d\n", pid);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ pctx = kpatch_ptrace_find_thread(proc, pid, regs.pc);
|
||||||
|
+
|
||||||
|
+ if (pctx == NULL) {
|
||||||
|
+ /* We either don't know anything about this thread or
|
||||||
|
+ * even worse -- we stopped it in the wrong place.
|
||||||
|
+ * Bail out.
|
||||||
|
+ */
|
||||||
|
+ pctx = kpatch_ptrace_find_thread(proc, pid, 0);
|
||||||
|
+ if (pctx != NULL)
|
||||||
|
+ pctx->running = 0;
|
||||||
|
+
|
||||||
|
+ /* TODO: fix the latter by SINGLESTEPping such a thread with
|
||||||
|
+ * the original instruction in place */
|
||||||
|
+ kperr("the thread ran out: %d, pc= %llx, expected = %lx\n", pid,
|
||||||
|
+ regs.pc, pctx->execute_until);
|
||||||
|
+ errno = ESRCH;
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ pctx->running = 0;
|
||||||
|
+
|
||||||
|
+ /* Restore thread registers, pctx is now valid */
|
||||||
|
+ kpdebug("Got thread %d at %llx\n", pctx->pid,
|
||||||
|
+ regs.pc - BREAK_INSN_LENGTH);
|
||||||
|
+
|
||||||
|
+ regs.pc = pctx->execute_until;
|
||||||
|
+
|
||||||
|
+ ret = ptrace(PTRACE_SETREGSET, pctx->pid, (void*)NT_PRSTATUS, (void*)®s_iov);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kplogerror("can't set regs - %d\n", pctx->pid);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
diff --git a/src/arch/x86/arch_ptrace.c b/src/arch/x86/arch_ptrace.c
|
||||||
|
index e69de29..6e943fd 100644
|
||||||
|
--- a/src/arch/x86/arch_ptrace.c
|
||||||
|
+++ b/src/arch/x86/arch_ptrace.c
|
||||||
|
@@ -0,0 +1,140 @@
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <errno.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <time.h>
|
||||||
|
+#include <fcntl.h>
|
||||||
|
+#include <sys/ptrace.h>
|
||||||
|
+#include <sys/wait.h>
|
||||||
|
+#include <asm/unistd.h>
|
||||||
|
+
|
||||||
|
+#include <unistd.h>
|
||||||
|
+#include <sys/syscall.h>
|
||||||
|
+#include <linux/auxvec.h>
|
||||||
|
+
|
||||||
|
+#include <sys/types.h>
|
||||||
|
+#include <sys/socket.h>
|
||||||
|
+
|
||||||
|
+#include "include/kpatch_process.h"
|
||||||
|
+#include "include/kpatch_common.h"
|
||||||
|
+#include "include/kpatch_ptrace.h"
|
||||||
|
+#include "include/kpatch_log.h"
|
||||||
|
+
|
||||||
|
+#include <gelf.h>
|
||||||
|
+
|
||||||
|
+int kpatch_arch_ptrace_waitpid(kpatch_process_t *proc,
|
||||||
|
+ struct timespec *timeout,
|
||||||
|
+ const sigset_t *sigset)
|
||||||
|
+{
|
||||||
|
+ struct kpatch_ptrace_ctx *pctx;
|
||||||
|
+ siginfo_t siginfo;
|
||||||
|
+ int ret, status;
|
||||||
|
+ pid_t pid;
|
||||||
|
+ struct user_regs_struct regs;
|
||||||
|
+
|
||||||
|
+ /* Immediately reap one attached thread */
|
||||||
|
+ pid = waitpid(-1, &status, __WALL | WNOHANG);
|
||||||
|
+
|
||||||
|
+ if (pid < 0) {
|
||||||
|
+ kplogerror("can't wait for tracees\n");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* There is none ready, wait for notification via signal */
|
||||||
|
+ if (pid == 0) {
|
||||||
|
+ ret = sigtimedwait(sigset, &siginfo, timeout);
|
||||||
|
+ if (ret == -1 && errno == EAGAIN) {
|
||||||
|
+ /* We have timeouted */
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (ret == -1 && errno == EINVAL) {
|
||||||
|
+ kperr("invalid timeout\n");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* We have got EINTR and must restart */
|
||||||
|
+ if (ret == -1 && errno == EINTR)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Kernel stacks signals that follow too quickly.
|
||||||
|
+ * Deal with it by waiting for any child, not just
|
||||||
|
+ * one that is specified in signal
|
||||||
|
+ */
|
||||||
|
+ pid = waitpid(-1, &status, __WALL | WNOHANG);
|
||||||
|
+
|
||||||
|
+ if (pid == 0) {
|
||||||
|
+ kperr("missing waitpid for %d\n", siginfo.si_pid);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (pid < 0) {
|
||||||
|
+ kplogerror("can't wait for tracee %d\n", siginfo.si_pid);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!WIFSTOPPED(status) && WIFSIGNALED(status)) {
|
||||||
|
+ /* Continue, resending the signal */
|
||||||
|
+ ret = ptrace(PTRACE_CONT, pid, NULL,
|
||||||
|
+ (void *)(uintptr_t)WTERMSIG(status));
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kplogerror("can't start tracee %d\n", pid);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (WIFEXITED(status)) {
|
||||||
|
+ pctx = kpatch_ptrace_find_thread(proc, pid, 0UL);
|
||||||
|
+ if (pctx == NULL) {
|
||||||
|
+ kperr("got unexpected child '%d' exit\n", pid);
|
||||||
|
+ } else {
|
||||||
|
+ /* It's dead */
|
||||||
|
+ pctx->pid = pctx->running = 0;
|
||||||
|
+ }
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = ptrace(PTRACE_GETREGS, pid, NULL, ®s);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kplogerror("can't get regs %d\n", pid);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ pctx = kpatch_ptrace_find_thread(proc, pid, regs.rip);
|
||||||
|
+
|
||||||
|
+ if (pctx == NULL) {
|
||||||
|
+ /* We either don't know anything about this thread or
|
||||||
|
+ * even worse -- we stopped it in the wrong place.
|
||||||
|
+ * Bail out.
|
||||||
|
+ */
|
||||||
|
+ pctx = kpatch_ptrace_find_thread(proc, pid, 0);
|
||||||
|
+ if (pctx != NULL)
|
||||||
|
+ pctx->running = 0;
|
||||||
|
+
|
||||||
|
+ /* TODO: fix the latter by SINGLESTEPping such a thread with
|
||||||
|
+ * the original instruction in place */
|
||||||
|
+ kperr("the thread ran out: %d, rip = %llx, expected = %lx\n", pid,
|
||||||
|
+ regs.rip, pctx->execute_until);
|
||||||
|
+ errno = ESRCH;
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ pctx->running = 0;
|
||||||
|
+
|
||||||
|
+ /* Restore thread registers, pctx is now valid */
|
||||||
|
+ kpdebug("Got thread %d at %llx\n", pctx->pid,
|
||||||
|
+ regs.rip - BREAK_INSN_LENGTH);
|
||||||
|
+
|
||||||
|
+ regs.rip = pctx->execute_until;
|
||||||
|
+
|
||||||
|
+ ret = ptrace(PTRACE_SETREGS, pctx->pid, NULL, ®s);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kplogerror("can't set regs - %d\n", pctx->pid);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
diff --git a/src/include/kpatch_ptrace.h b/src/include/kpatch_ptrace.h
|
||||||
|
index 7557e1f..1c7d33e 100644
|
||||||
|
--- a/src/include/kpatch_ptrace.h
|
||||||
|
+++ b/src/include/kpatch_ptrace.h
|
||||||
|
@@ -102,4 +102,24 @@ kpatch_process_memcpy(kpatch_process_t *proc,
|
||||||
|
unsigned long dst,
|
||||||
|
unsigned long src,
|
||||||
|
size_t size);
|
||||||
|
+
|
||||||
|
+#define BREAK_INSN_LENGTH 1
|
||||||
|
+#define BREAK_INSN {0xcc}
|
||||||
|
+
|
||||||
|
+#define SEC_TO_MSEC 1000
|
||||||
|
+#define MSEC_TO_NSEC 1000000
|
||||||
|
+
|
||||||
|
+#define for_each_thread(proc, pctx) \
|
||||||
|
+ list_for_each_entry(pctx, &proc->ptrace.pctxs, list)
|
||||||
|
+
|
||||||
|
+struct kpatch_ptrace_ctx *
|
||||||
|
+kpatch_ptrace_find_thread(kpatch_process_t *proc,
|
||||||
|
+ pid_t pid,
|
||||||
|
+ unsigned long rip);
|
||||||
|
+
|
||||||
|
+int
|
||||||
|
+kpatch_arch_ptrace_waitpid(kpatch_process_t *proc,
|
||||||
|
+ struct timespec *timeout,
|
||||||
|
+ const sigset_t *sigset);
|
||||||
|
+
|
||||||
|
#endif
|
||||||
|
diff --git a/src/kpatch_ptrace.c b/src/kpatch_ptrace.c
|
||||||
|
index 8910aa8..3c57288 100644
|
||||||
|
--- a/src/kpatch_ptrace.c
|
||||||
|
+++ b/src/kpatch_ptrace.c
|
||||||
|
@@ -180,16 +180,8 @@ int kpatch_ptrace_get_entry_point(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
return entry[0] == AT_ENTRY ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
-#define BREAK_INSN_LENGTH 1
|
||||||
|
-#define BREAK_INSN {0xcc}
|
||||||
|
|
||||||
|
-#define SEC_TO_MSEC 1000
|
||||||
|
-#define MSEC_TO_NSEC 1000000
|
||||||
|
-
|
||||||
|
-#define for_each_thread(proc, pctx) \
|
||||||
|
- list_for_each_entry(pctx, &proc->ptrace.pctxs, list)
|
||||||
|
-
|
||||||
|
-static struct kpatch_ptrace_ctx *
|
||||||
|
+struct kpatch_ptrace_ctx *
|
||||||
|
kpatch_ptrace_find_thread(kpatch_process_t *proc,
|
||||||
|
pid_t pid,
|
||||||
|
unsigned long rip)
|
||||||
|
@@ -213,124 +205,6 @@ kpatch_ptrace_find_thread(kpatch_process_t *proc,
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static inline int
|
||||||
|
-kpatch_ptrace_waitpid(kpatch_process_t *proc,
|
||||||
|
- struct timespec *timeout,
|
||||||
|
- const sigset_t *sigset)
|
||||||
|
-{
|
||||||
|
- struct kpatch_ptrace_ctx *pctx;
|
||||||
|
- siginfo_t siginfo;
|
||||||
|
- int ret, status;
|
||||||
|
- pid_t pid;
|
||||||
|
- struct user_regs_struct regs;
|
||||||
|
-
|
||||||
|
- /* Immediately reap one attached thread */
|
||||||
|
- pid = waitpid(-1, &status, __WALL | WNOHANG);
|
||||||
|
-
|
||||||
|
- if (pid < 0) {
|
||||||
|
- kplogerror("can't wait for tracees\n");
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* There is none ready, wait for notification via signal */
|
||||||
|
- if (pid == 0) {
|
||||||
|
- ret = sigtimedwait(sigset, &siginfo, timeout);
|
||||||
|
- if (ret == -1 && errno == EAGAIN) {
|
||||||
|
- /* We have timeouted */
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (ret == -1 && errno == EINVAL) {
|
||||||
|
- kperr("invalid timeout\n");
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* We have got EINTR and must restart */
|
||||||
|
- if (ret == -1 && errno == EINTR)
|
||||||
|
- return 0;
|
||||||
|
-
|
||||||
|
- /**
|
||||||
|
- * Kernel stacks signals that follow too quickly.
|
||||||
|
- * Deal with it by waiting for any child, not just
|
||||||
|
- * one that is specified in signal
|
||||||
|
- */
|
||||||
|
- pid = waitpid(-1, &status, __WALL | WNOHANG);
|
||||||
|
-
|
||||||
|
- if (pid == 0) {
|
||||||
|
- kperr("missing waitpid for %d\n", siginfo.si_pid);
|
||||||
|
- return 0;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (pid < 0) {
|
||||||
|
- kplogerror("can't wait for tracee %d\n", siginfo.si_pid);
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (!WIFSTOPPED(status) && WIFSIGNALED(status)) {
|
||||||
|
- /* Continue, resending the signal */
|
||||||
|
- ret = ptrace(PTRACE_CONT, pid, NULL,
|
||||||
|
- (void *)(uintptr_t)WTERMSIG(status));
|
||||||
|
- if (ret < 0) {
|
||||||
|
- kplogerror("can't start tracee %d\n", pid);
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
- return 0;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (WIFEXITED(status)) {
|
||||||
|
- pctx = kpatch_ptrace_find_thread(proc, pid, 0UL);
|
||||||
|
- if (pctx == NULL) {
|
||||||
|
- kperr("got unexpected child '%d' exit\n", pid);
|
||||||
|
- } else {
|
||||||
|
- /* It's dead */
|
||||||
|
- pctx->pid = pctx->running = 0;
|
||||||
|
- }
|
||||||
|
- return 1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- ret = ptrace(PTRACE_GETREGS, pid, NULL, ®s);
|
||||||
|
- if (ret < 0) {
|
||||||
|
- kplogerror("can't get regs %d\n", pid);
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- pctx = kpatch_ptrace_find_thread(proc, pid, regs.rip);
|
||||||
|
-
|
||||||
|
- if (pctx == NULL) {
|
||||||
|
- /* We either don't know anything about this thread or
|
||||||
|
- * even worse -- we stopped it in the wrong place.
|
||||||
|
- * Bail out.
|
||||||
|
- */
|
||||||
|
- pctx = kpatch_ptrace_find_thread(proc, pid, 0);
|
||||||
|
- if (pctx != NULL)
|
||||||
|
- pctx->running = 0;
|
||||||
|
-
|
||||||
|
- /* TODO: fix the latter by SINGLESTEPping such a thread with
|
||||||
|
- * the original instruction in place */
|
||||||
|
- kperr("the thread ran out: %d, rip = %llx, expected = %lx\n", pid,
|
||||||
|
- regs.rip, pctx->execute_until);
|
||||||
|
- errno = ESRCH;
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- pctx->running = 0;
|
||||||
|
-
|
||||||
|
- /* Restore thread registers, pctx is now valid */
|
||||||
|
- kpdebug("Got thread %d at %llx\n", pctx->pid,
|
||||||
|
- regs.rip - BREAK_INSN_LENGTH);
|
||||||
|
-
|
||||||
|
- regs.rip = pctx->execute_until;
|
||||||
|
-
|
||||||
|
- ret = ptrace(PTRACE_SETREGS, pctx->pid, NULL, ®s);
|
||||||
|
- if (ret < 0) {
|
||||||
|
- kplogerror("can't set regs - %d\n", pctx->pid);
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- return 1;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
struct breakpoint {
|
||||||
|
unsigned long addr;
|
||||||
|
unsigned char orig_code[BREAK_INSN_LENGTH];
|
||||||
|
@@ -441,7 +315,7 @@ kpatch_ptrace_execute_until(kpatch_process_t *proc,
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
- rv = kpatch_ptrace_waitpid(proc, &timeout, &sigset);
|
||||||
|
+ rv = kpatch_arch_ptrace_waitpid(proc, &timeout, &sigset);
|
||||||
|
if (rv < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
137
0040-kpatch_ptrace-Split-function-copy_regs.patch
Normal file
137
0040-kpatch_ptrace-Split-function-copy_regs.patch
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
From 8c0199836e7944569dbbeb5e571d791b8e466275 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Date: Mon, 12 Oct 2020 16:24:09 +0800
|
||||||
|
Subject: [PATCH 40/89] kpatch_ptrace: Split function copy_regs
|
||||||
|
|
||||||
|
The function copy_regs is arch related, so make two separate
|
||||||
|
definations in arch/x86/arch_ptrace.c and arch/aarch64/arch_ptrace.c
|
||||||
|
|
||||||
|
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||||
|
---
|
||||||
|
src/arch/aarch64/arch_ptrace.c | 28 ++++++++++++++++++++++++++++
|
||||||
|
src/arch/x86/arch_ptrace.c | 22 ++++++++++++++++++++++
|
||||||
|
src/include/kpatch_ptrace.h | 3 +++
|
||||||
|
src/kpatch_ptrace.c | 22 ----------------------
|
||||||
|
4 files changed, 53 insertions(+), 22 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/arch/aarch64/arch_ptrace.c b/src/arch/aarch64/arch_ptrace.c
|
||||||
|
index fb19e86..0366d4f 100644
|
||||||
|
--- a/src/arch/aarch64/arch_ptrace.c
|
||||||
|
+++ b/src/arch/aarch64/arch_ptrace.c
|
||||||
|
@@ -22,6 +22,34 @@
|
||||||
|
|
||||||
|
#include <gelf.h>
|
||||||
|
|
||||||
|
+void copy_regs(struct user_regs_struct *dst,
|
||||||
|
+ struct user_regs_struct *src)
|
||||||
|
+{
|
||||||
|
+#define COPY_REG(x) dst->x = src->x
|
||||||
|
+ COPY_REG(regs[0]);
|
||||||
|
+ COPY_REG(regs[1]);
|
||||||
|
+ COPY_REG(regs[2]);
|
||||||
|
+ COPY_REG(regs[3]);
|
||||||
|
+ COPY_REG(regs[4]);
|
||||||
|
+ COPY_REG(regs[5]);
|
||||||
|
+ COPY_REG(regs[8]);
|
||||||
|
+ COPY_REG(regs[29]);
|
||||||
|
+
|
||||||
|
+ COPY_REG(regs[9]);
|
||||||
|
+ COPY_REG(regs[10]);
|
||||||
|
+ COPY_REG(regs[11]);
|
||||||
|
+ COPY_REG(regs[12]);
|
||||||
|
+ COPY_REG(regs[13]);
|
||||||
|
+ COPY_REG(regs[14]);
|
||||||
|
+ COPY_REG(regs[15]);
|
||||||
|
+ COPY_REG(regs[16]);
|
||||||
|
+ COPY_REG(regs[17]);
|
||||||
|
+ COPY_REG(regs[18]);
|
||||||
|
+ COPY_REG(regs[19]);
|
||||||
|
+ COPY_REG(regs[20]);
|
||||||
|
+#undef COPY_REG
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int
|
||||||
|
kpatch_arch_ptrace_waitpid(kpatch_process_t *proc,
|
||||||
|
struct timespec *timeout,
|
||||||
|
diff --git a/src/arch/x86/arch_ptrace.c b/src/arch/x86/arch_ptrace.c
|
||||||
|
index 6e943fd..fa23757 100644
|
||||||
|
--- a/src/arch/x86/arch_ptrace.c
|
||||||
|
+++ b/src/arch/x86/arch_ptrace.c
|
||||||
|
@@ -22,6 +22,28 @@
|
||||||
|
|
||||||
|
#include <gelf.h>
|
||||||
|
|
||||||
|
+void copy_regs(struct user_regs_struct *dst,
|
||||||
|
+ struct user_regs_struct *src)
|
||||||
|
+{
|
||||||
|
+#define COPY_REG(x) dst->x = src->x
|
||||||
|
+ COPY_REG(r15);
|
||||||
|
+ COPY_REG(r14);
|
||||||
|
+ COPY_REG(r13);
|
||||||
|
+ COPY_REG(r12);
|
||||||
|
+ COPY_REG(rbp);
|
||||||
|
+ COPY_REG(rbx);
|
||||||
|
+ COPY_REG(r11);
|
||||||
|
+ COPY_REG(r10);
|
||||||
|
+ COPY_REG(r9);
|
||||||
|
+ COPY_REG(r8);
|
||||||
|
+ COPY_REG(rax);
|
||||||
|
+ COPY_REG(rcx);
|
||||||
|
+ COPY_REG(rdx);
|
||||||
|
+ COPY_REG(rsi);
|
||||||
|
+ COPY_REG(rdi);
|
||||||
|
+#undef COPY_REG
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int kpatch_arch_ptrace_waitpid(kpatch_process_t *proc,
|
||||||
|
struct timespec *timeout,
|
||||||
|
const sigset_t *sigset)
|
||||||
|
diff --git a/src/include/kpatch_ptrace.h b/src/include/kpatch_ptrace.h
|
||||||
|
index 1c7d33e..e434d68 100644
|
||||||
|
--- a/src/include/kpatch_ptrace.h
|
||||||
|
+++ b/src/include/kpatch_ptrace.h
|
||||||
|
@@ -122,4 +122,7 @@ kpatch_arch_ptrace_waitpid(kpatch_process_t *proc,
|
||||||
|
struct timespec *timeout,
|
||||||
|
const sigset_t *sigset);
|
||||||
|
|
||||||
|
+void copy_regs(struct user_regs_struct *dst,
|
||||||
|
+ struct user_regs_struct *src);
|
||||||
|
+
|
||||||
|
#endif
|
||||||
|
diff --git a/src/kpatch_ptrace.c b/src/kpatch_ptrace.c
|
||||||
|
index 3c57288..180bbaa 100644
|
||||||
|
--- a/src/kpatch_ptrace.c
|
||||||
|
+++ b/src/kpatch_ptrace.c
|
||||||
|
@@ -413,28 +413,6 @@ poke_back:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void copy_regs(struct user_regs_struct *dst,
|
||||||
|
- struct user_regs_struct *src)
|
||||||
|
-{
|
||||||
|
-#define COPY_REG(x) dst->x = src->x
|
||||||
|
- COPY_REG(r15);
|
||||||
|
- COPY_REG(r14);
|
||||||
|
- COPY_REG(r13);
|
||||||
|
- COPY_REG(r12);
|
||||||
|
- COPY_REG(rbp);
|
||||||
|
- COPY_REG(rbx);
|
||||||
|
- COPY_REG(r11);
|
||||||
|
- COPY_REG(r10);
|
||||||
|
- COPY_REG(r9);
|
||||||
|
- COPY_REG(r8);
|
||||||
|
- COPY_REG(rax);
|
||||||
|
- COPY_REG(rcx);
|
||||||
|
- COPY_REG(rdx);
|
||||||
|
- COPY_REG(rsi);
|
||||||
|
- COPY_REG(rdi);
|
||||||
|
-#undef COPY_REG
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static
|
||||||
|
int
|
||||||
|
kpatch_execute_remote_func(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
328
0041-kpatch_ptrace-Split-function-kpatch_execute_remote_f.patch
Normal file
328
0041-kpatch_ptrace-Split-function-kpatch_execute_remote_f.patch
Normal file
@ -0,0 +1,328 @@
|
|||||||
|
From e312d7a74924d6e3880fa27adb4bcd04c8c25983 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Date: Mon, 12 Oct 2020 16:30:58 +0800
|
||||||
|
Subject: [PATCH 41/89] kpatch_ptrace: Split function
|
||||||
|
kpatch_execute_remote_func
|
||||||
|
|
||||||
|
The function kpatch_execute_remote_func is arch related, first
|
||||||
|
rename it with kpatch_arch_execute_remote_func, and the make separate
|
||||||
|
definations in arch/x86/arch_ptrace.c and arch/aarch64/arch_ptrace.c
|
||||||
|
|
||||||
|
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||||
|
---
|
||||||
|
src/arch/aarch64/arch_ptrace.c | 87 ++++++++++++++++++++++++++++++++++
|
||||||
|
src/arch/x86/arch_ptrace.c | 79 ++++++++++++++++++++++++++++++
|
||||||
|
src/include/kpatch_ptrace.h | 9 ++++
|
||||||
|
src/kpatch_ptrace.c | 82 +-------------------------------
|
||||||
|
4 files changed, 176 insertions(+), 81 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/arch/aarch64/arch_ptrace.c b/src/arch/aarch64/arch_ptrace.c
|
||||||
|
index 0366d4f..821b4e8 100644
|
||||||
|
--- a/src/arch/aarch64/arch_ptrace.c
|
||||||
|
+++ b/src/arch/aarch64/arch_ptrace.c
|
||||||
|
@@ -22,6 +22,93 @@
|
||||||
|
|
||||||
|
#include <gelf.h>
|
||||||
|
|
||||||
|
+int
|
||||||
|
+kpatch_arch_execute_remote_func(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
+ const unsigned char *code,
|
||||||
|
+ size_t codelen,
|
||||||
|
+ struct user_regs_struct *pregs,
|
||||||
|
+ int (*func)(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
+ void *data),
|
||||||
|
+ void *data)
|
||||||
|
+{
|
||||||
|
+ struct user_regs_struct orig_regs, regs;
|
||||||
|
+ struct iovec orig_regs_iov, regs_iov;
|
||||||
|
+
|
||||||
|
+ orig_regs_iov.iov_base = &orig_regs;
|
||||||
|
+ orig_regs_iov.iov_len = sizeof(orig_regs);
|
||||||
|
+ regs_iov.iov_base = ®s;
|
||||||
|
+ regs_iov.iov_len = sizeof(regs);
|
||||||
|
+
|
||||||
|
+ unsigned char orig_code[codelen];
|
||||||
|
+ int ret;
|
||||||
|
+ kpatch_process_t *proc = pctx->proc;
|
||||||
|
+ unsigned long libc_base = proc->libc_base;
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ ret = ptrace(PTRACE_GETREGSET, pctx->pid, (void*)NT_PRSTATUS, (void*)&orig_regs_iov);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kplogerror("can't get regs - %d\n", pctx->pid);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ ret = kpatch_process_mem_read(
|
||||||
|
+ proc,
|
||||||
|
+ libc_base,
|
||||||
|
+ (unsigned long *)orig_code,
|
||||||
|
+ codelen);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kplogerror("can't peek original code - %d\n", pctx->pid);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ ret = kpatch_process_mem_write(
|
||||||
|
+ proc,
|
||||||
|
+ (unsigned long *)code,
|
||||||
|
+ libc_base,
|
||||||
|
+ codelen);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kplogerror("can't poke syscall code - %d\n", pctx->pid);
|
||||||
|
+ goto poke_back;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ regs = orig_regs;
|
||||||
|
+ regs.pc = libc_base;
|
||||||
|
+
|
||||||
|
+ copy_regs(®s, pregs);
|
||||||
|
+
|
||||||
|
+ ret = ptrace(PTRACE_SETREGSET, pctx->pid, (void*)NT_PRSTATUS, (void*)®s_iov);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kplogerror("can't set regs - %d\n", pctx->pid);
|
||||||
|
+ goto poke_back;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = func(pctx, data);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kplogerror("failed call to func\n");
|
||||||
|
+ goto poke_back;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = ptrace(PTRACE_GETREGSET, pctx->pid, (void*)NT_PRSTATUS, (void*)®s_iov);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kplogerror("can't get updated regs - %d\n", pctx->pid);
|
||||||
|
+ goto poke_back;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = ptrace(PTRACE_SETREGSET, pctx->pid, (void*)NT_PRSTATUS, (void*)&orig_regs_iov);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kplogerror("can't restore regs - %d\n", pctx->pid);
|
||||||
|
+ goto poke_back;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *pregs = regs;
|
||||||
|
+
|
||||||
|
+poke_back:
|
||||||
|
+ kpatch_process_mem_write(
|
||||||
|
+ proc,
|
||||||
|
+ (unsigned long *)orig_code,
|
||||||
|
+ libc_base,
|
||||||
|
+ codelen);
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void copy_regs(struct user_regs_struct *dst,
|
||||||
|
struct user_regs_struct *src)
|
||||||
|
{
|
||||||
|
diff --git a/src/arch/x86/arch_ptrace.c b/src/arch/x86/arch_ptrace.c
|
||||||
|
index fa23757..9239f52 100644
|
||||||
|
--- a/src/arch/x86/arch_ptrace.c
|
||||||
|
+++ b/src/arch/x86/arch_ptrace.c
|
||||||
|
@@ -22,6 +22,85 @@
|
||||||
|
|
||||||
|
#include <gelf.h>
|
||||||
|
|
||||||
|
+int
|
||||||
|
+kpatch_arch_execute_remote_func(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
+ const unsigned char *code,
|
||||||
|
+ size_t codelen,
|
||||||
|
+ struct user_regs_struct *pregs,
|
||||||
|
+ int (*func)(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
+ void *data),
|
||||||
|
+ void *data)
|
||||||
|
+{
|
||||||
|
+ struct user_regs_struct orig_regs, regs;
|
||||||
|
+ unsigned char orig_code[codelen];
|
||||||
|
+ int ret;
|
||||||
|
+ kpatch_process_t *proc = pctx->proc;
|
||||||
|
+ unsigned long libc_base = proc->libc_base;
|
||||||
|
+
|
||||||
|
+ ret = ptrace(PTRACE_GETREGS, pctx->pid, NULL, &orig_regs);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kplogerror("can't get regs - %d\n", pctx->pid);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ ret = kpatch_process_mem_read(
|
||||||
|
+ proc,
|
||||||
|
+ libc_base,
|
||||||
|
+ (unsigned long *)orig_code,
|
||||||
|
+ codelen);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kplogerror("can't peek original code - %d\n", pctx->pid);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ ret = kpatch_process_mem_write(
|
||||||
|
+ proc,
|
||||||
|
+ (unsigned long *)code,
|
||||||
|
+ libc_base,
|
||||||
|
+ codelen);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kplogerror("can't poke syscall code - %d\n", pctx->pid);
|
||||||
|
+ goto poke_back;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ regs = orig_regs;
|
||||||
|
+ regs.rip = libc_base;
|
||||||
|
+
|
||||||
|
+ copy_regs(®s, pregs);
|
||||||
|
+
|
||||||
|
+ ret = ptrace(PTRACE_SETREGS, pctx->pid, NULL, ®s);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kplogerror("can't set regs - %d\n", pctx->pid);
|
||||||
|
+ goto poke_back;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = func(pctx, data);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kplogerror("failed call to func\n");
|
||||||
|
+ goto poke_back;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = ptrace(PTRACE_GETREGS, pctx->pid, NULL, ®s);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kplogerror("can't get updated regs - %d\n", pctx->pid);
|
||||||
|
+ goto poke_back;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = ptrace(PTRACE_SETREGS, pctx->pid, NULL, &orig_regs);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kplogerror("can't restore regs - %d\n", pctx->pid);
|
||||||
|
+ goto poke_back;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *pregs = regs;
|
||||||
|
+
|
||||||
|
+poke_back:
|
||||||
|
+ kpatch_process_mem_write(
|
||||||
|
+ proc,
|
||||||
|
+ (unsigned long *)orig_code,
|
||||||
|
+ libc_base,
|
||||||
|
+ codelen);
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void copy_regs(struct user_regs_struct *dst,
|
||||||
|
struct user_regs_struct *src)
|
||||||
|
{
|
||||||
|
diff --git a/src/include/kpatch_ptrace.h b/src/include/kpatch_ptrace.h
|
||||||
|
index e434d68..f35aabd 100644
|
||||||
|
--- a/src/include/kpatch_ptrace.h
|
||||||
|
+++ b/src/include/kpatch_ptrace.h
|
||||||
|
@@ -125,4 +125,13 @@ kpatch_arch_ptrace_waitpid(kpatch_process_t *proc,
|
||||||
|
void copy_regs(struct user_regs_struct *dst,
|
||||||
|
struct user_regs_struct *src);
|
||||||
|
|
||||||
|
+int
|
||||||
|
+kpatch_arch_execute_remote_func(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
+ const unsigned char *code,
|
||||||
|
+ size_t codelen,
|
||||||
|
+ struct user_regs_struct *pregs,
|
||||||
|
+ int (*func)(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
+ void *data),
|
||||||
|
+ void *data);
|
||||||
|
+
|
||||||
|
#endif
|
||||||
|
diff --git a/src/kpatch_ptrace.c b/src/kpatch_ptrace.c
|
||||||
|
index 180bbaa..9056815 100644
|
||||||
|
--- a/src/kpatch_ptrace.c
|
||||||
|
+++ b/src/kpatch_ptrace.c
|
||||||
|
@@ -413,86 +413,6 @@ poke_back:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static
|
||||||
|
-int
|
||||||
|
-kpatch_execute_remote_func(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
- const unsigned char *code,
|
||||||
|
- size_t codelen,
|
||||||
|
- struct user_regs_struct *pregs,
|
||||||
|
- int (*func)(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
- void *data),
|
||||||
|
- void *data)
|
||||||
|
-{
|
||||||
|
- struct user_regs_struct orig_regs, regs;
|
||||||
|
- unsigned char orig_code[codelen];
|
||||||
|
- int ret;
|
||||||
|
- kpatch_process_t *proc = pctx->proc;
|
||||||
|
- unsigned long libc_base = proc->libc_base;
|
||||||
|
-
|
||||||
|
- ret = ptrace(PTRACE_GETREGS, pctx->pid, NULL, &orig_regs);
|
||||||
|
- if (ret < 0) {
|
||||||
|
- kplogerror("can't get regs - %d\n", pctx->pid);
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
- ret = kpatch_process_mem_read(
|
||||||
|
- proc,
|
||||||
|
- libc_base,
|
||||||
|
- (unsigned long *)orig_code,
|
||||||
|
- codelen);
|
||||||
|
- if (ret < 0) {
|
||||||
|
- kplogerror("can't peek original code - %d\n", pctx->pid);
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
- ret = kpatch_process_mem_write(
|
||||||
|
- proc,
|
||||||
|
- (unsigned long *)code,
|
||||||
|
- libc_base,
|
||||||
|
- codelen);
|
||||||
|
- if (ret < 0) {
|
||||||
|
- kplogerror("can't poke syscall code - %d\n", pctx->pid);
|
||||||
|
- goto poke_back;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- regs = orig_regs;
|
||||||
|
- regs.rip = libc_base;
|
||||||
|
-
|
||||||
|
- copy_regs(®s, pregs);
|
||||||
|
-
|
||||||
|
- ret = ptrace(PTRACE_SETREGS, pctx->pid, NULL, ®s);
|
||||||
|
- if (ret < 0) {
|
||||||
|
- kplogerror("can't set regs - %d\n", pctx->pid);
|
||||||
|
- goto poke_back;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- ret = func(pctx, data);
|
||||||
|
- if (ret < 0) {
|
||||||
|
- kplogerror("failed call to func\n");
|
||||||
|
- goto poke_back;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- ret = ptrace(PTRACE_GETREGS, pctx->pid, NULL, ®s);
|
||||||
|
- if (ret < 0) {
|
||||||
|
- kplogerror("can't get updated regs - %d\n", pctx->pid);
|
||||||
|
- goto poke_back;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- ret = ptrace(PTRACE_SETREGS, pctx->pid, NULL, &orig_regs);
|
||||||
|
- if (ret < 0) {
|
||||||
|
- kplogerror("can't restore regs - %d\n", pctx->pid);
|
||||||
|
- goto poke_back;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- *pregs = regs;
|
||||||
|
-
|
||||||
|
-poke_back:
|
||||||
|
- kpatch_process_mem_write(
|
||||||
|
- proc,
|
||||||
|
- (unsigned long *)orig_code,
|
||||||
|
- libc_base,
|
||||||
|
- codelen);
|
||||||
|
- return ret;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static int
|
||||||
|
wait_for_stop(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
void *data)
|
||||||
|
@@ -592,7 +512,7 @@ kpatch_execute_remote(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
size_t codelen,
|
||||||
|
struct user_regs_struct *pregs)
|
||||||
|
{
|
||||||
|
- return kpatch_execute_remote_func(pctx,
|
||||||
|
+ return kpatch_arch_execute_remote_func(pctx,
|
||||||
|
code,
|
||||||
|
codelen,
|
||||||
|
pregs,
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
146
0042-kpatch_ptrace-Split-function-kpatch_ptrace_resolve_i.patch
Normal file
146
0042-kpatch_ptrace-Split-function-kpatch_ptrace_resolve_i.patch
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
From aeeded44db6e705717bd24f3ffbbe878af47833b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Date: Mon, 12 Oct 2020 16:40:42 +0800
|
||||||
|
Subject: [PATCH 42/89] kpatch_ptrace: Split function
|
||||||
|
kpatch_ptrace_resolve_ifunc
|
||||||
|
|
||||||
|
The function kpatch_ptrace_resolve_ifunc is arch related, first
|
||||||
|
rename it with kpatch_arch_ptrace_resolve_ifunc, and then make
|
||||||
|
separate definations in arch/x86/arch_ptrace.c and arch/aarch64/arch_ptrace.c
|
||||||
|
|
||||||
|
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||||
|
---
|
||||||
|
src/arch/aarch64/arch_ptrace.c | 20 ++++++++++++++++++++
|
||||||
|
src/arch/x86/arch_ptrace.c | 21 +++++++++++++++++++++
|
||||||
|
src/include/kpatch_ptrace.h | 2 +-
|
||||||
|
src/kpatch_elf.c | 4 ++--
|
||||||
|
src/kpatch_ptrace.c | 21 ---------------------
|
||||||
|
5 files changed, 44 insertions(+), 24 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/arch/aarch64/arch_ptrace.c b/src/arch/aarch64/arch_ptrace.c
|
||||||
|
index 821b4e8..4dee0e5 100644
|
||||||
|
--- a/src/arch/aarch64/arch_ptrace.c
|
||||||
|
+++ b/src/arch/aarch64/arch_ptrace.c
|
||||||
|
@@ -22,6 +22,26 @@
|
||||||
|
|
||||||
|
#include <gelf.h>
|
||||||
|
|
||||||
|
+int kpatch_arch_ptrace_resolve_ifunc(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
+ unsigned long *addr)
|
||||||
|
+{
|
||||||
|
+ struct user_regs_struct regs;
|
||||||
|
+
|
||||||
|
+ unsigned char callrax[] = {
|
||||||
|
+ 0x00, 0x01, 0x3f, 0xd6, // blr x8
|
||||||
|
+ 0xa0, 0x00, 0x20, 0xd4, // brk #5
|
||||||
|
+ };
|
||||||
|
+ int ret;
|
||||||
|
+ kpdebug("Executing callrax %lx (pid %d)\n", *addr, pctx->pid);
|
||||||
|
+ regs.regs[8] = *addr;
|
||||||
|
+
|
||||||
|
+ ret = kpatch_execute_remote(pctx, callrax, sizeof(callrax), ®s);
|
||||||
|
+ if (ret == 0)
|
||||||
|
+ *addr = regs.regs[0];
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int
|
||||||
|
kpatch_arch_execute_remote_func(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
const unsigned char *code,
|
||||||
|
diff --git a/src/arch/x86/arch_ptrace.c b/src/arch/x86/arch_ptrace.c
|
||||||
|
index 9239f52..3d49638 100644
|
||||||
|
--- a/src/arch/x86/arch_ptrace.c
|
||||||
|
+++ b/src/arch/x86/arch_ptrace.c
|
||||||
|
@@ -22,6 +22,27 @@
|
||||||
|
|
||||||
|
#include <gelf.h>
|
||||||
|
|
||||||
|
+int kpatch_arch_ptrace_resolve_ifunc(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
+ unsigned long *addr)
|
||||||
|
+{
|
||||||
|
+ struct user_regs_struct regs;
|
||||||
|
+
|
||||||
|
+ unsigned char callrax[] = {
|
||||||
|
+ 0xff, 0xd0, /* call *%rax */
|
||||||
|
+ 0xcc, /* int3 */
|
||||||
|
+ };
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ kpdebug("Executing callrax %lx (pid %d)\n", *addr, pctx->pid);
|
||||||
|
+ regs.rax = *addr;
|
||||||
|
+
|
||||||
|
+ ret = kpatch_execute_remote(pctx, callrax, sizeof(callrax), ®s);
|
||||||
|
+ if (ret == 0)
|
||||||
|
+ *addr = regs.rax;
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int
|
||||||
|
kpatch_arch_execute_remote_func(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
const unsigned char *code,
|
||||||
|
diff --git a/src/include/kpatch_ptrace.h b/src/include/kpatch_ptrace.h
|
||||||
|
index f35aabd..19a1b2c 100644
|
||||||
|
--- a/src/include/kpatch_ptrace.h
|
||||||
|
+++ b/src/include/kpatch_ptrace.h
|
||||||
|
@@ -70,7 +70,7 @@ int kpatch_execute_remote(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
size_t codelen,
|
||||||
|
struct user_regs_struct *pregs);
|
||||||
|
|
||||||
|
-int kpatch_ptrace_resolve_ifunc(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
+int kpatch_arch_ptrace_resolve_ifunc(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
unsigned long *addr);
|
||||||
|
unsigned long
|
||||||
|
kpatch_mmap_remote(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
diff --git a/src/kpatch_elf.c b/src/kpatch_elf.c
|
||||||
|
index 5506292..d443001 100644
|
||||||
|
--- a/src/kpatch_elf.c
|
||||||
|
+++ b/src/kpatch_elf.c
|
||||||
|
@@ -677,8 +677,8 @@ kpatch_resolve_undefined(struct object_file *obj,
|
||||||
|
addr = vaddr2addr(o, addr);
|
||||||
|
|
||||||
|
if (type == STT_GNU_IFUNC)
|
||||||
|
- if (kpatch_ptrace_resolve_ifunc(proc2pctx(obj->proc), &addr) < 0)
|
||||||
|
- kpfatalerror("kpatch_ptrace_resolve_ifunc failed\n");
|
||||||
|
+ if (kpatch_arch_ptrace_resolve_ifunc(proc2pctx(obj->proc), &addr) < 0)
|
||||||
|
+ kpfatalerror("kpatch_arch_ptrace_resolve_ifunc failed\n");
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
diff --git a/src/kpatch_ptrace.c b/src/kpatch_ptrace.c
|
||||||
|
index 9056815..cd961e1 100644
|
||||||
|
--- a/src/kpatch_ptrace.c
|
||||||
|
+++ b/src/kpatch_ptrace.c
|
||||||
|
@@ -672,27 +672,6 @@ static int kpatch_syscall_remote(struct kpatch_ptrace_ctx *pctx, int nr,
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
-int kpatch_ptrace_resolve_ifunc(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
- unsigned long *addr)
|
||||||
|
-{
|
||||||
|
- struct user_regs_struct regs;
|
||||||
|
-
|
||||||
|
- unsigned char callrax[] = {
|
||||||
|
- 0xff, 0xd0, /* call *%rax */
|
||||||
|
- 0xcc, /* int3 */
|
||||||
|
- };
|
||||||
|
- int ret;
|
||||||
|
-
|
||||||
|
- kpdebug("Executing callrax %lx (pid %d)\n", *addr, pctx->pid);
|
||||||
|
- regs.rax = *addr;
|
||||||
|
-
|
||||||
|
- ret = kpatch_execute_remote(pctx, callrax, sizeof(callrax), ®s);
|
||||||
|
- if (ret == 0)
|
||||||
|
- *addr = regs.rax;
|
||||||
|
-
|
||||||
|
- return ret;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
#define MAX_ERRNO 4095
|
||||||
|
unsigned long
|
||||||
|
kpatch_mmap_remote(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
213
0043-kpatch_ptrace-Split-function-kpatch_arch_prctl_remot.patch
Normal file
213
0043-kpatch_ptrace-Split-function-kpatch_arch_prctl_remot.patch
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
From aa39ba7326c13546f68b51d95bf55004437c3110 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Date: Mon, 12 Oct 2020 16:49:15 +0800
|
||||||
|
Subject: [PATCH 43/89] kpatch_ptrace: Split function kpatch_arch_prctl_remote
|
||||||
|
|
||||||
|
The function kpatch_arch_prctl_remote is arch related, let's make two
|
||||||
|
separate definations in arch/x86/arch_ptrace.c and arch/aarch64/arch_ptrace.c
|
||||||
|
|
||||||
|
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||||
|
---
|
||||||
|
src/arch/aarch64/arch_ptrace.c | 49 ++++++++++++++++++++++++++++++++++
|
||||||
|
src/arch/x86/arch_ptrace.c | 45 +++++++++++++++++++++++++++++++
|
||||||
|
src/include/kpatch_ptrace.h | 2 ++
|
||||||
|
src/kpatch_ptrace.c | 46 -------------------------------
|
||||||
|
4 files changed, 96 insertions(+), 46 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/arch/aarch64/arch_ptrace.c b/src/arch/aarch64/arch_ptrace.c
|
||||||
|
index 4dee0e5..735927e 100644
|
||||||
|
--- a/src/arch/aarch64/arch_ptrace.c
|
||||||
|
+++ b/src/arch/aarch64/arch_ptrace.c
|
||||||
|
@@ -22,6 +22,55 @@
|
||||||
|
|
||||||
|
#include <gelf.h>
|
||||||
|
|
||||||
|
+int kpatch_arch_prctl_remote(struct kpatch_ptrace_ctx *pctx, int code, unsigned long *addr)
|
||||||
|
+{
|
||||||
|
+ struct user_regs_struct regs;
|
||||||
|
+ struct iovec regs_iov;
|
||||||
|
+ regs_iov.iov_base = ®s;
|
||||||
|
+ regs_iov.iov_len = sizeof(regs);
|
||||||
|
+
|
||||||
|
+ unsigned long res, sp;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ kpdebug("arch_prctl_remote: %d, %p\n", code, addr);
|
||||||
|
+ ret = ptrace(PTRACE_GETREGSET, pctx->pid, (void*)NT_PRSTATUS, (void*)®s_iov);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kpdebug("FAIL. Can't get regs - %s\n", strerror(errno));
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ ret = kpatch_process_mem_read(pctx->proc,
|
||||||
|
+ regs.sp,
|
||||||
|
+ &sp,
|
||||||
|
+ sizeof(sp));
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kplogerror("can't peek original stack data\n");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ //ret = kpatch_syscall_remote(pctx, __NR_arch_prctl, code, regs.sp, 0, 0, 0, 0, &res);
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ goto poke;
|
||||||
|
+ if (ret == 0 && res >= (unsigned long)-MAX_ERRNO) {
|
||||||
|
+ errno = -(long)res;
|
||||||
|
+ ret = -1;
|
||||||
|
+ goto poke;
|
||||||
|
+ }
|
||||||
|
+ ret = kpatch_process_mem_read(pctx->proc,
|
||||||
|
+ regs.sp,
|
||||||
|
+ &res,
|
||||||
|
+ sizeof(res));
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ kplogerror("can't peek new stack data\n");
|
||||||
|
+
|
||||||
|
+poke:
|
||||||
|
+ if (kpatch_process_mem_write(pctx->proc,
|
||||||
|
+ &sp,
|
||||||
|
+ regs.sp,
|
||||||
|
+ sizeof(sp)))
|
||||||
|
+ kplogerror("can't poke orig stack data\n");
|
||||||
|
+ *addr = res;
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int kpatch_arch_ptrace_resolve_ifunc(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
unsigned long *addr)
|
||||||
|
{
|
||||||
|
diff --git a/src/arch/x86/arch_ptrace.c b/src/arch/x86/arch_ptrace.c
|
||||||
|
index 3d49638..5f1e703 100644
|
||||||
|
--- a/src/arch/x86/arch_ptrace.c
|
||||||
|
+++ b/src/arch/x86/arch_ptrace.c
|
||||||
|
@@ -22,6 +22,51 @@
|
||||||
|
|
||||||
|
#include <gelf.h>
|
||||||
|
|
||||||
|
+int kpatch_arch_prctl_remote(struct kpatch_ptrace_ctx *pctx, int code, unsigned long *addr)
|
||||||
|
+{
|
||||||
|
+ struct user_regs_struct regs;
|
||||||
|
+ unsigned long res, rsp;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ kpdebug("arch_prctl_remote: %d, %p\n", code, addr);
|
||||||
|
+ ret = ptrace(PTRACE_GETREGS, pctx->pid, NULL, ®s);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kpdebug("FAIL. Can't get regs - %s\n", strerror(errno));
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ ret = kpatch_process_mem_read(pctx->proc,
|
||||||
|
+ regs.rsp,
|
||||||
|
+ &rsp,
|
||||||
|
+ sizeof(rsp));
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kplogerror("can't peek original stack data\n");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ ret = kpatch_syscall_remote(pctx, __NR_arch_prctl, code, regs.rsp, 0, 0, 0, 0, &res);
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ goto poke;
|
||||||
|
+ if (ret == 0 && res >= (unsigned long)-MAX_ERRNO) {
|
||||||
|
+ errno = -(long)res;
|
||||||
|
+ ret = -1;
|
||||||
|
+ goto poke;
|
||||||
|
+ }
|
||||||
|
+ ret = kpatch_process_mem_read(pctx->proc,
|
||||||
|
+ regs.rsp,
|
||||||
|
+ &res,
|
||||||
|
+ sizeof(res));
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ kplogerror("can't peek new stack data\n");
|
||||||
|
+
|
||||||
|
+poke:
|
||||||
|
+ if (kpatch_process_mem_write(pctx->proc,
|
||||||
|
+ &rsp,
|
||||||
|
+ regs.rsp,
|
||||||
|
+ sizeof(rsp)))
|
||||||
|
+ kplogerror("can't poke orig stack data\n");
|
||||||
|
+ *addr = res;
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int kpatch_arch_ptrace_resolve_ifunc(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
unsigned long *addr)
|
||||||
|
{
|
||||||
|
diff --git a/src/include/kpatch_ptrace.h b/src/include/kpatch_ptrace.h
|
||||||
|
index 19a1b2c..ddaa9e6 100644
|
||||||
|
--- a/src/include/kpatch_ptrace.h
|
||||||
|
+++ b/src/include/kpatch_ptrace.h
|
||||||
|
@@ -84,6 +84,8 @@ int
|
||||||
|
kpatch_munmap_remote(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
unsigned long addr,
|
||||||
|
size_t length);
|
||||||
|
+
|
||||||
|
+#define MAX_ERRNO 4095
|
||||||
|
int kpatch_arch_prctl_remote(struct kpatch_ptrace_ctx *pctx, int code, unsigned long *addr);
|
||||||
|
|
||||||
|
int
|
||||||
|
diff --git a/src/kpatch_ptrace.c b/src/kpatch_ptrace.c
|
||||||
|
index cd961e1..4d2223e 100644
|
||||||
|
--- a/src/kpatch_ptrace.c
|
||||||
|
+++ b/src/kpatch_ptrace.c
|
||||||
|
@@ -672,7 +672,6 @@ static int kpatch_syscall_remote(struct kpatch_ptrace_ctx *pctx, int nr,
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
-#define MAX_ERRNO 4095
|
||||||
|
unsigned long
|
||||||
|
kpatch_mmap_remote(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
unsigned long addr,
|
||||||
|
@@ -717,51 +716,6 @@ int kpatch_munmap_remote(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-int kpatch_arch_prctl_remote(struct kpatch_ptrace_ctx *pctx, int code, unsigned long *addr)
|
||||||
|
-{
|
||||||
|
- struct user_regs_struct regs;
|
||||||
|
- unsigned long res, rsp;
|
||||||
|
- int ret;
|
||||||
|
-
|
||||||
|
- kpdebug("arch_prctl_remote: %d, %p\n", code, addr);
|
||||||
|
- ret = ptrace(PTRACE_GETREGS, pctx->pid, NULL, ®s);
|
||||||
|
- if (ret < 0) {
|
||||||
|
- kpdebug("FAIL. Can't get regs - %s\n", strerror(errno));
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
- ret = kpatch_process_mem_read(pctx->proc,
|
||||||
|
- regs.rsp,
|
||||||
|
- &rsp,
|
||||||
|
- sizeof(rsp));
|
||||||
|
- if (ret < 0) {
|
||||||
|
- kplogerror("can't peek original stack data\n");
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
- ret = kpatch_syscall_remote(pctx, __NR_arch_prctl, code, regs.rsp, 0, 0, 0, 0, &res);
|
||||||
|
- if (ret < 0)
|
||||||
|
- goto poke;
|
||||||
|
- if (ret == 0 && res >= (unsigned long)-MAX_ERRNO) {
|
||||||
|
- errno = -(long)res;
|
||||||
|
- ret = -1;
|
||||||
|
- goto poke;
|
||||||
|
- }
|
||||||
|
- ret = kpatch_process_mem_read(pctx->proc,
|
||||||
|
- regs.rsp,
|
||||||
|
- &res,
|
||||||
|
- sizeof(res));
|
||||||
|
- if (ret < 0)
|
||||||
|
- kplogerror("can't peek new stack data\n");
|
||||||
|
-
|
||||||
|
-poke:
|
||||||
|
- if (kpatch_process_mem_write(pctx->proc,
|
||||||
|
- &rsp,
|
||||||
|
- regs.rsp,
|
||||||
|
- sizeof(rsp)))
|
||||||
|
- kplogerror("can't poke orig stack data\n");
|
||||||
|
- *addr = res;
|
||||||
|
- return ret;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
int
|
||||||
|
kpatch_remote_write(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
unsigned long dst,
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
191
0044-kpatch_ptrace-Split-function-kpatch_syscall_remote.patch
Normal file
191
0044-kpatch_ptrace-Split-function-kpatch_syscall_remote.patch
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
From 335b90a54e629e0dc2f954ec2c3bd0b7e149aeec Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Date: Mon, 12 Oct 2020 16:55:27 +0800
|
||||||
|
Subject: [PATCH 44/89] kpatch_ptrace: Split function kpatch_syscall_remote
|
||||||
|
|
||||||
|
The function kpatch_syscall_remote is arch related, first
|
||||||
|
rename it with kpatch_arch_syscall_remote, and then make
|
||||||
|
separate definations in arch/x86/arch_ptrace.c and arch/aarch64/arch_ptrace.c
|
||||||
|
|
||||||
|
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||||
|
---
|
||||||
|
src/arch/aarch64/arch_ptrace.c | 31 ++++++++++++++++++++++++++++++-
|
||||||
|
src/arch/x86/arch_ptrace.c | 31 ++++++++++++++++++++++++++++++-
|
||||||
|
src/include/kpatch_ptrace.h | 5 +++++
|
||||||
|
src/kpatch_ptrace.c | 33 ++-------------------------------
|
||||||
|
4 files changed, 67 insertions(+), 33 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/arch/aarch64/arch_ptrace.c b/src/arch/aarch64/arch_ptrace.c
|
||||||
|
index 735927e..a444285 100644
|
||||||
|
--- a/src/arch/aarch64/arch_ptrace.c
|
||||||
|
+++ b/src/arch/aarch64/arch_ptrace.c
|
||||||
|
@@ -22,6 +22,35 @@
|
||||||
|
|
||||||
|
#include <gelf.h>
|
||||||
|
|
||||||
|
+int kpatch_arch_syscall_remote(struct kpatch_ptrace_ctx *pctx, int nr,
|
||||||
|
+ unsigned long arg1, unsigned long arg2, unsigned long arg3,
|
||||||
|
+ unsigned long arg4, unsigned long arg5, unsigned long arg6,
|
||||||
|
+ unsigned long *res)
|
||||||
|
+{
|
||||||
|
+ struct user_regs_struct regs;
|
||||||
|
+
|
||||||
|
+ unsigned char syscall[] = {
|
||||||
|
+ 0x01, 0x00, 0x00, 0xd4, //0xd4000001 svc #0 = syscall
|
||||||
|
+ 0xa0, 0x00, 0x20, 0xd4, //0xd42000a0 brk #5 = int3
|
||||||
|
+ };
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ kpdebug("Executing syscall %d (pid %d)...\n", nr, pctx->pid);
|
||||||
|
+ regs.regs[8] = (unsigned long)nr;
|
||||||
|
+ regs.regs[0] = arg1;
|
||||||
|
+ regs.regs[1] = arg2;
|
||||||
|
+ regs.regs[2] = arg3;
|
||||||
|
+ regs.regs[3] = arg4;
|
||||||
|
+ regs.regs[4] = arg5;
|
||||||
|
+ regs.regs[5] = arg6;
|
||||||
|
+
|
||||||
|
+ ret = kpatch_execute_remote(pctx, syscall, sizeof(syscall), ®s);
|
||||||
|
+ if (ret == 0)
|
||||||
|
+ *res = regs.regs[0];
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int kpatch_arch_prctl_remote(struct kpatch_ptrace_ctx *pctx, int code, unsigned long *addr)
|
||||||
|
{
|
||||||
|
struct user_regs_struct regs;
|
||||||
|
@@ -46,7 +75,7 @@ int kpatch_arch_prctl_remote(struct kpatch_ptrace_ctx *pctx, int code, unsigned
|
||||||
|
kplogerror("can't peek original stack data\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
- //ret = kpatch_syscall_remote(pctx, __NR_arch_prctl, code, regs.sp, 0, 0, 0, 0, &res);
|
||||||
|
+ //ret = kpatch_arch_syscall_remote(pctx, __NR_arch_prctl, code, regs.sp, 0, 0, 0, 0, &res);
|
||||||
|
if (ret < 0)
|
||||||
|
goto poke;
|
||||||
|
if (ret == 0 && res >= (unsigned long)-MAX_ERRNO) {
|
||||||
|
diff --git a/src/arch/x86/arch_ptrace.c b/src/arch/x86/arch_ptrace.c
|
||||||
|
index 5f1e703..10127a3 100644
|
||||||
|
--- a/src/arch/x86/arch_ptrace.c
|
||||||
|
+++ b/src/arch/x86/arch_ptrace.c
|
||||||
|
@@ -22,6 +22,35 @@
|
||||||
|
|
||||||
|
#include <gelf.h>
|
||||||
|
|
||||||
|
+int kpatch_arch_syscall_remote(struct kpatch_ptrace_ctx *pctx, int nr,
|
||||||
|
+ unsigned long arg1, unsigned long arg2, unsigned long arg3,
|
||||||
|
+ unsigned long arg4, unsigned long arg5, unsigned long arg6,
|
||||||
|
+ unsigned long *res)
|
||||||
|
+{
|
||||||
|
+ struct user_regs_struct regs;
|
||||||
|
+
|
||||||
|
+ unsigned char syscall[] = {
|
||||||
|
+ 0x0f, 0x05, /* syscall */
|
||||||
|
+ 0xcc, /* int3 */
|
||||||
|
+ };
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ kpdebug("Executing syscall %d (pid %d)...\n", nr, pctx->pid);
|
||||||
|
+ regs.rax = (unsigned long)nr;
|
||||||
|
+ regs.rdi = arg1;
|
||||||
|
+ regs.rsi = arg2;
|
||||||
|
+ regs.rdx = arg3;
|
||||||
|
+ regs.r10 = arg4;
|
||||||
|
+ regs.r8 = arg5;
|
||||||
|
+ regs.r9 = arg6;
|
||||||
|
+
|
||||||
|
+ ret = kpatch_execute_remote(pctx, syscall, sizeof(syscall), ®s);
|
||||||
|
+ if (ret == 0)
|
||||||
|
+ *res = regs.rax;
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int kpatch_arch_prctl_remote(struct kpatch_ptrace_ctx *pctx, int code, unsigned long *addr)
|
||||||
|
{
|
||||||
|
struct user_regs_struct regs;
|
||||||
|
@@ -42,7 +71,7 @@ int kpatch_arch_prctl_remote(struct kpatch_ptrace_ctx *pctx, int code, unsigned
|
||||||
|
kplogerror("can't peek original stack data\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
- ret = kpatch_syscall_remote(pctx, __NR_arch_prctl, code, regs.rsp, 0, 0, 0, 0, &res);
|
||||||
|
+ ret = kpatch_arch_syscall_remote(pctx, __NR_arch_prctl, code, regs.rsp, 0, 0, 0, 0, &res);
|
||||||
|
if (ret < 0)
|
||||||
|
goto poke;
|
||||||
|
if (ret == 0 && res >= (unsigned long)-MAX_ERRNO) {
|
||||||
|
diff --git a/src/include/kpatch_ptrace.h b/src/include/kpatch_ptrace.h
|
||||||
|
index ddaa9e6..c8cfd41 100644
|
||||||
|
--- a/src/include/kpatch_ptrace.h
|
||||||
|
+++ b/src/include/kpatch_ptrace.h
|
||||||
|
@@ -136,4 +136,9 @@ kpatch_arch_execute_remote_func(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
void *data),
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
+int kpatch_arch_syscall_remote(struct kpatch_ptrace_ctx *pctx, int nr,
|
||||||
|
+ unsigned long arg1, unsigned long arg2, unsigned long arg3,
|
||||||
|
+ unsigned long arg4, unsigned long arg5, unsigned long arg6,
|
||||||
|
+ unsigned long *res);
|
||||||
|
+
|
||||||
|
#endif
|
||||||
|
diff --git a/src/kpatch_ptrace.c b/src/kpatch_ptrace.c
|
||||||
|
index 4d2223e..057b08a 100644
|
||||||
|
--- a/src/kpatch_ptrace.c
|
||||||
|
+++ b/src/kpatch_ptrace.c
|
||||||
|
@@ -643,35 +643,6 @@ kpatch_ptrace_kickstart_execve_wrapper(kpatch_process_t *proc)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int kpatch_syscall_remote(struct kpatch_ptrace_ctx *pctx, int nr,
|
||||||
|
- unsigned long arg1, unsigned long arg2, unsigned long arg3,
|
||||||
|
- unsigned long arg4, unsigned long arg5, unsigned long arg6,
|
||||||
|
- unsigned long *res)
|
||||||
|
-{
|
||||||
|
- struct user_regs_struct regs;
|
||||||
|
-
|
||||||
|
- unsigned char syscall[] = {
|
||||||
|
- 0x0f, 0x05, /* syscall */
|
||||||
|
- 0xcc, /* int3 */
|
||||||
|
- };
|
||||||
|
- int ret;
|
||||||
|
-
|
||||||
|
- kpdebug("Executing syscall %d (pid %d)...\n", nr, pctx->pid);
|
||||||
|
- regs.rax = (unsigned long)nr;
|
||||||
|
- regs.rdi = arg1;
|
||||||
|
- regs.rsi = arg2;
|
||||||
|
- regs.rdx = arg3;
|
||||||
|
- regs.r10 = arg4;
|
||||||
|
- regs.r8 = arg5;
|
||||||
|
- regs.r9 = arg6;
|
||||||
|
-
|
||||||
|
- ret = kpatch_execute_remote(pctx, syscall, sizeof(syscall), ®s);
|
||||||
|
- if (ret == 0)
|
||||||
|
- *res = regs.rax;
|
||||||
|
-
|
||||||
|
- return ret;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
unsigned long
|
||||||
|
kpatch_mmap_remote(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
unsigned long addr,
|
||||||
|
@@ -686,7 +657,7 @@ kpatch_mmap_remote(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
|
||||||
|
kpdebug("mmap_remote: 0x%lx+%lx, %x, %x, %d, %lx\n", addr, length,
|
||||||
|
prot, flags, fd, offset);
|
||||||
|
- ret = kpatch_syscall_remote(pctx, __NR_mmap, (unsigned long)addr,
|
||||||
|
+ ret = kpatch_arch_syscall_remote(pctx, __NR_mmap, (unsigned long)addr,
|
||||||
|
length, prot, flags, fd, offset, &res);
|
||||||
|
if (ret < 0)
|
||||||
|
return 0;
|
||||||
|
@@ -705,7 +676,7 @@ int kpatch_munmap_remote(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
unsigned long res;
|
||||||
|
|
||||||
|
kpdebug("munmap_remote: 0x%lx+%lx\n", addr, length);
|
||||||
|
- ret = kpatch_syscall_remote(pctx, __NR_munmap, (unsigned long)addr,
|
||||||
|
+ ret = kpatch_arch_syscall_remote(pctx, __NR_munmap, (unsigned long)addr,
|
||||||
|
length, 0, 0, 0, 0, &res);
|
||||||
|
if (ret < 0)
|
||||||
|
return -1;
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
239
0045-kpatch_ptrace-Split-function-wait_for_mmap.patch
Normal file
239
0045-kpatch_ptrace-Split-function-wait_for_mmap.patch
Normal file
@ -0,0 +1,239 @@
|
|||||||
|
From 05b64620354b8f8bd36c3f782eff9cd145f57fea Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Date: Tue, 13 Oct 2020 11:10:11 +0800
|
||||||
|
Subject: [PATCH 45/89] kpatch_ptrace: Split function wait_for_mmap
|
||||||
|
|
||||||
|
The function wait_for_mmap is arch related, so make two separate
|
||||||
|
definations in arch/x86/arch_ptrace.c and arch/aarch64/arch_ptrace.c
|
||||||
|
|
||||||
|
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||||
|
---
|
||||||
|
src/arch/aarch64/arch_ptrace.c | 58 ++++++++++++++++++++++++++++++++++
|
||||||
|
src/arch/x86/arch_ptrace.c | 58 ++++++++++++++++++++++++++++++++++
|
||||||
|
src/include/kpatch_ptrace.h | 3 ++
|
||||||
|
src/kpatch_ptrace.c | 58 ----------------------------------
|
||||||
|
4 files changed, 119 insertions(+), 58 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/arch/aarch64/arch_ptrace.c b/src/arch/aarch64/arch_ptrace.c
|
||||||
|
index a444285..b21189e 100644
|
||||||
|
--- a/src/arch/aarch64/arch_ptrace.c
|
||||||
|
+++ b/src/arch/aarch64/arch_ptrace.c
|
||||||
|
@@ -22,6 +22,64 @@
|
||||||
|
|
||||||
|
#include <gelf.h>
|
||||||
|
|
||||||
|
+int
|
||||||
|
+wait_for_mmap(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
+ unsigned long *pbase)
|
||||||
|
+{
|
||||||
|
+ int ret, status = 0, insyscall = 0;
|
||||||
|
+ long rv;
|
||||||
|
+
|
||||||
|
+ while (1) {
|
||||||
|
+ ret = ptrace(PTRACE_SYSCALL, pctx->pid, NULL,
|
||||||
|
+ (void *)(uintptr_t)status);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kplogerror("can't PTRACE_SYSCALL tracee - %d\n",
|
||||||
|
+ pctx->pid);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = waitpid(pctx->pid, &status, __WALL);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kplogerror("can't wait tracee - %d\n", pctx->pid);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (WIFEXITED(status)) {
|
||||||
|
+ status = WTERMSIG(status);
|
||||||
|
+ continue;
|
||||||
|
+ } else if (!WIFSTOPPED(status)) {
|
||||||
|
+ status = 0;
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ status = 0;
|
||||||
|
+
|
||||||
|
+ if (insyscall == 0) {
|
||||||
|
+ rv = ptrace(PTRACE_PEEKUSER, pctx->pid,
|
||||||
|
+ offsetof(struct user_regs_struct,
|
||||||
|
+ regs[29]),
|
||||||
|
+ NULL);
|
||||||
|
+ if (rv == -1) {
|
||||||
|
+ kplogerror("ptrace(PTRACE_PEEKUSER)\n");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ insyscall = rv;
|
||||||
|
+ continue;
|
||||||
|
+ } else if (insyscall == __NR_mmap) {
|
||||||
|
+ rv = ptrace(PTRACE_PEEKUSER, pctx->pid,
|
||||||
|
+ offsetof(struct user_regs_struct,
|
||||||
|
+ regs[8]),
|
||||||
|
+ NULL);
|
||||||
|
+ *pbase = rv;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ insyscall = !insyscall;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int kpatch_arch_syscall_remote(struct kpatch_ptrace_ctx *pctx, int nr,
|
||||||
|
unsigned long arg1, unsigned long arg2, unsigned long arg3,
|
||||||
|
unsigned long arg4, unsigned long arg5, unsigned long arg6,
|
||||||
|
diff --git a/src/arch/x86/arch_ptrace.c b/src/arch/x86/arch_ptrace.c
|
||||||
|
index 10127a3..0032cbd 100644
|
||||||
|
--- a/src/arch/x86/arch_ptrace.c
|
||||||
|
+++ b/src/arch/x86/arch_ptrace.c
|
||||||
|
@@ -22,6 +22,64 @@
|
||||||
|
|
||||||
|
#include <gelf.h>
|
||||||
|
|
||||||
|
+int
|
||||||
|
+wait_for_mmap(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
+ unsigned long *pbase)
|
||||||
|
+{
|
||||||
|
+ int ret, status = 0, insyscall = 0;
|
||||||
|
+ long rv;
|
||||||
|
+
|
||||||
|
+ while (1) {
|
||||||
|
+ ret = ptrace(PTRACE_SYSCALL, pctx->pid, NULL,
|
||||||
|
+ (void *)(uintptr_t)status);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kplogerror("can't PTRACE_SYSCALL tracee - %d\n",
|
||||||
|
+ pctx->pid);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = waitpid(pctx->pid, &status, __WALL);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kplogerror("can't wait tracee - %d\n", pctx->pid);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (WIFEXITED(status)) {
|
||||||
|
+ status = WTERMSIG(status);
|
||||||
|
+ continue;
|
||||||
|
+ } else if (!WIFSTOPPED(status)) {
|
||||||
|
+ status = 0;
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ status = 0;
|
||||||
|
+
|
||||||
|
+ if (insyscall == 0) {
|
||||||
|
+ rv = ptrace(PTRACE_PEEKUSER, pctx->pid,
|
||||||
|
+ offsetof(struct user_regs_struct,
|
||||||
|
+ orig_rax),
|
||||||
|
+ NULL);
|
||||||
|
+ if (rv == -1) {
|
||||||
|
+ kplogerror("ptrace(PTRACE_PEEKUSER)\n");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ insyscall = rv;
|
||||||
|
+ continue;
|
||||||
|
+ } else if (insyscall == __NR_mmap) {
|
||||||
|
+ rv = ptrace(PTRACE_PEEKUSER, pctx->pid,
|
||||||
|
+ offsetof(struct user_regs_struct,
|
||||||
|
+ rax),
|
||||||
|
+ NULL);
|
||||||
|
+ *pbase = rv;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ insyscall = !insyscall;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int kpatch_arch_syscall_remote(struct kpatch_ptrace_ctx *pctx, int nr,
|
||||||
|
unsigned long arg1, unsigned long arg2, unsigned long arg3,
|
||||||
|
unsigned long arg4, unsigned long arg5, unsigned long arg6,
|
||||||
|
diff --git a/src/include/kpatch_ptrace.h b/src/include/kpatch_ptrace.h
|
||||||
|
index c8cfd41..5abcf26 100644
|
||||||
|
--- a/src/include/kpatch_ptrace.h
|
||||||
|
+++ b/src/include/kpatch_ptrace.h
|
||||||
|
@@ -141,4 +141,7 @@ int kpatch_arch_syscall_remote(struct kpatch_ptrace_ctx *pctx, int nr,
|
||||||
|
unsigned long arg4, unsigned long arg5, unsigned long arg6,
|
||||||
|
unsigned long *res);
|
||||||
|
|
||||||
|
+int wait_for_mmap(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
+ unsigned long *pbase);
|
||||||
|
+
|
||||||
|
#endif
|
||||||
|
diff --git a/src/kpatch_ptrace.c b/src/kpatch_ptrace.c
|
||||||
|
index 057b08a..7ab550c 100644
|
||||||
|
--- a/src/kpatch_ptrace.c
|
||||||
|
+++ b/src/kpatch_ptrace.c
|
||||||
|
@@ -448,64 +448,6 @@ wait_for_stop(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int
|
||||||
|
-wait_for_mmap(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
- unsigned long *pbase)
|
||||||
|
-{
|
||||||
|
- int ret, status = 0, insyscall = 0;
|
||||||
|
- long rv;
|
||||||
|
-
|
||||||
|
- while (1) {
|
||||||
|
- ret = ptrace(PTRACE_SYSCALL, pctx->pid, NULL,
|
||||||
|
- (void *)(uintptr_t)status);
|
||||||
|
- if (ret < 0) {
|
||||||
|
- kplogerror("can't PTRACE_SYSCALL tracee - %d\n",
|
||||||
|
- pctx->pid);
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- ret = waitpid(pctx->pid, &status, __WALL);
|
||||||
|
- if (ret < 0) {
|
||||||
|
- kplogerror("can't wait tracee - %d\n", pctx->pid);
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (WIFEXITED(status)) {
|
||||||
|
- status = WTERMSIG(status);
|
||||||
|
- continue;
|
||||||
|
- } else if (!WIFSTOPPED(status)) {
|
||||||
|
- status = 0;
|
||||||
|
- continue;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- status = 0;
|
||||||
|
-
|
||||||
|
- if (insyscall == 0) {
|
||||||
|
- rv = ptrace(PTRACE_PEEKUSER, pctx->pid,
|
||||||
|
- offsetof(struct user_regs_struct,
|
||||||
|
- orig_rax),
|
||||||
|
- NULL);
|
||||||
|
- if (rv == -1) {
|
||||||
|
- kplogerror("ptrace(PTRACE_PEEKUSER)\n");
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
- insyscall = rv;
|
||||||
|
- continue;
|
||||||
|
- } else if (insyscall == __NR_mmap) {
|
||||||
|
- rv = ptrace(PTRACE_PEEKUSER, pctx->pid,
|
||||||
|
- offsetof(struct user_regs_struct,
|
||||||
|
- rax),
|
||||||
|
- NULL);
|
||||||
|
- *pbase = rv;
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- insyscall = !insyscall;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- return 0;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
int
|
||||||
|
kpatch_execute_remote(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
const unsigned char *code,
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
401
0046-kpatch_ptrace-Split-function-kpatch_ptrace_kickstart.patch
Normal file
401
0046-kpatch_ptrace-Split-function-kpatch_ptrace_kickstart.patch
Normal file
@ -0,0 +1,401 @@
|
|||||||
|
From f53cbbe63cbe16b2b0eb0466b5c85ea35f68da2b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Date: Tue, 13 Oct 2020 11:22:27 +0800
|
||||||
|
Subject: [PATCH 46/89] kpatch_ptrace: Split function
|
||||||
|
kpatch_ptrace_kickstart_execve_wrapper
|
||||||
|
|
||||||
|
The function kpatch_ptrace_kickstart_execve_wrapper is arch related,
|
||||||
|
first rename it with kpatch_arch_ptrace_kickstart_execve_wrapper,
|
||||||
|
and then make separate definations in arch/x86/arch_ptrace.c and
|
||||||
|
arch/aarch64/arch_ptrace.c
|
||||||
|
|
||||||
|
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
|
||||||
|
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||||
|
---
|
||||||
|
src/arch/aarch64/arch_ptrace.c | 99 +++++++++++++++++++++++++++++++
|
||||||
|
src/arch/x86/arch_ptrace.c | 99 +++++++++++++++++++++++++++++++
|
||||||
|
src/include/kpatch_ptrace.h | 5 +-
|
||||||
|
src/kpatch_process.c | 2 +-
|
||||||
|
src/kpatch_ptrace.c | 103 +--------------------------------
|
||||||
|
5 files changed, 205 insertions(+), 103 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/arch/aarch64/arch_ptrace.c b/src/arch/aarch64/arch_ptrace.c
|
||||||
|
index b21189e..9f87d10 100644
|
||||||
|
--- a/src/arch/aarch64/arch_ptrace.c
|
||||||
|
+++ b/src/arch/aarch64/arch_ptrace.c
|
||||||
|
@@ -22,6 +22,105 @@
|
||||||
|
|
||||||
|
#include <gelf.h>
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * This is rather tricky since we are accounting for the non-main
|
||||||
|
+ * thread calling for execve(). See `ptrace(2)` for details.
|
||||||
|
+ *
|
||||||
|
+ * FIXME(pboldin): this is broken for multi-threaded calls
|
||||||
|
+ * to execve. Sight.
|
||||||
|
+ */
|
||||||
|
+int
|
||||||
|
+kpatch_arch_ptrace_kickstart_execve_wrapper(kpatch_process_t *proc)
|
||||||
|
+{
|
||||||
|
+ int ret, pid = 0;
|
||||||
|
+ struct kpatch_ptrace_ctx *pctx, *ptmp, *execve_pctx = NULL;
|
||||||
|
+ long rv;
|
||||||
|
+
|
||||||
|
+ kpdebug("kpatch_arch_ptrace_kickstart_execve_wrapper\n");
|
||||||
|
+
|
||||||
|
+ list_for_each_entry(pctx, &proc->ptrace.pctxs, list) {
|
||||||
|
+ /* proc->pid equals to THREAD ID of the thread
|
||||||
|
+ * executing execve.so's version of execve
|
||||||
|
+ */
|
||||||
|
+ if (pctx->pid != proc->pid)
|
||||||
|
+ continue;
|
||||||
|
+ execve_pctx = pctx;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (execve_pctx == NULL) {
|
||||||
|
+ kperr("can't find thread executing execve");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Send a message to our `execve` wrapper so it will continue
|
||||||
|
+ * execution
|
||||||
|
+ */
|
||||||
|
+ ret = send(proc->send_fd, &ret, sizeof(ret), 0);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kplogerror("send failed\n");
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Wait for it to reach BRKN instruction just before real execve */
|
||||||
|
+ while (1) {
|
||||||
|
+ ret = wait_for_stop(execve_pctx, NULL);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kplogerror("wait_for_stop\n");
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ rv = ptrace(PTRACE_PEEKUSER, execve_pctx->pid,
|
||||||
|
+ offsetof(struct user_regs_struct, pc),
|
||||||
|
+ NULL);
|
||||||
|
+ if (rv == -1)
|
||||||
|
+ return rv;
|
||||||
|
+
|
||||||
|
+ rv = ptrace(PTRACE_PEEKTEXT, execve_pctx->pid,
|
||||||
|
+ rv - 1, NULL);
|
||||||
|
+ if (rv == -1)
|
||||||
|
+ return rv;
|
||||||
|
+ if ((unsigned char)rv == 0xcc)
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Wait for SIGTRAP from the execve. It happens from the thread
|
||||||
|
+ * group ID, so find it if thread doing execve() is not it. */
|
||||||
|
+ if (execve_pctx != proc2pctx(proc)) {
|
||||||
|
+ pid = get_threadgroup_id(proc->pid);
|
||||||
|
+ if (pid < 0)
|
||||||
|
+ return -1;
|
||||||
|
+
|
||||||
|
+ proc->pid = pid;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = wait_for_stop(execve_pctx, (void *)(uintptr_t)pid);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kplogerror("waitpid\n");
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ list_for_each_entry_safe(pctx, ptmp, &proc->ptrace.pctxs, list) {
|
||||||
|
+ if (pctx->pid == proc->pid)
|
||||||
|
+ continue;
|
||||||
|
+ kpatch_ptrace_detach(pctx);
|
||||||
|
+ kpatch_ptrace_ctx_destroy(pctx);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Suddenly, /proc/pid/mem gets invalidated */
|
||||||
|
+ {
|
||||||
|
+ char buf[128];
|
||||||
|
+ close(proc->memfd);
|
||||||
|
+
|
||||||
|
+ snprintf(buf, sizeof(buf), "/proc/%d/mem", proc->pid);
|
||||||
|
+ proc->memfd = open(buf, O_RDWR);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ kpdebug("...done\n");
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int
|
||||||
|
wait_for_mmap(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
unsigned long *pbase)
|
||||||
|
diff --git a/src/arch/x86/arch_ptrace.c b/src/arch/x86/arch_ptrace.c
|
||||||
|
index 0032cbd..ef0f460 100644
|
||||||
|
--- a/src/arch/x86/arch_ptrace.c
|
||||||
|
+++ b/src/arch/x86/arch_ptrace.c
|
||||||
|
@@ -22,6 +22,105 @@
|
||||||
|
|
||||||
|
#include <gelf.h>
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * This is rather tricky since we are accounting for the non-main
|
||||||
|
+ * thread calling for execve(). See `ptrace(2)` for details.
|
||||||
|
+ *
|
||||||
|
+ * FIXME(pboldin): this is broken for multi-threaded calls
|
||||||
|
+ * to execve. Sight.
|
||||||
|
+ */
|
||||||
|
+int
|
||||||
|
+kpatch_arch_ptrace_kickstart_execve_wrapper(kpatch_process_t *proc)
|
||||||
|
+{
|
||||||
|
+ int ret, pid = 0;
|
||||||
|
+ struct kpatch_ptrace_ctx *pctx, *ptmp, *execve_pctx = NULL;
|
||||||
|
+ long rv;
|
||||||
|
+
|
||||||
|
+ kpdebug("kpatch_arch_ptrace_kickstart_execve_wrapper\n");
|
||||||
|
+
|
||||||
|
+ list_for_each_entry(pctx, &proc->ptrace.pctxs, list) {
|
||||||
|
+ /* proc->pid equals to THREAD ID of the thread
|
||||||
|
+ * executing execve.so's version of execve
|
||||||
|
+ */
|
||||||
|
+ if (pctx->pid != proc->pid)
|
||||||
|
+ continue;
|
||||||
|
+ execve_pctx = pctx;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (execve_pctx == NULL) {
|
||||||
|
+ kperr("can't find thread executing execve");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Send a message to our `execve` wrapper so it will continue
|
||||||
|
+ * execution
|
||||||
|
+ */
|
||||||
|
+ ret = send(proc->send_fd, &ret, sizeof(ret), 0);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kplogerror("send failed\n");
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Wait for it to reach BRKN instruction just before real execve */
|
||||||
|
+ while (1) {
|
||||||
|
+ ret = wait_for_stop(execve_pctx, NULL);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kplogerror("wait_for_stop\n");
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ rv = ptrace(PTRACE_PEEKUSER, execve_pctx->pid,
|
||||||
|
+ offsetof(struct user_regs_struct, rip),
|
||||||
|
+ NULL);
|
||||||
|
+ if (rv == -1)
|
||||||
|
+ return rv;
|
||||||
|
+
|
||||||
|
+ rv = ptrace(PTRACE_PEEKTEXT, execve_pctx->pid,
|
||||||
|
+ rv - 1, NULL);
|
||||||
|
+ if (rv == -1)
|
||||||
|
+ return rv;
|
||||||
|
+ if ((unsigned char)rv == 0xcc)
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Wait for SIGTRAP from the execve. It happens from the thread
|
||||||
|
+ * group ID, so find it if thread doing execve() is not it. */
|
||||||
|
+ if (execve_pctx != proc2pctx(proc)) {
|
||||||
|
+ pid = get_threadgroup_id(proc->pid);
|
||||||
|
+ if (pid < 0)
|
||||||
|
+ return -1;
|
||||||
|
+
|
||||||
|
+ proc->pid = pid;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = wait_for_stop(execve_pctx, (void *)(uintptr_t)pid);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ kplogerror("waitpid\n");
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ list_for_each_entry_safe(pctx, ptmp, &proc->ptrace.pctxs, list) {
|
||||||
|
+ if (pctx->pid == proc->pid)
|
||||||
|
+ continue;
|
||||||
|
+ kpatch_ptrace_detach(pctx);
|
||||||
|
+ kpatch_ptrace_ctx_destroy(pctx);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Suddenly, /proc/pid/mem gets invalidated */
|
||||||
|
+ {
|
||||||
|
+ char buf[128];
|
||||||
|
+ close(proc->memfd);
|
||||||
|
+
|
||||||
|
+ snprintf(buf, sizeof(buf), "/proc/%d/mem", proc->pid);
|
||||||
|
+ proc->memfd = open(buf, O_RDWR);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ kpdebug("...done\n");
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int
|
||||||
|
wait_for_mmap(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
unsigned long *pbase)
|
||||||
|
diff --git a/src/include/kpatch_ptrace.h b/src/include/kpatch_ptrace.h
|
||||||
|
index 5abcf26..f0e83c0 100644
|
||||||
|
--- a/src/include/kpatch_ptrace.h
|
||||||
|
+++ b/src/include/kpatch_ptrace.h
|
||||||
|
@@ -55,7 +55,10 @@ int kpatch_ptrace_detach(struct kpatch_ptrace_ctx *pctx);
|
||||||
|
int kpatch_ptrace_handle_ld_linux(kpatch_process_t *proc,
|
||||||
|
unsigned long *pentry_point);
|
||||||
|
|
||||||
|
-int kpatch_ptrace_kickstart_execve_wrapper(kpatch_process_t *proc);
|
||||||
|
+
|
||||||
|
+int wait_for_stop(struct kpatch_ptrace_ctx *pctx, void *data);
|
||||||
|
+int get_threadgroup_id(int tid);
|
||||||
|
+int kpatch_arch_ptrace_kickstart_execve_wrapper(kpatch_process_t *proc);
|
||||||
|
int kpatch_ptrace_get_entry_point(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
unsigned long *pentry_point);
|
||||||
|
|
||||||
|
diff --git a/src/kpatch_process.c b/src/kpatch_process.c
|
||||||
|
index 9561962..f987b7e 100644
|
||||||
|
--- a/src/kpatch_process.c
|
||||||
|
+++ b/src/kpatch_process.c
|
||||||
|
@@ -856,7 +856,7 @@ kpatch_process_kickstart_execve_wrapper(kpatch_process_t *proc)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
- ret = kpatch_ptrace_kickstart_execve_wrapper(proc);
|
||||||
|
+ ret = kpatch_arch_ptrace_kickstart_execve_wrapper(proc);
|
||||||
|
if (ret < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
diff --git a/src/kpatch_ptrace.c b/src/kpatch_ptrace.c
|
||||||
|
index 7ab550c..d0bfbdd 100644
|
||||||
|
--- a/src/kpatch_ptrace.c
|
||||||
|
+++ b/src/kpatch_ptrace.c
|
||||||
|
@@ -413,7 +413,7 @@ poke_back:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int
|
||||||
|
+int
|
||||||
|
wait_for_stop(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
@@ -463,7 +463,7 @@ kpatch_execute_remote(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME(pboldin) buf might be too small */
|
||||||
|
-static int
|
||||||
|
+int
|
||||||
|
get_threadgroup_id(int tid)
|
||||||
|
{
|
||||||
|
FILE *fh;
|
||||||
|
@@ -486,105 +486,6 @@ get_threadgroup_id(int tid)
|
||||||
|
return pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
-/**
|
||||||
|
- * This is rather tricky since we are accounting for the non-main
|
||||||
|
- * thread calling for execve(). See `ptrace(2)` for details.
|
||||||
|
- *
|
||||||
|
- * FIXME(pboldin): this is broken for multi-threaded calls
|
||||||
|
- * to execve. Sight.
|
||||||
|
- */
|
||||||
|
-int
|
||||||
|
-kpatch_ptrace_kickstart_execve_wrapper(kpatch_process_t *proc)
|
||||||
|
-{
|
||||||
|
- int ret, pid = 0;
|
||||||
|
- struct kpatch_ptrace_ctx *pctx, *ptmp, *execve_pctx = NULL;
|
||||||
|
- long rv;
|
||||||
|
-
|
||||||
|
- kpdebug("kpatch_ptrace_kickstart_execve_wrapper\n");
|
||||||
|
-
|
||||||
|
- list_for_each_entry(pctx, &proc->ptrace.pctxs, list) {
|
||||||
|
- /* proc->pid equals to THREAD ID of the thread
|
||||||
|
- * executing execve.so's version of execve
|
||||||
|
- */
|
||||||
|
- if (pctx->pid != proc->pid)
|
||||||
|
- continue;
|
||||||
|
- execve_pctx = pctx;
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (execve_pctx == NULL) {
|
||||||
|
- kperr("can't find thread executing execve");
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* Send a message to our `execve` wrapper so it will continue
|
||||||
|
- * execution
|
||||||
|
- */
|
||||||
|
- ret = send(proc->send_fd, &ret, sizeof(ret), 0);
|
||||||
|
- if (ret < 0) {
|
||||||
|
- kplogerror("send failed\n");
|
||||||
|
- return ret;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* Wait for it to reach BRKN instruction just before real execve */
|
||||||
|
- while (1) {
|
||||||
|
- ret = wait_for_stop(execve_pctx, NULL);
|
||||||
|
- if (ret < 0) {
|
||||||
|
- kplogerror("wait_for_stop\n");
|
||||||
|
- return ret;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- rv = ptrace(PTRACE_PEEKUSER, execve_pctx->pid,
|
||||||
|
- offsetof(struct user_regs_struct, rip),
|
||||||
|
- NULL);
|
||||||
|
- if (rv == -1)
|
||||||
|
- return rv;
|
||||||
|
-
|
||||||
|
- rv = ptrace(PTRACE_PEEKTEXT, execve_pctx->pid,
|
||||||
|
- rv - 1, NULL);
|
||||||
|
- if (rv == -1)
|
||||||
|
- return rv;
|
||||||
|
- if ((unsigned char)rv == 0xcc)
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* Wait for SIGTRAP from the execve. It happens from the thread
|
||||||
|
- * group ID, so find it if thread doing execve() is not it. */
|
||||||
|
- if (execve_pctx != proc2pctx(proc)) {
|
||||||
|
- pid = get_threadgroup_id(proc->pid);
|
||||||
|
- if (pid < 0)
|
||||||
|
- return -1;
|
||||||
|
-
|
||||||
|
- proc->pid = pid;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- ret = wait_for_stop(execve_pctx, (void *)(uintptr_t)pid);
|
||||||
|
- if (ret < 0) {
|
||||||
|
- kplogerror("waitpid\n");
|
||||||
|
- return ret;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- list_for_each_entry_safe(pctx, ptmp, &proc->ptrace.pctxs, list) {
|
||||||
|
- if (pctx->pid == proc->pid)
|
||||||
|
- continue;
|
||||||
|
- kpatch_ptrace_detach(pctx);
|
||||||
|
- kpatch_ptrace_ctx_destroy(pctx);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* Suddenly, /proc/pid/mem gets invalidated */
|
||||||
|
- {
|
||||||
|
- char buf[128];
|
||||||
|
- close(proc->memfd);
|
||||||
|
-
|
||||||
|
- snprintf(buf, sizeof(buf), "/proc/%d/mem", proc->pid);
|
||||||
|
- proc->memfd = open(buf, O_RDWR);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- kpdebug("...done\n");
|
||||||
|
-
|
||||||
|
- return 0;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
unsigned long
|
||||||
|
kpatch_mmap_remote(struct kpatch_ptrace_ctx *pctx,
|
||||||
|
unsigned long addr,
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
@ -1,15 +1,60 @@
|
|||||||
Version: 0.1.4
|
Version: 0.1.4
|
||||||
Name: libcareplus
|
Name: libcareplus
|
||||||
Summary: LibcarePlus tools
|
Summary: LibcarePlus tools
|
||||||
Release: 2
|
Release: 3
|
||||||
Group: Applications/System
|
Group: Applications/System
|
||||||
License: GPLv2
|
License: GPLv2
|
||||||
Url: https://gitee.com/openeuler/libcareplus
|
Url: https://gitee.com/openeuler/libcareplus
|
||||||
Source0: %{name}-%{version}.tar.gz
|
Source0: %{name}-%{version}.tar.gz
|
||||||
|
|
||||||
Patch0001: src-Makefile-install-kpatch_gensrc-into-bindir.patch
|
Patch0001: src-Makefile-install-kpatch_gensrc-into-bindir.patch
|
||||||
|
Patch0002: 0001-Split-kpatch_storage.c-from-kpatch_user.c.patch
|
||||||
|
Patch0003: 0002-Split-kpatch_patch.c-from-kpatch_user.c.patch
|
||||||
|
Patch0004: 0003-cmd_patch-pass-arguments-directly.patch
|
||||||
|
Patch0005: 0004-travis-use-VM-for-now.patch
|
||||||
|
Patch0006: 0005-scripts-pkgbuild-add-prepare_env-hook.patch
|
||||||
|
Patch0007: 0006-pkgbuild-fix-for-non-root-rpmbuild-built-root.patch
|
||||||
|
Patch0008: 0007-Toil-package-builder.patch
|
||||||
|
Patch0009: 0008-pkgbuild-use-yumdownloader-if-source-url-is-missing.patch
|
||||||
|
Patch0010: 0009-execve-abort-on-failure.patch
|
||||||
|
Patch0011: 0010-Add-test-stage-to-pkgbuild.patch
|
||||||
|
Patch0012: 0011-glibc-minimal-readme-for-toil-builder.patch
|
||||||
|
Patch0013: 0012-Fix-kpatch_process_init-kpatch_coroutines_free.patch
|
||||||
|
Patch0014: 0013-Add-libcare-stresstest.patch
|
||||||
|
Patch0015: 0014-read-auxv-from-proc-pid-auxv.patch
|
||||||
|
Patch0016: 0015-add-fail-to-unpatch-test.patch
|
||||||
|
Patch0017: 0016-Waitpid-for-finished-threads-after-detach.patch
|
||||||
|
Patch0018: 0017-.gitignore-build-artefacts.patch
|
||||||
|
Patch0019: 0018-kpatch_storage-put-an-end-to-description-string-load.patch
|
||||||
|
Patch0020: 0019-Fix-README-files.patch
|
||||||
|
Patch0021: 0020-include-Create-include-directory-for-header-files.patch
|
||||||
|
Patch0022: 0021-src-Update-header-file-position.patch
|
||||||
|
Patch0023: 0022-arch-Create-arch-directory-to-support-multi-arch.patch
|
||||||
|
Patch0024: 0023-config-configure-out-the-running-arch.patch
|
||||||
|
Patch0025: 0024-Makefile-Adapt-Makefile-for-different-architectures.patch
|
||||||
|
Patch0026: 0025-kpatch_parse-Update-asm_directives-for-aarch64.patch
|
||||||
|
Patch0027: 0026-kpatch_parse-Split-function-parse_ctype.patch
|
||||||
|
Patch0028: 0027-kpatch_parse-Split-function-init_multilines.patch
|
||||||
|
Patch0029: 0028-kpatch_parse-Split-function-is_variable_start.patch
|
||||||
|
Patch0030: 0029-kpatch_parse-Split-function-is_data_def.patch
|
||||||
|
Patch0031: 0030-kpatch_parse-Split-function-is_function_start.patch
|
||||||
|
Patch0032: 0031-kpatch_common.h-Factor-out-PAGE_SIZE-marco.patch
|
||||||
|
Patch0033: 0032-kpatch_coro-Split-function-_UCORO_access_reg.patch
|
||||||
|
Patch0034: 0033-kpatch_coro-Split-function-get_ptr_guard.patch
|
||||||
|
Patch0035: 0034-kpatch_coro-Split-function-locate_start_context_symb.patch
|
||||||
|
Patch0036: 0035-kpatch_patch-Split-function-patch_apply_hunk.patch
|
||||||
|
Patch0037: 0036-kpatch_elf-Split-function-kpatch_add_jmp_entry.patch
|
||||||
|
Patch0038: 0037-kpatch_elf-Split-function-kpatch_apply_relocate_add.patch
|
||||||
|
Patch0039: 0038-kpatch_process-Split-function-object_find_patch_regi.patch
|
||||||
|
Patch0040: 0039-kpatch_ptrace-Split-function-kpatch_ptrace_waitpid.patch
|
||||||
|
Patch0041: 0040-kpatch_ptrace-Split-function-copy_regs.patch
|
||||||
|
Patch0042: 0041-kpatch_ptrace-Split-function-kpatch_execute_remote_f.patch
|
||||||
|
Patch0043: 0042-kpatch_ptrace-Split-function-kpatch_ptrace_resolve_i.patch
|
||||||
|
Patch0044: 0043-kpatch_ptrace-Split-function-kpatch_arch_prctl_remot.patch
|
||||||
|
Patch0045: 0044-kpatch_ptrace-Split-function-kpatch_syscall_remote.patch
|
||||||
|
Patch0046: 0045-kpatch_ptrace-Split-function-wait_for_mmap.patch
|
||||||
|
Patch0047: 0046-kpatch_ptrace-Split-function-kpatch_ptrace_kickstart.patch
|
||||||
|
|
||||||
ExclusiveArch: x86_64
|
|
||||||
BuildRequires: elfutils-libelf-devel libunwind-devel
|
BuildRequires: elfutils-libelf-devel libunwind-devel
|
||||||
|
|
||||||
%if 0%{with selinux}
|
%if 0%{with selinux}
|
||||||
@ -53,7 +98,9 @@ LibcarePlus devel files.
|
|||||||
%autopatch -p1
|
%autopatch -p1
|
||||||
|
|
||||||
%build
|
%build
|
||||||
|
cd src
|
||||||
|
sh ./config
|
||||||
|
cd ../
|
||||||
make -C src
|
make -C src
|
||||||
%if 0%{with selinux}
|
%if 0%{with selinux}
|
||||||
make -C dist/selinux
|
make -C dist/selinux
|
||||||
@ -163,6 +210,9 @@ exit 0
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Feb 09 2021 Jiajie Li <lijiajie11@huawei.com> - 0.1.4-3
|
||||||
|
- Add basic support libcareplus on aarch64
|
||||||
|
|
||||||
* Mon Dec 28 2020 sunguoshuai <sunguoshuai@huawei.com> - 0.1.4-2
|
* Mon Dec 28 2020 sunguoshuai <sunguoshuai@huawei.com> - 0.1.4-2
|
||||||
- Del the {dist} in release.
|
- Del the {dist} in release.
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user