Skip to content

Commit 11dbc8c

Browse files
committed
pkgbuild: provide a sample
Fix pkgbuild to work with the new project and provide a sample building the patch for GHOST vulnerability of the glibc. Change-Id: I6efc3b60edb798e611f2330cfaa5635e70389687 Signed-off-by: Pavel Boldin <pboldin@cloudlinux.com>
1 parent ce11be6 commit 11dbc8c

File tree

9 files changed

+521
-16
lines changed

9 files changed

+521
-16
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
FROM centos:centos7
2+
RUN yum install -y --enablerepo=C7.0.1406-base gcc rpm-build xmlto "perl(ExtUtils::Embed)" patchutils redhat-rpm-config asciidoc elfutils-devel zlib-devel binutils-devel newt-devel python-devel audit-libs-devel perl bison flex hmaccalc tar gzip bzip2 vim python-setuptools ncurses-devel make net-tools bc openssl pesign numactl-devel pciutils-devel gettext kmod hostname libunwind-devel
3+
RUN yum downgrade -y --enablerepo=C7.0.1406-base gcc-4.8.2-16.el7 cpp-4.8.2-16.el7 kernel-headers-3.10.0-123.el7 libgomp-4.8.2-16.el7 cpp-4.8.2-16.el7 binutils-2.23.52.0.1-16.el7 binutils-devel-2.23.52.0.1-16.el7
4+
RUN easy_install pyelftools

docs/libcare.rst

Lines changed: 137 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,137 @@ Congratulations on going through the sample! Go on and learn how the magic of
132132
`kpmake`_ script works, read how the patch is `build under the hood`_ and how
133133
it is applied by the `kpatch_user`_. Or even jump to our `hacking guide`_!
134134

135+
RHEL7 ``glibc`` sample
136+
----------------------
137+
138+
.. _`glibc sample`:
139+
140+
Most of the binaries in the system are coming from distribution packages so
141+
building patches for them is different from the above. Here is how to do it.
142+
143+
This example builds ``glibc`` patch for old fashioned CVE-2015-0235 GHOST_
144+
vulnerability for RHEL7. The build is done using `scripts/pkgbuild`_ and
145+
package files are stored in ``../packages/rhel7/glibc/glibc-2.17-55.el7``.
146+
147+
Preparing environment
148+
~~~~~~~~~~~~~~~~~~~~~
149+
150+
First, we need the exactly the versions of tools and libs. Let's build a
151+
docker_ image and container for that:
152+
153+
.. code:: console
154+
155+
$ docker build docker/kernelcare/centos7/gcc-4.8.2-16.el7 \
156+
-t kernelcare/centos7:gcc-4.8.2-16.el7
157+
...
158+
$ docker run -v $PWD:/libcare --cap-add SYS_PTRACE -it \
159+
kernelcare/centos7:gcc-4.8.2-16.el7 /bin/bash
160+
[root@... /]#
161+
162+
Now, from inside the container let's install vulnerable version of glibc:
163+
164+
.. code:: console
165+
166+
[root@... /]# yum downgrade -y --enablerepo=C7.0.1406-base \
167+
glibc-2.17-55.el7 glibc-devel-2.17-55.el7 \
168+
glibc-headers-2.17-55.el7 glibc-common-2.17-55.el7
169+
...
170+
171+
Build the ``libcare`` tools:
172+
173+
.. code:: console
174+
175+
[root@... /]# make -C /libcare/src clean all
176+
...
177+
178+
Now build and run the sample GHOST app that runs 16 threads to constantly check
179+
whether the ``glibc`` is vulnerable to GHOST_ and prints a dot every time it founds
180+
it still is:
181+
182+
.. code:: console
183+
184+
[root@... /]# cd /libcare/samples/ghost
185+
[root@... ghost]# make
186+
...
187+
[root@... ghost]# ./GHOST
188+
............^C
189+
190+
Press Ctrl-C to get your console back and let's start building the patch for
191+
``glibc``.
192+
193+
Building the patch
194+
~~~~~~~~~~~~~~~~~~
195+
196+
The build is done in two stages.
197+
198+
First, the original package build is repeated with all the `intermediate
199+
assembly files`_ stored and saved for later. This greatly helps to speed up
200+
builds against the same base code. Run the following from inside our docker
201+
container to prebuild ``glibc`` package:
202+
203+
.. code:: console
204+
205+
[root@... /]# cd /libcare/
206+
[root@... /libcare]# ./scripts/pkgbuild -p packages/rhel7/glibc/glibc-2.17-55.el7
207+
...
208+
209+
This should download the package, do a regular RPM build with ``kpatch_cc``
210+
wrapper substituted for GCC and store the pre-built data into archive under
211+
``/kcdata`` directory:
212+
213+
.. code:: console
214+
215+
[root@... /libcare]# ls /kcdata
216+
build.orig-glibc-2.17-55.el7.x86_64.rpm.tgz glibc-2.17-55.el7.src.rpm
217+
218+
Now let's build the patch, output will be verbose since it contains tests run
219+
by the ``kp_patch_test`` defined in ``packages/rhel7/glibc/glibc-2.17-55.el7/info``:
220+
221+
.. code:: console
222+
223+
[root@... /libcare]# ./scripts/pkgbuild packages/rhel7/glibc/glibc-2.17-55.el7
224+
...
225+
[root@... /libcare]# ls /kcdata/kpatch*
226+
/kcdata/kpatch-glibc-2.17-55.el7.x86_64.tgz
227+
228+
Unwrap build patches and run the GHOST_ sample:
229+
230+
.. code:: console
231+
232+
[root@... /libcare]# cd /kcdata
233+
[root@... /kcdata]# tar xf kpatch*
234+
[root@... /kcdata]# /libcare/samples/ghost/GHOST 2>/dev/null &
235+
[root@... /kcdata]# patient_pid=$!
236+
237+
And, finally, patch it. All the threads of sample should stop when the GHOST
238+
vulnerability is finally patched:
239+
240+
.. code:: console
241+
242+
[root@... /kcdata]# /libcare/src/kpatch_user -v patch -p $patient_pid \
243+
root/kpatch-glibc-2.17-55.el7.x86_64
244+
...
245+
1 patch hunk(s) have been successfully applied to PID '...'
246+
(Press Enter again)
247+
[1]+ Done /libcare/samples/ghost/GHOST 2> /dev/null
248+
249+
You can patch any running application this way:
250+
251+
.. code:: console
252+
253+
[root@... /kcdata]# sleep 100 &
254+
[root@... /kcdata]# patient_pid=$!
255+
[root@... /kcdata]# /libcare/src/kpatch_user -v patch -p $patient_pid \
256+
root/kpatch-glibc-2.17-55.el7.x86_64
257+
...
258+
1 patch hunk(s) have been successfully applied to PID '...'
259+
260+
Congratulations on finishing this rather confusing sample!
261+
262+
.. _GHOST: https://access.redhat.com/articles/1332213
263+
.. _docker: https://www.docker.com/
264+
265+
135266

