1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# (c) 2017, Alice Ferrazzi <alice.ferrazzi@gmail.com>
# Distributed under the terms of the GNU General Public License v2 or later
import subprocess
import os
import fileinput
class PaTch(object):
def __init__(self):
pass
# kpatch-build/kpatch-build -s /usr/src/linux-4.9.16-gentoo/
# -v /usr/src/linux-4.9.16-gentoo/vmlinux examples/test.patch
# -c ../elivepatch/elivepatch_server/config --skip-gcc-check
def build_livepatch(self, uuid, vmlinux, debug=True):
"""
Function for building the livepatch
:param uuid: UUID session identification
:param vmlinux: path to the vmlinux file
:param debug: copy build.log in the uuid directory
:return: void
"""
# TODO: use $CACHEDIR for define the .kpatch folder, if needed
kernel_source = os.path.join('/tmp/','elivepatch-' + uuid, 'usr/src/linux/')
uuid_dir = os.path.join('/tmp/','elivepatch-' + uuid)
vmlinux_source = os.path.join(kernel_source, vmlinux)
if not os.path.isfile(vmlinux_source):
self.build_kernel(uuid)
bashCommand = ['sudo', 'kpatch-build']
bashCommand.extend(['-s',kernel_source])
bashCommand.extend(['-v',vmlinux_source])
bashCommand.extend(['-c','config'])
bashCommand.extend(['01.patch'])
bashCommand.extend(['--skip-gcc-check'])
if debug:
bashCommand.extend(['--skip-cleanup'])
bashCommand.extend(['--debug'])
command(bashCommand, uuid_dir)
if debug:
command(['sudo','cp', '-f', '/root/.kpatch/build.log', uuid_dir ])
def get_kernel_sources(self, uuid, kernel_version):
"""
Function for download the kernel sources
:return: void
"""
try:
command(['git','clone','https://github.com/aliceinwire/gentoo-sources_overlay.git'])
except:
print('git clone failed.')
ebuild_path = os.path.join('gentoo-sources_overlay', 'sys-kernel', 'gentoo-sources', 'gentoo-sources-' + kernel_version + '.ebuild')
print(ebuild_path)
if os.path.isfile(ebuild_path):
command(['sudo', 'ROOT=/tmp/elivepatch-' + uuid, 'ebuild', ebuild_path, 'clean', 'merge'])
kernel_sources_status = True
else:
print('ebuild not present')
kernel_sources_status = None
return kernel_sources_status
def build_kernel(self, uuid):
kernel_source_dir = '/tmp/elivepatch-' + uuid + '/usr/src/linux/'
uuid_dir_config = '/tmp/elivepatch-' + uuid + '/config'
if 'CONFIG_DEBUG_INFO=y' in open(uuid_dir_config).read():
print("DEBUG_INFO correctly present")
elif 'CONFIG_DEBUG_INFO=n' in open(uuid_dir_config).read():
print("changing DEBUG_INFO to yes")
for line in fileinput.input(uuid_dir_config, inplace = 1):
print(line.replace("CONFIG_DEBUG_INFO=n", "CONFIG_DEBUG_INFO=y"))
else:
print("Adding DEBUG_INFO for getting kernel debug symbols")
for line in fileinput.input(uuid_dir_config, inplace = 1):
print(line.replace("# CONFIG_DEBUG_INFO is not set", "CONFIG_DEBUG_INFO=y"))
command(['sudo','cp','/tmp/elivepatch-' + uuid + '/config',kernel_source_dir + '.config'])
# olddefconfig default everything that is new from the configuration file
command(['sudo','make','olddefconfig'], kernel_source_dir)
command(['sudo','make'], kernel_source_dir)
command(['sudo','make', 'modules'], kernel_source_dir)
def command(bashCommand, kernel_source_dir=None):
"""
Popen override function
:param bashCommand: List of command arguments to execute
:param kernel_source_dir: the source directory of the kernel
:return: void
"""
if kernel_source_dir:
print(bashCommand)
process = subprocess.Popen(bashCommand, stdout=subprocess.PIPE, cwd=kernel_source_dir)
output, error = process.communicate()
print(output)
else:
print(bashCommand)
process = subprocess.Popen(bashCommand, stdout=subprocess.PIPE)
output, error = process.communicate()
print(output)
|