[SCM] Debian package checker branch, master, updated. 2.5.6-60-g33acfe7
The following commit has been merged in the master branch:
commit d44806c01bc074364c6f422d8dbeeaec74b4d27e
Author: Kees Cook <kees@outflux.net>
Date: Thu Dec 1 16:04:00 2011 -0800
Add initial lintian checks for ELF hardening
This adds the "hardening-info" collector which depends on the
new "--lintian" mode of the "hardening-check" tool found in the
"hardening-includes" package.
Signed-off-by: Kees Cook <kees@debian.org>
Changes to the original patch:
* Give hardening tags a common prefix in their names
* Remove hardening-no-bindnow and hardening-no-format tags
* Minor test clean up
Signed-off-by: Niels Thykier <niels@thykier.net>
diff --git a/checks/binaries b/checks/binaries
index faa4b8b..d5842b5 100644
--- a/checks/binaries
+++ b/checks/binaries
@@ -1,6 +1,7 @@
# binaries -- lintian check script -*- perl -*-
# Copyright (C) 1998 Christian Schwarz and Richard Braakman
+# Copyright (C) 2012 Kees Cook
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -429,6 +430,15 @@ foreach my $file (@{$info->sorted_index}) {
tag 'program-not-linked-against-libc', $file;
}
}
+
+ # Check for missing hardening characteristics. This currently
+ # handles the following checks:
+ # no-relro no-fortify-functions no-stackprotector no-bindnow no-pie
+ if (exists($info->hardening_info->{$file})) {
+ foreach my $tag (@{$info->hardening_info->{$file}}) {
+ tag "hardening-$tag", $file;
+ }
+ }
}
}
diff --git a/checks/binaries.desc b/checks/binaries.desc
index 4e0ad1e..fe5fed7 100644
--- a/checks/binaries.desc
+++ b/checks/binaries.desc
@@ -2,7 +2,7 @@ Check-Script: binaries
Author: Christian Schwarz <schwarz@debian.org>
Abbrev: bin
Type: binary, udeb
-Needs-Info: objdump-info, file-info, strings, index
+Needs-Info: hardening-info, objdump-info, file-info, strings, index
Info: This script checks binaries and object files for bugs.
Tag: arch-independent-package-contains-binary-or-object
@@ -299,3 +299,36 @@ Info: This package provides an OCaml bytecode executable linked with a
custom runtime. Such executables cannot be stripped and require
special care. Their usage is deprecated in favour of shared libraries
for C stubs (dll*.so).
+
+Tag: hardening-no-stackprotector
+Severity: normal
+Certainty: possible
+Info: This package provides an ELF binary that lacks the stack protector
+ function <tt>__stack_chk_fail</tt>. Either there are no character arrays used
+ on the stack of any routines, or the package was not built with the
+ default Debian compiler flags defined by <tt>dpkg-buildflags</tt>. If built
+ using <tt>dpkg-buildflags</tt> directly, be sure to import <tt>CFLAGS</tt>
+ and/or <tt>CXXFLAGS</tt>.
+Ref: http://wiki.debian.org/Hardening
+
+Tag: hardening-no-fortify-functions
+Severity: normal
+Certainty: possible
+Info: This package provides an ELF binary that lacks the use of fortified
+ libc functions. Either there are no potentially unfortified functions
+ called by any routines, all unfortified calls have already been fully
+ validated at compile-time, or the package was not built with the default
+ Debian compiler flags defined by <tt>dpkg-buildflags</tt>. If built using
+ <tt>dpkg-buildflags</tt> directly, be sure to import <tt>CPPFLAGS</tt>.
+Ref: http://wiki.debian.org/Hardening
+
+Tag: hardening-no-relro
+Severity: normal
+Certainty: certain
+Info: This package provides an ELF binary that lacks the "read-only
+ relocation" link flag. This package was likely not built with the
+ default Debian compiler flags defined by <tt>dpkg-buildflags</tt>.
+ If built using <tt>dpkg-buildflags</tt> directly, be sure to import
+ <tt>LDFLAGS</tt>.
+Ref: http://wiki.debian.org/Hardening
+
diff --git a/collection/hardening-info b/collection/hardening-info
new file mode 100755
index 0000000..c8e49d0
--- /dev/null
+++ b/collection/hardening-info
@@ -0,0 +1,98 @@
+#!/usr/bin/perl -w
+# hardening-info -- lintian collection script
+
+# The original shell script version of this script is
+# Copyright (C) 1998 Christian Schwarz
+#
+# The objdump version, including support for etch's binutils, is
+# Copyright (C) 2008 Adam D. Barratt
+#
+# This version, a trimmed-down wrapper for hardening-check, is
+# Copyright (C) 2012 Kees Cook <kees@debian.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, you can find it on the World Wide
+# Web at http://www.gnu.org/copyleft/gpl.html, or write to the Free
+# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+use strict;
+use warnings;
+
+use lib "$ENV{'LINTIAN_ROOT'}/lib";
+use Util;
+use Cwd;
+
+open (OUT, '>', 'hardening-info')
+ or fail("cannot open hardening-info: $!");
+
+# If we're running inside the Lintian test suite itself, we need to avoid
+# all the tests except the "binaries-hardening" test.
+my $base = Cwd::realpath('.');
+exit 0
+ if (defined $ENV{'LINTIAN_INTERNAL_TESTSUITE'} and
+ $ENV{'LINTIAN_INTERNAL_TESTSUITE'} eq "1" and
+ $base !~ m|/binaries-hardening/binaries-hardening_1.0_.*_binary$|);
+
+open (FILES, '<', 'file-info')
+ or fail("cannot open file-info: $!");
+
+# Override the arch seen by dpkg-buildflags for the arch of this package.
+my @fields = read_dpkg_control ('control/control');
+defined ($fields[0]{'architecture'})
+ or fail ("cannot determine architecture of package!");
+$ENV{'DEB_HOST_ARCH'} = $fields[0]{'architecture'}
+ if ($fields[0]{'architecture'} ne "all");
+
+# Prepare to examine the file tree.
+chdir ('unpacked')
+ or fail("unable to chdir to unpacked: $!");
+
+# We must figure out what hardening features are expected by default for a
+# given architecture. Extract this from "dpkg-buildflags", and set up the
+# needed arguments for calling "hardening-check".
+open (my $FLAGS, '-|', "dpkg-buildflags --query-features hardening")
+ or fail ("could not launch dpkg-buildflags: $!");
+my $args = "--lintian";
+my $feature = "";
+@fields = parse_dpkg_control ($FLAGS);
+foreach my $flag (@fields) {
+ if ($flag->{enabled} eq "no") {
+ $args .= " --no" . $flag->{feature};
+ }
+}
+close $FLAGS;
+
+while (<FILES>) {
+ if (m/^(.+?)\x00\s.*ELF/) {
+ my $bin = $1;
+
+ if (open (PIPE, '-|', "hardening-check $args -- \Q$bin\E 2>&1")) {
+ local $/;
+ local $_ = <PIPE>;
+ print OUT $_;
+ close PIPE;
+ }
+ }
+}
+
+close FILES;
+close OUT or fail("cannot write objdump-info: $!");
+
+exit 0;
+
+# Local Variables:
+# indent-tabs-mode: nil
+# cperl-indent-level: 4
+# End:
+# vim: syntax=perl sw=4 sts=4 sr et
diff --git a/collection/hardening-info.desc b/collection/hardening-info.desc
new file mode 100644
index 0000000..ee051fe
--- /dev/null
+++ b/collection/hardening-info.desc
@@ -0,0 +1,7 @@
+Collector-Script: hardening-info
+Author: Kees Cook <kees@debian.org>
+Info: This script runs hardening-check(1) over all ELF binaries of a binary
+ package.
+Type: binary, udeb
+Version: 1
+Needs-Info: bin-pkg-control, file-info, unpacked
diff --git a/debian/changelog b/debian/changelog
index 99cf292..c0798b7 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -11,6 +11,9 @@ lintian (2.5.7) UNRELEASED; urgency=low
- debian-control-with-duplicate-fields
- doc-base-file-references-usr-doc
- duplicate-fields-in-templates
+ - hardening-no-fortify-functions
+ - hardening-no-relro
+ - hardening-no-stackprotector
- manpage-for-non-x11-binary-in-wrong-directory
- manpage-for-x11-binary-in-wrong-directory
- obsolete-field
@@ -28,8 +31,10 @@ lintian (2.5.7) UNRELEASED; urgency=low
+ [NT] Remove some old tags that are no longer useful.
(Closes: #663516)
+ [NT] Migrate to sorted_index from sorted_file_info.
- * checks/binaries:
+ * checks/binaries{,.desc}:
+ [NT] Move embedded library data to a data file.
+ + [NT] Add ELF hardening checks. Thanks to Kees Cook for
+ report and the patches. (Closes: 650536)
* checks/changes-file{,.desc}:
+ [NT] Remove Ubuntu specific handling of distribution names.
Instead replace it with a more generalized one that derivatives
@@ -72,6 +77,8 @@ lintian (2.5.7) UNRELEASED; urgency=low
bin-pkg-control.
* collection/file-info{,.desc}:
+ [NT] Compress file-info output and bump version of file-info.
+ * collection/hardening-info{,.desc}:
+ + [NT] New files. Thanks to Kees Cook for the patch.
* collection/index{,.desc}:
+ [NT] Compress index output and bump version of index.
* collection/objdump-info:
diff --git a/debian/control b/debian/control
index 24be849..6967aae 100644
--- a/debian/control
+++ b/debian/control
@@ -16,9 +16,11 @@ Build-Depends: binutils,
diffstat,
docbook-utils,
docbook-xml,
+ dpkg-dev (>= 1.16.2~wipmultiarch),
fakeroot,
file,
gettext,
+ hardening-includes (>= 1.35),
intltool-debian,
javahelper (>= 0.32~),
libapt-pkg-perl,
@@ -60,8 +62,10 @@ Architecture: all
Depends: binutils,
bzip2,
diffstat,
+ dpkg-dev (>= 1.16.2~wipmultiarch),
file,
gettext,
+ hardening-includes (>= 1.35),
intltool-debian,
libapt-pkg-perl,
libc-bin (>= 2.13) | locales,
@@ -80,7 +84,6 @@ Depends: binutils,
unzip,
${misc:Depends}
Suggests: binutils-multiarch,
- dpkg-dev,
libhtml-parser-perl,
libtext-template-perl,
man-db (>= 2.5.1-1),
diff --git a/lib/Lintian/Collect/Binary.pm b/lib/Lintian/Collect/Binary.pm
index 0c50326..6098eec 100644
--- a/lib/Lintian/Collect/Binary.pm
+++ b/lib/Lintian/Collect/Binary.pm
@@ -3,6 +3,7 @@
# Copyright (C) 2008, 2009 Russ Allbery
# Copyright (C) 2008 Frank Lichtenheld
+# Copyright (C) 2012 Kees Cook
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
@@ -227,6 +228,32 @@ sub objdump_info {
}
+# Returns the information from collect/hardening-info
+# sub hardening_info Needs-Info hardening-info
+sub hardening_info {
+ my ($self) = @_;
+ return $self->{hardening_info} if exists $self->{hardening_info};
+ my $base_dir = $self->base_dir();
+ my %hardening_info;
+ my ($file);
+ open(my $idx, '<', "$base_dir/hardening-info")
+ or fail("cannot open $base_dir/hardening-info: $!");
+ while (<$idx>) {
+ chomp;
+
+ if (m,^([^:]+):\./(.*)$,) {
+ my ($tag, $file) = ($1, $2);
+
+ push(@{$hardening_info{$file}}, $tag);
+ }
+ }
+
+ $self->{hardening_info} = \%hardening_info;
+
+ return $self->{hardening_info};
+}
+
+
# Returns the information from collect/objdump-info
# sub java_info Needs-Info java-info
sub java_info {
diff --git a/t/scripts/implemented-tags.t b/t/scripts/implemented-tags.t
index 2575748..8672416 100755
--- a/t/scripts/implemented-tags.t
+++ b/t/scripts/implemented-tags.t
@@ -42,6 +42,7 @@ our $EXCLUDE =
^example.*interpreter.*
^example-script-.*$
^example-shell-script-.*$
+ ^hardening-.*$
));
# Find all of the check description files. We'll do one check per
diff --git a/t/tests/binaries-hardening/debian/Makefile b/t/tests/binaries-hardening/debian/Makefile
new file mode 100644
index 0000000..40ce958
--- /dev/null
+++ b/t/tests/binaries-hardening/debian/Makefile
@@ -0,0 +1,24 @@
+all: weak.1 strong.1
+ # Build without dpkg-buildflags.
+ gcc -o weak hello.c
+ gcc -o strong \
+ $(shell dpkg-buildflags --get CPPFLAGS) \
+ $(shell dpkg-buildflags --get CFLAGS) \
+ $(shell dpkg-buildflags --get LDFLAGS) \
+ hello.c
+%.1: base.pod
+ sed s/@NAME@/$(basename $@)/g < $< | \
+ pod2man --name $(basename $@) --section 1 > $@
+
+install:
+ install -d $(DESTDIR)/usr/bin/
+ install -d $(DESTDIR)/usr/share/man/man1
+ install -m 755 -c weak $(DESTDIR)/usr/bin/weak
+ install -m 755 -c strong $(DESTDIR)/usr/bin/strong
+ install -m 644 -c weak.1 $(DESTDIR)/usr/share/man/man1/weak.1
+ install -m 644 -c strong.1 $(DESTDIR)/usr/share/man/man1/strong.1
+
+clean distclean:
+ rm -f weak strong *.1
+
+check test:
diff --git a/t/tests/binaries-hardening/debian/base.pod b/t/tests/binaries-hardening/debian/base.pod
new file mode 100644
index 0000000..1e900d7
--- /dev/null
+++ b/t/tests/binaries-hardening/debian/base.pod
@@ -0,0 +1,12 @@
+=head1 NAME
+
+@NAME@ -- binary that does something
+
+=head1 SYNOPSIS
+
+ @NAME@ [options]
+
+=head1 DESCRIPTION
+
+@NAME@ does something very useful.
+
diff --git a/t/tests/binaries-hardening/debian/hello.c b/t/tests/binaries-hardening/debian/hello.c
new file mode 100644
index 0000000..7b87bd7
--- /dev/null
+++ b/t/tests/binaries-hardening/debian/hello.c
@@ -0,0 +1,17 @@
+#include <stdio.h>
+
+void
+report(char *string)
+{
+ char buf[80];
+ int len;
+
+ strcpy(buf, string);
+ fprintf(stdout, "Hello world from %s!\n%n", buf, &len);
+}
+
+int
+main(int argc, char *argv[])
+{
+ report(argv[0]);
+}
diff --git a/t/tests/binaries-hardening/desc b/t/tests/binaries-hardening/desc
new file mode 100644
index 0000000..ad18843
--- /dev/null
+++ b/t/tests/binaries-hardening/desc
@@ -0,0 +1,9 @@
+Testname: binaries-hardening
+Sequence: 6000
+Version: 1.0
+Description: Check for missing hardening features
+Architecture: amd64 i386
+Test-For:
+ hardening-no-relro
+ hardening-no-stackprotector
+ hardening-no-fortify-functions
diff --git a/t/tests/binaries-hardening/tags b/t/tests/binaries-hardening/tags
new file mode 100644
index 0000000..ec90777
--- /dev/null
+++ b/t/tests/binaries-hardening/tags
@@ -0,0 +1,3 @@
+W: binaries-hardening: hardening-no-fortify-functions usr/bin/weak
+W: binaries-hardening: hardening-no-relro usr/bin/weak
+W: binaries-hardening: hardening-no-stackprotector usr/bin/weak
--
Debian package checker
Reply to: