コード例 #1
0
ファイル: exception_handling.py プロジェクト: SUSE/libpulp
#!/usr/bin/env python3

#   libpulp - User-space Livepatching Library
#
#   Copyright (C) 2021 SUSE Software Solutions GmbH
#
#   This file is part of libpulp.
#
#   libpulp is free software; you can redistribute it and/or
#   modify it under the terms of the GNU Lesser General Public
#   License as published by the Free Software Foundation; either
#   version 2.1 of the License, or (at your option) any later version.
#
#   libpulp is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#   Lesser General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with libpulp.  If not, see <http://www.gnu.org/licenses/>.

import testsuite

child = testsuite.spawn('exception_handling')

child.expect('caught in lib')
child.expect('caught in main')

child.close(force=True)
exit(0)
コード例 #2
0
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#   Lesser General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with libpulp.  If not, see <http://www.gnu.org/licenses/>.

# Check the comments of `libbuildid_livepatch1.ulp` Makefile rule in
# Makefile.am on this folder.
#
# This test should fail because of buildid mismatch.

import testsuite
import subprocess

errorcode = 1

child = testsuite.spawn('buildid')
child.expect('Waiting for input.')

child.sendline('')
child.expect('1338')

try:
    child.livepatch('libbuildid_livepatch1.ulp')
except subprocess.CalledProcessError:
    errorcode = 0

child.close(force=True)
exit(errorcode)
コード例 #3
0
#   libpulp is free software; you can redistribute it and/or
#   modify it under the terms of the GNU Lesser General Public
#   License as published by the Free Software Foundation; either
#   version 2.1 of the License, or (at your option) any later version.
#
#   libpulp is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#   Lesser General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with libpulp.  If not, see <http://www.gnu.org/licenses/>.

import testsuite

child = testsuite.spawn('contract')

child.expect('Waiting for input.')

errors = 0
child.sendline('')
child.sendline('')
child.expect('TYPE A data 128')
child.sendline('')
child.expect('TYPE B data 256.000000')

# Send the test program into the library.
child.sendline('')

# Apply live patch while inside library
child.livepatch('libcontract_livepatch1.ulp')
コード例 #4
0
ファイル: cancel.py プロジェクト: SUSE/libpulp
#!/usr/bin/env python3

#   libpulp - User-space Livepatching Library
#
#   Copyright (C) 2021 SUSE Software Solutions GmbH
#
#   This file is part of libpulp.
#
#   libpulp is free software; you can redistribute it and/or
#   modify it under the terms of the GNU Lesser General Public
#   License as published by the Free Software Foundation; either
#   version 2.1 of the License, or (at your option) any later version.
#
#   libpulp is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#   Lesser General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with libpulp.  If not, see <http://www.gnu.org/licenses/>.

import testsuite

child = testsuite.spawn('cancel')

child.expect('OK')

child.close(force=True)
exit(0)
コード例 #5
0
ファイル: memory_protection.py プロジェクト: SUSE/libpulp
#   libpulp is free software; you can redistribute it and/or
#   modify it under the terms of the GNU Lesser General Public
#   License as published by the Free Software Foundation; either
#   version 2.1 of the License, or (at your option) any later version.
#
#   libpulp is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#   Lesser General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with libpulp.  If not, see <http://www.gnu.org/licenses/>.

import testsuite

child = testsuite.spawn('memory_protection')

child.expect('Waiting for input.')

# Every time a newline is sent, the test program touchs code memory
child.sendline('')
child.expect('pristine')

child.livepatch('libaddress_livepatch1.ulp')

# Try to touch code memory after live patching
child.sendline('')
try:
    child.expect('patched', reject='pristine')
except EOFError:
    # Diagnose the error
コード例 #6
0
ファイル: asunsafe_conversion.py プロジェクト: SUSE/libpulp
#   version 2.1 of the License, or (at your option) any later version.
#
#   libpulp is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#   Lesser General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with libpulp.  If not, see <http://www.gnu.org/licenses/>.

