Bug 2231619 - "stap --sign-module" doesn't sign the module, as one would expect
Summary: "stap --sign-module" doesn't sign the module, as one would expect
Keywords:
Status: VERIFIED
Alias: None
Product: Red Hat Enterprise Linux 8
Classification: Red Hat
Component: systemtap
Version: 8.8
Hardware: All
OS: Linux
medium
medium
Target Milestone: rc
: ---
Assignee: Frank Ch. Eigler
QA Contact: Martin Cermak
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2023-08-12 14:45 UTC by Renaud Métrich
Modified: 2023-08-17 08:45 UTC (History)
3 users (show)

Fixed In Version: systemtap-4.9-3.el8
Doc Type: No Doc Update
Doc Text:
Clone Of:
: 2231632 (view as bug list)
Environment:
Last Closed:
Type: Bug
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
Red Hat Issue Tracker RHELPLAN-165694 0 None None None 2023-08-12 14:46:58 UTC

Description Renaud Métrich 2023-08-12 14:45:58 UTC
Description of problem:

Trying to use "stap" on a UEFI Secure Boot system, I need to sign the module.
It appears "stap --sign-module" creates everything greatly, including a new cert if needed (and shows the command line to import in the MOK, which is great as well), BUT there is a bug:

the module gets not signed, as shown below:
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------
# stap --sign-module -m hello -vv -p4 -e 'probe begin { printf("hello\n"); exit() }'
[...]
Pass 4: compiled C into "hello.ko" in 1230usr/370sys/1453real ms.
Copying /tmp/stapcvFF5Q/stapconf_fba5f0e2ee83dcfb42ea7fe4e36fbc30_785.h to /root/.systemtap/cache/fb/stapconf_fba5f0e2ee83dcfb42ea7fe4e36fbc30_785.h
Copying /tmp/stapcvFF5Q/hello.ko to hello.ko
Module signed with MOK, fingerprint "71:6d:81:10:8f:93:98:ad:77:de:e1:00:8d:65:16:77:0e:da:04:59"
Running rm -rf /tmp/stapcvFF5Q
Spawn waitpid result (0x0): 0
Removed temporary directory "/tmp/stapcvFF5Q"

# /usr/src/kernels/$(uname -r)/scripts/extract-module-sig.pl -s ./hello.ko 
Read 1284280 bytes from module file
Magic number not found at 1284280
--> NO SIGNATURE
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------

Digging into this with GDB, it appears it's the SOURCE module, in /tmp/stapcvFF5Q temporary directory, that got signed, but the signing is done AFTER copying to current directory, hence has no effect on the destination module:

-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------
# gdb --args stap --sign-module -m hello -vv -p4 -e 'probe begin { printf("hello\n"); exit() }' 
[...]

(gdb) break remove_tmp_dir
Breakpoint 1 at 0x92cb0: file session.cxx, line 2683.
(gdb) run

[...]

Copying /tmp/stapBcSIKR/hello.ko to hello.ko
[Detaching after vfork from child process 14476]
Module signed with MOK, fingerprint "71:6d:81:10:8f:93:98:ad:77:de:e1:00:8d:65:16:77:0e:da:04:59"

Breakpoint 1, systemtap_session::remove_tmp_dir (this=0x7fffffffd410) at session.cxx:2683

[...]

(gdb) !bash

# /usr/src/kernels/4.18.0-477.21.1.el8_8.x86_64/scripts/extract-module-sig.pl -s /tmp/stapBcSIKR/hello.ko 
Read 1285014 bytes from module file
Found magic number at 1285014
Found PKCS#7/CMS encapsulation
Found 694 bytes of signature [308202b206092a864886f70d010702a0]
[...]

--> CORRECT, SIGNED, but it's the temporary module!!!
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------

Checking the source code, it looks like the copying and signing have to be inverted:
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------
 511 // Compilation passes 0 through 4
 512 int       
 513 passes_0_4 (systemtap_session &s)
 514 {   
 :
1309       // Copy module to the current directory.
1310       if (s.save_module && !pending_interrupts)
1311         {
1312           string module_src_path = s.tmpdir + "/" + s.module_filename();
1313           string module_dest_path = s.module_filename();
1314           copy_file(module_src_path, module_dest_path, s.verbose > 1);
1315         }
 :
1326 #if HAVE_NSS
1327   if (s.module_sign_given)
1328     {
1329       // when run on client as --sign-module, mok fingerprints are result of mokutil -l
1330       // when run from server as --sign-module=PATH, mok fingerprint is given by PATH
1331       string mok_path;
1332       if (!s.module_sign_mok_path.empty())
1333         {
1334           string mok_fingerprint;
1335           split_path (s.module_sign_mok_path, mok_path, mok_fingerprint);
1336           s.mok_fingerprints.clear();
1337           s.mok_fingerprints.push_back(mok_fingerprint);
1338         }
1339 
1340       rc = sign_module (s.tmpdir, s.module_filename(), s.mok_fingerprints, mok_path, s.kernel_build_tree);
1341     }
1342 #endif
 :
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------

Version-Release number of selected component (if applicable):

systemtap-client-4.8-2.el8.x86_64 (RHEL8)
systemtap-client-4.8-2.el9.x86_64 (RHEL9)

How reproducible:

Always, see above.

Comment 1 Frank Ch. Eigler 2023-08-12 17:14:48 UTC
Thanks for the clear diagnosis & almost-complete fix.

Comment 2 Frank Ch. Eigler 2023-08-12 19:04:19 UTC
upstream commit 9839db5514 appears to fix this problem


Note You need to log in before you can comment on or make changes to this bug.