package init 1.0.0

Signed-off-by: imxcc <xingchaochao@huawei.com>
(cherry picked from commit 0318c7e5e7bd9a0f9638119c573e82ff47edc15f)
This commit is contained in:
imxcc 2022-02-08 21:55:48 +08:00 committed by openeuler-sync-bot
parent 8ef93e293a
commit 43d0eac058
51 changed files with 42 additions and 11474 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,152 +0,0 @@
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

View File

@ -1,71 +0,0 @@
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

View File

@ -1,39 +0,0 @@
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

View File

@ -1,42 +0,0 @@
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

File diff suppressed because it is too large Load Diff

View File

@ -1,30 +0,0 @@
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

View File

@ -1,52 +0,0 @@
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

View File

@ -1,379 +0,0 @@
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

View File

@ -1,36 +0,0 @@
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

View File

@ -1,46 +0,0 @@
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

View File

@ -1,206 +0,0 @@
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

View File

@ -1,93 +0,0 @@
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, &regs);
- 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

View File

@ -1,147 +0,0 @@
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

View File

@ -1,67 +0,0 @@
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

View File

@ -1,28 +0,0 @@
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

View File

@ -1,29 +0,0 @@
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

View File

@ -1,51 +0,0 @@
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

View File

@ -1,129 +0,0 @@
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

View File

@ -1,373 +0,0 @@
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

View File

@ -1,73 +0,0 @@
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

View File

@ -1,26 +0,0 @@
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

View File

@ -1,72 +0,0 @@
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

View File

@ -1,31 +0,0 @@
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

View File

@ -1,154 +0,0 @@
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

View File

@ -1,249 +0,0 @@
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

View File

@ -1,282 +0,0 @@
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

View File

@ -1,180 +0,0 @@
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

View File

@ -1,149 +0,0 @@
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

View File

@ -1,43 +0,0 @@
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

View File

@ -1,196 +0,0 @@
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

View File

@ -1,148 +0,0 @@
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

View File

@ -1,307 +0,0 @@
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,
+ &regs);
+ 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,
+ &regs);
+ 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,
- &regs);
- 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

View File

@ -1,237 +0,0 @@
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

View File

@ -1,151 +0,0 @@
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

View File

@ -1,414 +0,0 @@
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

View File

@ -1,416 +0,0 @@
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

View File

@ -1,501 +0,0 @@
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 = &regs;
+ 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 *)&regs_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*)&regs_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, &regs);
+ 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, &regs);
+ 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, &regs);
- 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, &regs);
- 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

View File

@ -1,137 +0,0 @@
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

View File

@ -1,328 +0,0 @@
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 = &regs;
+ 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(&regs, pregs);
+
+ ret = ptrace(PTRACE_SETREGSET, pctx->pid, (void*)NT_PRSTATUS, (void*)&regs_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*)&regs_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(&regs, pregs);
+
+ ret = ptrace(PTRACE_SETREGS, pctx->pid, NULL, &regs);
+ 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, &regs);
+ 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(&regs, pregs);
-
- ret = ptrace(PTRACE_SETREGS, pctx->pid, NULL, &regs);
- 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, &regs);
- 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

View File

@ -1,146 +0,0 @@
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), &regs);
+ 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), &regs);
+ 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), &regs);
- 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

View File

@ -1,213 +0,0 @@
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 = &regs;
+ 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*)&regs_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, &regs);
+ 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, &regs);
- 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

View File

@ -1,191 +0,0 @@
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), &regs);
+ 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), &regs);
+ 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), &regs);
- 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

View File

@ -1,239 +0,0 @@
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

View File

@ -1,401 +0,0 @@
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

View File

@ -1,30 +0,0 @@
From 7782210333c3296b68f954b46284024701ec79e4 Mon Sep 17 00:00:00 2001
From: imxcc <xingchaochao@huawei.com>
Date: Wed, 8 Sep 2021 11:28:28 +0800
Subject: [PATCH] Allow init_t create lnk file
Bugfix: When the selinux mode is enforcing, libcare.socket cannot
create symlink libcare.sock. This will cause the libcare.service
to fail to start.
Signed-off-by: imxcc <xingchaochao@huawei.com>
---
dist/selinux/libcare.te | 2 ++
1 file changed, 2 insertions(+)
diff --git a/dist/selinux/libcare.te b/dist/selinux/libcare.te
index c240875..936fc34 100644
--- a/dist/selinux/libcare.te
+++ b/dist/selinux/libcare.te
@@ -49,6 +49,8 @@ allow libcare_t libcare_file_t: file exec_file_perms;
allow libcare_t libcare_file_t: dir list_dir_perms;
allow libcare_t libcare_file_t: lnk_file read_lnk_file_perms;
+allow init_t var_run_t:lnk_file create;
+
# to read patient's /proc entries and be able to attach to it
allow libcare_t self: capability { dac_override dac_read_search sys_ptrace };
--
2.27.0

Binary file not shown.

BIN
libcareplus-1.0.0.tar.gz Normal file

Binary file not shown.

View File