import signal
import subprocess

import testsuite

child = testsuite.spawn('asunsafe_conversion')

child.expect('Waiting for signals.')

child.kill(signal.SIGUSR1)
child.expect('hello')

errors = 0
try:
    # Apply the live patch.
    child.livepatch('libblocked_livepatch1.ulp', retries=100)
except subprocess.TimeoutExpired:
    print('Deadlock while live patching - AS-Unsafe conversion not tested')
    # The deadlock test (tests/deadlock) has a far greater chance of
    # detecting deadlocks during the application of live-patches, so
    # return 77 to report that this test case was unable to detect the
コード例 #7
0
ファイル: manyprocesses.py プロジェクト: SUSE/libpulp
    try:
        print('Applying/reverting live patch.')
        tool = subprocess.run(command, timeout=timeout)
    except subprocess.TimeoutExpired:
        print('Live patching timed out.')
        raise

    # The trigger tool returns 0 on success, so use check_returncode(),
    # which asserts that, and raises CalledProcessError otherwise.
    tool.check_returncode()

    print('Live patch applied/reverted successfully.')


childs = [
    testsuite.spawn('manyprocesses'),
    testsuite.spawn('manyprocesses'),
    testsuite.spawn('manyprocesses')
]

for child in childs:
    child.expect('Waiting for input.')

    child.sendline('')
    child.expect('1-2-3-4-5-6-7-8')
    child.expect('1.0-2.0-3.0-4.0-5.0-6.0-7.0-8.0-9.0-10.0')

childless_livepatch(wildcard='./libmanyprocesses*.ulp',
                    verbose=True,
                    revert_lib='libmanyprocesses.so.0')
コード例 #8
0
ファイル: deadlock.py プロジェクト: SUSE/libpulp
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#   Lesser General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with libpulp.  If not, see <http://www.gnu.org/licenses/>.

import subprocess

import testsuite

# Since the deadlock demonstrated by this test case does not occur
# everytime it executes, run it in a loop. The amount of iterations
# hardcoded is arbitrary
errors = 0

child = testsuite.spawn('deadlock', log=None)

child.expect('Waiting for input.')

child.sendline('')
child.expect('hello')

# Applying a live patch to a process entails stopping all of its
# threads, then stealing one of them to jack into the process and call
# libpulp.so's routines that load and apply the live patch. These
# routines are called from the context of a signal-handler, and, as
# such, should not make calls to Asynchronous Signal Unsafe functions.
# However, libpulp calls dlopen, which is AS-Unsafe.
for attempt in range(200):
    print('  Attempt #' + str(attempt))
    try:
コード例 #9
0
ファイル: terminal.py プロジェクト: SUSE/libpulp
#   libpulp is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#   Lesser General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with libpulp.  If not, see <http://www.gnu.org/licenses/>.

import os
import subprocess
import time

import testsuite
from testsuite import ulptool

parent = testsuite.spawn('./terminal ./loop', script=False)

# Parent signal readiness first
parent.expect('Parent ready')

# Read the pid of the child process, which wrote it to stdout
parent.expect('Child ready')
parent.expect('[0-9]+')
pid = parent.after
if not type(pid) == str:
    raise TypeError
if not pid.isnumeric():
    raise ValueError

# If live patching SIGSTOPs the target process, the parent detects it
# with waitpid, but only most of the time. If the trigger and check
コード例 #10
0
ファイル: redzone.py プロジェクト: SUSE/libpulp
#   libpulp is free software; you can redistribute it and/or
#   modify it under the terms of the GNU Lesser General Public
#   License as published by the Free Software Foundation; either
#   version 2.1 of the License, or (at your option) any later version.
#
#   libpulp is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#   Lesser General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with libpulp.  If not, see <http://www.gnu.org/licenses/>.

import testsuite

child = testsuite.spawn('redzone', timeout=50)

child.expect('Waiting for input.')