136267
.. contents::
137268

@@ -224,6 +355,8 @@ First, the original code is built as is either via make or via packaging
224355
system. The build is done with compiler substituted to ``kpatch_cc`` wrapper.
225356
Wrapper's behaviour is configured via environment variables.
226357

358+
.. _`intermediate assembly files`:
359+
227360
When ``kpatch_cc`` is invoked with ``KPATCH_STAGE=original`` it simply builds
228361
the project while keeping intermediate assembly files under name
229362
``.kpatch_${filename}.original.s`` invoking real compiler twice: first with the
@@ -347,6 +480,8 @@ Note that ``kpmake`` uses ``kpatch_cc`` under the hood. Read about it
347480
Building patch for a package via ``scripts/pkgbuild``
348481
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
349482

483+
.. _`scripts/pkgbuild`:
484+
350485
The ``scripts/pkgbuild`` is responsible for the building of the patch
351486
and prebuilding the original package and assembly files. At the moment
352487
it only supports building of the RPM-based packages.
@@ -374,6 +509,7 @@ The project directory contains three main files:
374509
packages URL and Docker container images with toolchain
375510
(GCC/binutils) version required to properly build the package.
376511

512+
This is not used at the moment and left as information source for the users.
377513

378514
The Doctor: ``kpatch_user``
379515
---------------------------
@@ -1001,7 +1137,7 @@ Manual Patch Creation
10011137
Throughout this section availability of the kpatch tools are assumed. To
10021138
build them and add them into PATH do:
10031139

1004-
.. code:: shell
1140+
.. code:: console
10051141
10061142
$ make -C src
10071143
$ export PATH=$PWD/src:$PATH

packages/rhel7/glibc/glibc-2.17-55.el7/info

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ KP_PROJECT_SPEC=glibc.spec
99
KP_PROJECT_DIR=$KP_PROJECT_BUILD_ROOT/BUILD/glibc-2.17-c758a686
1010
KP_PROJECT_BUILD_DIR=$KP_PROJECT_DIR/build-x86_64-redhat-linux
1111

12+
KP_PROJECT_SOURCE_URL=ftp://bo.mirror.garr.it/2/scientific/7x/SRPMS/vendor/glibc-2.17-55.el7.src.rpm
1213
KP_PROJECT_SOURCE=glibc-2.17-55.el7.src.rpm
1314
KP_PROJECT_BINARY=glibc-2.17-55.el7.$ARCH.rpm
1415

@@ -71,7 +72,7 @@ _install_originals() {
7172
}
7273

7374
_run_tests() {
74-
export LD_PRELOAD=/kernelcare/user/execve/execve.so
75+
export LD_PRELOAD=/libcare/execve/execve.so
7576

7677
local ld_linux="$KP_PROJECT_BUILD_DIR/elf/ld*"
7778

@@ -106,8 +107,9 @@ _run_tests() {
106107
kp_patch_test() {
107108
_install_originals
108109

110+
KPATCH_TOOLS=/libcare/src \
109111
PATCH_ROOT=/root/${KP_PROJECT_PATCH%.*} \
110-
/kernelcare/user/execve/listener >/root/test.log 2>&1 & :
112+
/libcare/execve/listener >/root/test.log 2>&1 & :
111113
LISTENER_PID=$!
112114

113115
pushd $KP_PROJECT_BUILD_DIR

0 commit comments

Comments
 (0)