@ -1,62 +1,14 @@
%define with_selinux 1
Version: 0.1.4
Version: 1.0.0
Name: libcareplus
Summary: LibcarePlus tools
Release: 8
Release: 0
Group: Applications/System
License: GPLv2
Url: https://gitee.com/openeuler/libcareplus
Source0: %{name}-%{version}.tar.gz
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
Patch0048: 0047-Allow-init_t-create-lnk-file.patch
BuildRequires: elfutils-libelf-devel libunwind-devel gcc systemd
@ -159,6 +111,7 @@ rm -rf $RPM_BUILD_ROOT
%defattr(-,root,root)
%{_bindir}/libcare-ctl
%{_bindir}/libcare-client
%{_bindir}/libcare-server
%{_unitdir}/libcare.service
%{_unitdir}/libcare.socket
%{_presetdir}/90-libcare.preset
@ -167,6 +120,7 @@ rm -rf $RPM_BUILD_ROOT
%defattr(-,root,root)
%{_bindir}/libcare-cc
%{_bindir}/libcare-patch-make
%{_bindir}/libcare-dump
%{_bindir}/kpatch_gensrc
%{_bindir}/kpatch_strip
%{_bindir}/kpatch_make
@ -212,6 +166,44 @@ exit 0
%endif
%changelog
* Mon Feb 07 2022 imxcc <xingchaochao@huawei.com> - 1.0.0.0
- package init 1.0.0
* Mon Feb 07 2022 imxcc <xingchaochao@huawei.com> - 0.1.4.15
- kpatch_user: init pid in cmd_info_user
* Mon Feb 07 2022 imxcc <xingchaochao@huawei.com> - 0.1.4.14
- some bugfix
- support aarch64 UT
- fix memory RWX problem
* Mon Feb 07 2022 imxcc <xingchaochao@huawei.com> - 0.1.4.13
- add libcare-dump tool
- support test sets running on x86
- some bugfixs
* Mon Feb 07 2022 imxcc <xingchaochao@huawei.com> - 0.1.4.12
- src/Makefile: execute config scripts before building
- kpatch_gensrc.c: support ignoring functions which we don't need
- arch/aarch64/arch_parse: modify is_variable_start for arm asm
- libcare-ctl: implement applied patch list
- libcare-ctl: introduce patch-id
- arch/aarch64/arch_elf: Add LDR and B instruction relocation
- arch/aarch64/arch_parse: improve VAR_CBLOCK start indentify
- tls: add support for TLS symbol with IE model
- arch64/arch_elf: add R_AARCH64_LDST32_ABS_LO12_NC relocation type for aarch64
- process: fix region start calculation
- aarch64/arch_elf: Add ldr and ldrb relocation for aarch6
* Mon Feb 07 2022 imxcc <xingchaochao@huawei.com> - 0.1.4.11
- kpatch_cc: support gcc -MQ option
- libcare-cc: add gcc iquote option support
* Mon Feb 07 2022 imxcc <xingchaochao@huawei.com> - 0.1.4.10
- kpatch_user.c: fix gcc warning
* Mon Feb 07 2022 imxcc <xingchaochao@huawei.com> - 0.1.4.9
- libcare-patch-make: add `-j|--jobs` option
* Mon Feb 07 2022 imxcc <xingchaochao@huawei.com> - 0.1.4.8
- updated the README.en.md file

View File

@ -1,31 +0,0 @@
From 9221bb4ccd3f448fde2923df4598df17488978a9 Mon Sep 17 00:00:00 2001
From: Ying Fang <fangying1@huawei.com>
Date: Tue, 8 Dec 2020 15:18:19 +0800
Subject: [PATCH] src/Makefile: install kpatch_gensrc into bindir
Signed-off-by: Ying Fang <fangying1@huawei.com>
---
src/Makefile | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/src/Makefile b/src/Makefile
index 72ec073..22eb623 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -98,10 +98,8 @@ install: all
$(INSTALL) -m 0755 libcare-client $(DESTDIR)/$(bindir)/libcare-client
$(INSTALL) -m 0755 libcare-cc $(DESTDIR)/$(bindir)/libcare-cc
$(INSTALL) -m 0755 libcare-patch-make $(DESTDIR)/$(bindir)/libcare-patch-make
-
- $(INSTALL) -d $(DESTDIR)/$(libexecdir)/libcare
- $(INSTALL) -m 0755 kpatch_gensrc $(DESTDIR)/$(libexecdir)/libcare/kpatch_gensrc
- $(INSTALL) -m 0755 kpatch_make $(DESTDIR)/$(libexecdir)/libcare/kpatch_make
- $(INSTALL) -m 0755 kpatch_strip $(DESTDIR)/$(libexecdir)/libcare/kpatch_strip
+ $(INSTALL) -m 0755 kpatch_gensrc $(DESTDIR)/$(bindir)/kpatch_gensrc
+ $(INSTALL) -m 0755 kpatch_make $(DESTDIR)/$(bindir)/kpatch_make
+ $(INSTALL) -m 0755 kpatch_strip $(DESTDIR)/$(bindir)/kpatch_strip
.PHONY: all clean test tests tests-gensrc tests-strip
--
2.25.4