forked from pool/suse-module-tools
Accepting request 400389 from Base:System
1 OBS-URL: https://build.opensuse.org/request/show/400389 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/suse-module-tools?expand=0&rev=21
This commit is contained in:
commit
ebb0abb2cd
149
modhash
Normal file
149
modhash
Normal file
@ -0,0 +1,149 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
# Calculate the digest of the kernel module
|
||||
# It will strip kernel modules signature before calculation.
|
||||
#
|
||||
# Based on modsign-verify, written by Michal Marek
|
||||
# Authors:
|
||||
# Gary Lin <GLin@suse.com>
|
||||
# Joey Lee <JLee@suse.com>
|
||||
#
|
||||
|
||||
my $USAGE = "Usage: modhash [-v] [-q] [-d <digest algorithm>] <module>\n";
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use IPC::Open2;
|
||||
use Getopt::Long;
|
||||
use File::Temp qw(tempfile);
|
||||
|
||||
my $verbose = 1;
|
||||
my $dgst = "sha256";
|
||||
GetOptions(
|
||||
"d=s" => \$dgst,
|
||||
"q|quiet" => sub { $verbose-- if $verbose; },
|
||||
"v|verbose" => sub { $verbose++; },
|
||||
"h|help" => sub {
|
||||
print $USAGE;
|
||||
exit(0);
|
||||
}
|
||||
) or die($USAGE);
|
||||
|
||||
sub _verbose {
|
||||
my $level = shift;
|
||||
|
||||
return if $verbose < $level;
|
||||
print STDERR @_;
|
||||
}
|
||||
|
||||
sub info { _verbose(1, @_); }
|
||||
sub verbose { _verbose(2, @_); }
|
||||
sub debug { _verbose(3, @_); }
|
||||
|
||||
if (@ARGV > 1) {
|
||||
print STDERR "Excess arguments\n";
|
||||
die($USAGE);
|
||||
} elsif (@ARGV < 1) {
|
||||
print STDERR "No module supplied\n";
|
||||
die($USAGE);
|
||||
}
|
||||
my $module_name = shift(@ARGV);
|
||||
|
||||
if ($dgst ne "sha" and $dgst ne "sha1" and $dgst ne "sha256" and
|
||||
$dgst ne "sha384" and $dgst ne "sha512") {
|
||||
die("unsupported algorithm: $dgst");
|
||||
}
|
||||
|
||||
#
|
||||
# Function to read the contents of a file into a variable.
|
||||
#
|
||||
sub read_file($)
|
||||
{
|
||||
my ($file) = @_;
|
||||
my $contents;
|
||||
my $len;
|
||||
|
||||
open(FD, "<$file") || die $file;
|
||||
binmode FD;
|
||||
my @st = stat(FD);
|
||||
die $file if (!@st);
|
||||
$len = read(FD, $contents, $st[7]) || die $file;
|
||||
close(FD) || die $file;
|
||||
die "$file: Wanted length ", $st[7], ", got ", $len, "\n"
|
||||
if ($len != $st[7]);
|
||||
return $contents;
|
||||
}
|
||||
|
||||
sub openssl_pipe($$) {
|
||||
my ($input, $cmd) = @_;
|
||||
my ($pid, $res);
|
||||
|
||||
$pid = open2(*read_from, *write_to, $cmd) || die $cmd;
|
||||
binmode write_to;
|
||||
if (defined($input) && $input ne "") {
|
||||
print write_to $input || die "$cmd: $!";
|
||||
}
|
||||
close(write_to) || die "$cmd: $!";
|
||||
|
||||
binmode read_from;
|
||||
read(read_from, $res, 4096) || die "$cmd: $!";
|
||||
close(read_from) || die "$cmd: $!";
|
||||
waitpid($pid, 0) || die;
|
||||
die "$cmd died: $?" if ($? >> 8);
|
||||
return $res;
|
||||
}
|
||||
|
||||
my $module = read_file($module_name);
|
||||
my $module_len = length($module);
|
||||
my $magic_number = "~Module signature appended~\n";
|
||||
my $magic_len = length($magic_number);
|
||||
my $info_len = 12;
|
||||
|
||||
if ($module_len < $magic_len) {
|
||||
die "Module size too short\n";
|
||||
}
|
||||
|
||||
sub eat
|
||||
{
|
||||
my $length = shift;
|
||||
if ($module_len < $length) {
|
||||
die "Module size too short\n";
|
||||
}
|
||||
my $res = substr($module, -$length);
|
||||
$module = substr($module, 0, $module_len - $length);
|
||||
$module_len -= $length;
|
||||
return $res;
|
||||
}
|
||||
|
||||
if (substr($module, -$magic_len) eq $magic_number) {
|
||||
$module = substr($module, 0, $module_len - $magic_len);
|
||||
$module_len -= $magic_len;
|
||||
my $info = eat($info_len);
|
||||
my ($algo, $hash, $id_type, $name_len, $key_len, $sig_len) =
|
||||
unpack("CCCCCxxxN", $info);
|
||||
my $signature = eat($sig_len);
|
||||
if ($id_type == 1) {
|
||||
if (unpack("n", $signature) == $sig_len - 2) {
|
||||
verbose ("signed module (X.509)\n");
|
||||
} else {
|
||||
die "Invalid signature format\n";
|
||||
}
|
||||
if ($algo != 1) {
|
||||
die "Unsupported signature algorithm\n";
|
||||
}
|
||||
$signature = substr($signature, 2);
|
||||
my $key_id = eat($key_len);
|
||||
my $name = eat($name_len);
|
||||
} elsif ($id_type == 2) {
|
||||
verbose ("signed module (PKCS#7)\n");
|
||||
}
|
||||
} else {
|
||||
verbose ("unsigned module\n");
|
||||
}
|
||||
|
||||
verbose("Hash algorithm: $dgst\n");
|
||||
|
||||
my $digest = openssl_pipe($module, "openssl dgst -$dgst");
|
||||
$digest =~ s/\(stdin\)= //;
|
||||
|
||||
print "$module_name: $digest"
|
@ -1,3 +1,20 @@
|
||||
-------------------------------------------------------------------
|
||||
Fri May 27 13:14:36 UTC 2016 - mmarek@suse.cz
|
||||
|
||||
- Run dos2unix on the modhash script.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu May 26 07:36:58 UTC 2016 - jlee@suse.com
|
||||
|
||||
- Add modhash tool to calculate hash of signed module.
|
||||
It strips X.509 or PKCS#7 signature before hash kernel module.
|
||||
(fate#319460)
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed May 25 13:23:35 UTC 2016 - mmarek@suse.cz
|
||||
|
||||
- Remove -x bit from 50-kernel-uname_r.conf (bsc#981291).
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Apr 29 11:31:46 UTC 2016 - mmarek@suse.cz
|
||||
|
||||
|
@ -46,6 +46,7 @@ Source10: kmp-install
|
||||
Source11: macros.initrd
|
||||
Source12: regenerate-initrd-posttrans
|
||||
Source13: 50-kernel-uname_r.conf
|
||||
Source14: modhash
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||
|
||||
%description
|
||||
@ -94,10 +95,12 @@ install -pm 755 "%_sourcedir/regenerate-initrd-posttrans" "$b/usr/lib/module-ini
|
||||
install -d -m 755 "$b/usr/bin"
|
||||
install -pm 755 %_sourcedir/modsign-verify "$b/usr/bin/"
|
||||
install -pm 755 %_sourcedir/kmp-install "$b/usr/bin/"
|
||||
# modhash for calculating hash of signed kernel module
|
||||
install -pm 755 %_sourcedir/modhash "$b/usr/bin/"
|
||||
|
||||
# systemd service to load /boot/sysctl.conf-`uname -r`
|
||||
install -d -m 755 "$b/usr/lib/systemd/system/systemd-sysctl.service.d"
|
||||
install -pm 755 %_sourcedir/50-kernel-uname_r.conf "$b/usr/lib/systemd/system/systemd-sysctl.service.d"
|
||||
install -pm 644 %_sourcedir/50-kernel-uname_r.conf "$b/usr/lib/systemd/system/systemd-sysctl.service.d"
|
||||
|
||||
%post
|
||||
test_allow_on_install()
|
||||
@ -163,6 +166,7 @@ fi
|
||||
%config /etc/depmod.d/00-system.conf
|
||||
%config /etc/rpm/macros.initrd
|
||||
%_docdir/module-init-tools
|
||||
/usr/bin/modhash
|
||||
/usr/bin/kmp-install
|
||||
/usr/bin/modsign-verify
|
||||
/usr/lib/module-init-tools
|
||||
|
Loading…
Reference in New Issue
Block a user