48
48
kexec, except for the kexec in loop test.
49
49
'''
50
50
51
+ import os
51
52
import unittest
52
53
import OpTestLogger
53
54
58
59
59
60
log = OpTestLogger .optest_logger_glob .get_logger (__name__ )
60
61
62
+
61
63
class OpTestKexec (unittest .TestCase ):
62
64
"""kexec test class"""
63
65
@@ -75,10 +77,8 @@ def populate_kernel_initrd_image(self):
75
77
and initrd_image instance variable
76
78
"""
77
79
78
- distro = self .op_test_util .distro_name ()
79
-
80
80
# Skip the test for unsupported distro
81
- if distro == "unknown" :
81
+ if self . distro == "unknown" :
82
82
self .skipTest ("Unsupported distro" )
83
83
84
84
# Find kexec kernel version. If user provided the kernel source
@@ -99,13 +99,13 @@ def populate_kernel_initrd_image(self):
99
99
# Set kernel_image and initrd_image instance variable with
100
100
# corresponding filenames path
101
101
k_ver = str (k_ver )
102
- if distro == "rhel" :
102
+ if self . distro == "rhel" :
103
103
self .kernel_image = "vmlinuz-" + k_ver
104
104
self .initrd_image = "initramfs-" + k_ver + ".img"
105
- elif distro == "sles" :
105
+ elif self . distro == "sles" :
106
106
self .kernel_image = "vmlinux-" + k_ver
107
107
self .initrd_image = "initrd-" + k_ver
108
- elif distro == "ubuntu" :
108
+ elif self . distro == "ubuntu" :
109
109
self .kernel_image = "vmlinux-" + k_ver
110
110
self .initrd_image = "initrd.img-" + k_ver
111
111
@@ -115,7 +115,7 @@ def setUp(self):
115
115
self .cv_SYSTEM = conf .system ()
116
116
self .c = self .cv_SYSTEM .console
117
117
self .cv_HOST = conf .host ()
118
- self .distro = None
118
+ self .distro = self . op_test_util . distro_name ()
119
119
self .num_of_iterations = conf .args .num_of_iterations
120
120
self .kernel_image = conf .args .kernel_image
121
121
self .initrd_image = conf .args .initrd_image
@@ -132,7 +132,7 @@ def setUp(self):
132
132
self .os_level_secureboot = sb_utilities .check_os_level_secureboot_state ()
133
133
134
134
def get_kexec_load_cmd (self , load_opt = True , copy_cmdline = True ,
135
- file_load = False , add_arg = None ):
135
+ syscall_load = False , file_load = False , add_arg = None ):
136
136
"""
137
137
Generates a kexec command for loading a kernel image with various
138
138
optional arguments.
@@ -159,6 +159,9 @@ def get_kexec_load_cmd(self, load_opt=True, copy_cmdline=True,
159
159
if file_load :
160
160
kexec_cmd = kexec_cmd + " -s"
161
161
162
+ if syscall_load :
163
+ kexec_cmd = "%s -c" % kexec_cmd
164
+
162
165
if copy_cmdline :
163
166
kexec_cmd = kexec_cmd + " --append=\" `cat /proc/cmdline`\" "
164
167
@@ -350,10 +353,59 @@ def test_load_and_exec(self):
350
353
ret = self .load_kexec_kernel (kexec_load_cmd )
351
354
self .assertTrue (ret , "Kexec load failed" )
352
355
356
+ kexec_exec_cmd = self .get_kexec_exec_command (exec_opt = True )
357
+ ret = self .execute_kexec_cmd (kexec_exec_cmd , raw_pty_console = True )
358
+ self .assertTrue (ret , "kexec exec failed: %s " % kexec_exec_cmd )
359
+
360
+ def test_file_load_and_exec (self ):
361
+ """
362
+ Test kexec functionality by loading with kexec-file-syscall and exec
363
+ into kexec kernel.
364
+
365
+ First load the kexec kernel using -s, -l and --append(command line
366
+ arguments of currently running kenrel form /proc/cmdline) option.
367
+ Then exec into kexec kernel.
368
+
369
+ Test passes if both the kexec load and the execution into the
370
+ kexec kernel go fine; otherwise, it fails."
371
+ """
372
+
373
+ kexec_load_cmd = self .get_kexec_load_cmd (file_load = True )
374
+ ret = self .load_kexec_kernel (kexec_load_cmd )
375
+ self .assertTrue (ret , "Kexec load failed" )
376
+
353
377
kexec_exec_cmd = self .get_kexec_exec_command (exec_opt = True )
354
378
ret = self .execute_kexec_cmd (kexec_exec_cmd , raw_pty_console = True )
355
379
self .assertTrue (ret , "kexec exec failed: " + kexec_exec_cmd )
356
380
381
+ def test_syscall_load_and_exec (self ):
382
+ """
383
+ Test kexec functionality by loading with kexec-syscall and exec
384
+ into kexec kernel.
385
+
386
+ First load the kexec kernel using -c, -l and --append(command line
387
+ arguments of currently running kenrel form /proc/cmdline) option.
388
+ Then exec into kexec kernel.
389
+
390
+ Test passes if both the kexec load and the execution into the
391
+ kexec kernel go fine; otherwise, it fails."
392
+ """
393
+
394
+ kexec_load_cmd = self .get_kexec_load_cmd (syscall_load = True )
395
+ ret = self .load_kexec_kernel (kexec_load_cmd )
396
+ if self .os_level_secureboot :
397
+ self .assertFalse (ret , "Kexec load pass, with -c option" )
398
+ else :
399
+ self .assertTrue (ret , "Kexec load failed, with -c option" )
400
+
401
+ kexec_exec_cmd = self .get_kexec_exec_command (exec_opt = True )
402
+ if self .os_level_secureboot :
403
+ ret = self .execute_kexec_cmd (kexec_exec_cmd )
404
+ self .assertFalse (ret , "Kexec exec pass, with -c option" )
405
+ else :
406
+ ret = self .execute_kexec_cmd (kexec_exec_cmd , raw_pty_console = True )
407
+ self .assertTrue (ret , "Kexec exec failed, with -c option" )
408
+
357
409
def test_kexec_force (self ):
358
410
"""
359
411
Test kexec load and exec into kexec kernel using --force (-f) option.
@@ -397,6 +449,65 @@ def test_kexec_in_loop(self):
397
449
self .assertTrue (ret , "kexec failed, at iteration cnt: " + str (i ))
398
450
log .info ("Completed kexec iteration cnt %s." % str (i ))
399
451
452
+ def test_kexec_unsigned_kernel (self ):
453
+ """
454
+ Tests the unsigned kernel when secure boot is enabled.
455
+
456
+ From the signed kernel image, create unsigned kernel image. The same
457
+ used for 'kexec' when secure boot is enabled. Expected failure while
458
+ loading kexec.
459
+ """
460
+ if self .os_level_secureboot :
461
+ if self .op_test_util .check_kernel_signature ():
462
+ if self .distro in ["unknown" , "ubuntu" ]:
463
+ self .skipTest ("Unsupported Linux distribution." )
464
+ install_cmd = "wget"
465
+ wget_bool = True
466
+ res = self .cv_HOST .host_run_command ('which %s' % install_cmd ,
467
+ timeout = 120 )
468
+ if install_cmd not in res [0 ]:
469
+ wget_bool = False
470
+ if not wget_bool :
471
+ if self .distro == "rhel" :
472
+ install_cmd = "yum install -y %s" % install_cmd
473
+ elif self .distro == "sles" :
474
+ install_cmd = "zypper install -y %s" % install_cmd
475
+ self .cv_HOST .host_run_command (install_cmd , timeout = 120 )
476
+ try :
477
+ url = "https://raw.githubusercontent.com/torvalds/linux/master/scripts/extract-module-sig.pl"
478
+ self .cv_HOST .host_run_command ("wget %s -P /tmp/" % url , timeout = 120 )
479
+ except CommandFailed :
480
+ self .skipTest ("Can't get extract-module-sig.pl file." )
481
+ module_sig_file = '/tmp/extract-module-sig.pl'
482
+ self .cv_HOST .host_run_command ("chmod u+x %s" % module_sig_file )
483
+ self .kernel_image = "/boot/%s" % self .kernel_image
484
+ cmd = "%s -0 %s > %s.unsigned" % \
485
+ (module_sig_file , self .kernel_image , self .kernel_image )
486
+ out = self .cv_HOST .host_run_command (cmd )
487
+ if '0' not in out [3 ]:
488
+ self .skipTest ("Can not create unsigned binary. Using- %s"
489
+ % cmd )
490
+ cmd = "kexec -s -l %s.unsigned" % self .kernel_image
491
+ ret = self .execute_kexec_cmd (cmd )
492
+ if ret :
493
+ self .fail ("kexec loaded unsigned kernel when secure boot"
494
+ " is enabled." )
495
+ else :
496
+ log .info ("kexec loading with unsigned kernel failed. "
497
+ "Which is expected." )
498
+ else :
499
+ self .skipTest ("secure boot is disabled." )
500
+
501
+ def tearDown (self ):
502
+ unsigned_kernel = "%s.unsigned" % self .kernel_image
503
+ if 'boot' not in unsigned_kernel :
504
+ unsigned_kernel = "/boot/%s" % unsigned_kernel
505
+ if os .path .exists (unsigned_kernel ):
506
+ os .remove (unsigned_kernel )
507
+ sign_file = "/tmp/extract-module-sig.pl"
508
+ if os .path .exists (sign_file ):
509
+ os .remove (sign_file )
510
+
400
511
401
512
def kexec_suite ():
402
513
"""kexec test suite"""
@@ -406,5 +517,8 @@ def kexec_suite():
406
517
suite .addTest (OpTestKexec ('test_load_and_exec' ))
407
518
suite .addTest (OpTestKexec ('test_kexec_force' ))
408
519
suite .addTest (OpTestKexec ('test_kexec_single_step' ))
520
+ suite .addTest (OpTestKexec ('test_file_load_and_exec' ))
521
+ suite .addTest (OpTestKexec ('test_syscall_load_and_exec' ))
409
522
suite .addTest (OpTestKexec ('test_kexec_in_loop' ))
523
+ suite .addTest (OpTestKexec ('test_kexec_unsigned_kernel' ))
410
524
return suite
0 commit comments