child.livepatch('libblocked_livepatch1.ulp')

# Check live patch, which should not touch the redzone
child.is_patch_applied('libblocked_livepatch1.ulp')

# Read error output, if any
child.readline()
child.readline()

ret = child.wait()
if ret:
    exit(1)
コード例 #11
0
#
#   libpulp is free software; you can redistribute it and/or
#   modify it under the terms of the GNU Lesser General Public
#   License as published by the Free Software Foundation; either
#   version 2.1 of the License, or (at your option) any later version.
#
#   libpulp is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#   Lesser General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with libpulp.  If not, see <http://www.gnu.org/licenses/>.

import testsuite

child = testsuite.spawn('recursion', timeout=60)

child.expect('Waiting for input.')

child.sendline('45')
child.expect('1134903170')

child.livepatch('librecursion_livepatch1.ulp')

child.sendline('45')
child.expect('2537720636', reject='1134903170')

child.close(force=True)
exit(0)
コード例 #12
0
ファイル: syscall_restart.py プロジェクト: SUSE/libpulp
#   libpulp is free software; you can redistribute it and/or
#   modify it under the terms of the GNU Lesser General Public
#   License as published by the Free Software Foundation; either
#   version 2.1 of the License, or (at your option) any later version.
#
#   libpulp is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#   Lesser General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with libpulp.  If not, see <http://www.gnu.org/licenses/>.

import testsuite

child = testsuite.spawn('syscall_restart')

child.expect('Waiting for input.')

# After printing the greeting message, the target process makes a call
# to fgets, which calls the read syscall. Applying a live patch will
# interrupt the syscall.
child.livepatch('libparameters_livepatch1.ulp')

# Send a newline, which should be received by the read syscall if it has
# been successfully restarted by libpulp. If the syscall has not been
# restarted, the child program will exit without printing anything.
child.sendline('')
child.expect('8-7-6-5-4-3-2-1')
child.expect('10.0-9.0-8.0-7.0-6.0-5.0-4.0-3.0-2.0-1.0')
コード例 #13
0
#   libpulp - User-space Livepatching Library
#
#   Copyright (C) 2021 SUSE Software Solutions GmbH
#
#   This file is part of libpulp.
#
#   libpulp is free software; you can redistribute it and/or
#   modify it under the terms of the GNU Lesser General Public
#   License as published by the Free Software Foundation; either
#   version 2.1 of the License, or (at your option) any later version.
#
#   libpulp is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#   Lesser General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with libpulp.  If not, see <http://www.gnu.org/licenses/>.

import testsuite

child = testsuite.spawn('constructor')

# Simply check that the test program works correctly with malloc interposition.
# See constructor.c for a lengthier explanation.
child.expect('OK')

child.close(force=True)
exit(0)
コード例 #14
0
ファイル: process_revert.py プロジェクト: SUSE/libpulp
#   libpulp is free software; you can redistribute it and/or
#   modify it under the terms of the GNU Lesser General Public
#   License as published by the Free Software Foundation; either
#   version 2.1 of the License, or (at your option) any later version.
#
#   libpulp is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#   Lesser General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with libpulp.  If not, see <http://www.gnu.org/licenses/>.

import testsuite

child = testsuite.spawn('process', script=False)

child.expect('Waiting for input.')

child.sendline('')
child.expect('1-2-3-4-5-6-7-8');
child.expect('1.0-2.0-3.0-4.0-5.0-6.0-7.0-8.0-9.0-10.0');

child.livepatch('libprocess_livepatch1.ulp')

child.sendline('')
child.expect('8-7-6-5-4-3-2-1', reject='1-2-3-4-5-6-7-8');
child.expect('10.0-9.0-8.0-7.0-6.0-5.0-4.0-3.0-2.0-1.0',
             reject='1.0-2.0-3.0-4.0-5.0-6.0-7.0-8.0-9.0-10.0');

child.livepatch('libprocess_livepatch1.rev')
コード例 #15
0
#   License as published by the Free Software Foundation; either
#   version 2.1 of the License, or (at your option) any later version.
#
#   libpulp is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#   Lesser General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with libpulp.  If not, see <http://www.gnu.org/licenses/>.

import signal

import testsuite

child = testsuite.spawn('blocked')

# Wait for both threads to be ready (the order does not matter)
child.expect('Waiting for signals.')
child.expect('Waiting for signals.')

# At program start, two threads are put into loops waiting for signals,
# thread1 waits for SIGUSR1 and thread2 waits for SIGUSR2.
child.kill(signal.SIGUSR1)
child.expect('hello')
child.kill(signal.SIGUSR2)
child.expect('hello')

# After the live patching, thread1, which is looping outside the
# library, should produce a different output, whereas thread2, which
# never leaves the library, should display the old behavior.
コード例 #16
0
ファイル: missing_function.py プロジェクト: SUSE/libpulp
#   License as published by the Free Software Foundation; either
#   version 2.1 of the License, or (at your option) any later version.
#
#   libpulp is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#   Lesser General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with libpulp.  If not, see <http://www.gnu.org/licenses/>.

import subprocess
import testsuite

livepatch_metadata = 'libparameters_livepatch2.ulp'
livepatch_container = 'libparameters_livepatch2.so'

child = testsuite.spawn('parameters')

child.expect('Waiting for input.')

errors = 1
try:
    child.livepatch(livepatch_metadata)
except subprocess.CalledProcessError:
    if not child.is_so_loaded(livepatch_container):
        errors = 0

child.close(force=True)
exit(errors)
コード例 #17
0
ファイル: tls.py プロジェクト: SUSE/libpulp
#   libpulp is free software; you can redistribute it and/or
#   modify it under the terms of the GNU Lesser General Public
#   License as published by the Free Software Foundation; either
#   version 2.1 of the License, or (at your option) any later version.
#
#   libpulp is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#   Lesser General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with libpulp.  If not, see <http://www.gnu.org/licenses/>.

import testsuite

child = testsuite.spawn(testsuite.testname)

child.expect('Original TLS banner')
child.expect('Banner changed from thread_func: 0')
child.expect('Banner changed from thread_func: 1')

child.livepatch('libtls_livepatch1.ulp')

child.sendline('')
child.expect('String from live patch',
             reject=[
                 'String from thread_func: 0', 'String from thread_func: 1',
                 'Live patch data references not initialized'
             ])

child.close(force=True)
コード例 #18
0
#   libpulp is free software; you can redistribute it and/or
#   modify it under the terms of the GNU Lesser General Public
#   License as published by the Free Software Foundation; either
#   version 2.1 of the License, or (at your option) any later version.
#
#   libpulp is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#   Lesser General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with libpulp.  If not, see <http://www.gnu.org/licenses/>.

import testsuite

child = testsuite.spawn('numserv')

child.expect('Waiting for input.')

child.sendline('hundred')
child.expect('100')

child.livepatch('libhundreds_livepatch1.ulp')

child.sendline('hundred')
child.expect('200', reject='100')

child.livepatch('libhundreds_livepatch2.ulp')

child.sendline('hundred')
child.expect('300', reject=['100', '200'])
コード例 #19
0
ファイル: pagecross.py プロジェクト: SUSE/libpulp
#
#   libpulp is free software; you can redistribute it and/or
#   modify it under the terms of the GNU Lesser General Public
#   License as published by the Free Software Foundation; either
#   version 2.1 of the License, or (at your option) any later version.
#
#   libpulp is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#   Lesser General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with libpulp.  If not, see <http://www.gnu.org/licenses/>.

import testsuite

child = testsuite.spawn('pagecross')

child.expect('Waiting for input.')

child.sendline('')
child.expect('default')

child.livepatch('libpagecross_livepatch1.ulp')

child.sendline('')
child.expect('patched', reject='default')

child.close(force=True)
exit(0)