The following commit has been merged in the master branch:
commit 8994a516a52f1e5927d1ce7f31f854a7ccf872d8
Author: Kees Cook <[email protected]>
Date: Thu Dec 8 15:53:14 2011 -0800
dpkg-buildflags: new --query-features command
Since the logic for having a hardening flag enabled or disabled depends
on the architecture, and since the flags may change over time for each
hardening feature, there needs to be a way to externally query the state
of the hardening features. Specifically, lintian needs this to be able
to figure out if a binary package is missing expected hardening features.
Instead of maintaining multiple hard-coded lists of expected hardening
features, this makes dpkg-buildflags the canonical location of the
information, which can be queried by externally. (See bug 650536.)
Signed-off-by: Kees Cook <[email protected]>
Signed-off-by: Raphaël Hertzog <[email protected]>
diff --git a/debian/changelog b/debian/changelog
index fff5158..fc5fde6 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -70,6 +70,8 @@ dpkg (1.16.2) UNRELEASED; urgency=low
is given with a relative filename. Closes: #652414
* Further clarify in dpkg-source(1) the conditions under which it's possible
to pass an explicit patch file to dpkg-source --commit.
+ * Add new --query-features command to dpkg-buildflags. Thanks to Kees Cook
+ for the patch. Closes: #651481
[ Jonathan Nieder ]
* Bump po4a version in Build-Depends to 0.41, since earlier versions do
diff --git a/man/dpkg-buildflags.1 b/man/dpkg-buildflags.1
index b86ae0d..2b5fb2e 100644
--- a/man/dpkg-buildflags.1
+++ b/man/dpkg-buildflags.1
@@ -87,6 +87,22 @@ the flag is set/modified by a user-specific configuration;
the flag is set/modified by an environment-specific configuration.
.RE
.TP
+.BI \-\-query\-features " area"
+Print the features enabled for a given area. The only currently recognized
+area is \fBhardening\fP. Exits with 0 if the area is known otherwise exits
+with 1.
+.IP
+The output format is RFC822 header-style, with one section per feature.
+For example:
+.IP
+.nf
+ Feature: pie
+ Enabled: no
+
+ Feature: stackprotector
+ Enabled: yes
+.fi
+.TP
.B \-\-help
Show the usage message and exit.
.TP
diff --git a/scripts/Dpkg/BuildFlags.pm b/scripts/Dpkg/BuildFlags.pm
index 6112a9f..b114335 100644
--- a/scripts/Dpkg/BuildFlags.pm
+++ b/scripts/Dpkg/BuildFlags.pm
@@ -18,7 +18,7 @@ package Dpkg::BuildFlags;
use strict;
use warnings;
-our $VERSION = "1.01";
+our $VERSION = "1.02";
use Dpkg::Gettext;
use Dpkg::BuildOptions;
@@ -68,6 +68,7 @@ sub load_vendor_defaults {
my ($self) = @_;
$self->{'options'} = {};
$self->{'source'} = {};
+ $self->{'features'} = {};
my $build_opts = Dpkg::BuildOptions->new();
my $default_flags = $build_opts->has("noopt") ? "-g -O0" : "-g -O2";
$self->{flags} = {
@@ -202,6 +203,19 @@ sub set {
$self->{origin}->{$flag} = $src if defined $src;
}
+=item $bf->set_feature($area, $feature, $enabled)
+
+Update the boolean state of whether a specific feature within a known
+feature area has been enabled. The only currently known feature area is
+"hardening".
+
+=cut
+
+sub set_feature {
+ my ($self, $area, $feature, $enabled) = @_;
+ $self->{'features'}{$area}{$feature} = $enabled;
+}
+
=item $bf->strip($flag, $value, $source)
Update the build flag $flag by stripping the flags listed in $value and
@@ -306,6 +320,18 @@ sub get {
return $self->{'flags'}{$key};
}
+=item $bf->get_features($area)
+
+Return, for the given area, a hash with keys as feature names, and values
+as booleans indicating whether the feature is enabled or not.
+
+=cut
+
+sub get_features {
+ my ($self, $area) = @_;
+ return %{$self->{'features'}{$area}};
+}
+
=item $bf->get_origin($flag)
Return the origin associated to the flag. It might be undef if the
@@ -318,6 +344,18 @@ sub get_origin {
return $self->{'origin'}{$key};
}
+=item $bf->has_features($area)
+
+Returns true if the given area of features is known, and false otherwise.
+The only currently recognized area is "hardening".
+
+=cut
+
+sub has_features {
+ my ($self, $area) = @_;
+ return exists $self->{'features'}{$area};
+}
+
=item $bf->has($option)
Returns a boolean indicating whether the flags exists in the object.
diff --git a/scripts/Dpkg/Vendor/Debian.pm b/scripts/Dpkg/Vendor/Debian.pm
index f363fee..537293f 100644
--- a/scripts/Dpkg/Vendor/Debian.pm
+++ b/scripts/Dpkg/Vendor/Debian.pm
@@ -174,6 +174,11 @@ sub add_hardening_flags {
if ($use_feature{"bindnow"}) {
$flags->append("LDFLAGS", "-Wl,-z,now");
}
+
+ # Store the feature usage.
+ while (my ($feature, $enabled) = each %use_feature) {
+ $flags->set_feature("hardening", $feature, $enabled);
+ }
}
1;
diff --git a/scripts/dpkg-buildflags.pl b/scripts/dpkg-buildflags.pl
index ee33961..8f4b7f0 100755
--- a/scripts/dpkg-buildflags.pl
+++ b/scripts/dpkg-buildflags.pl
@@ -47,6 +47,8 @@ Actions:
--get <flag> output the requested flag to stdout.
--origin <flag> output the origin of the flag to stdout:
value is one of vendor, system, user, env.
+ --query-features <area>
+ output the status of features for the given area.
--list output a list of the flags supported by the current
vendor.
--export=(sh|make|configure)
output something convenient to import the
@@ -62,7 +64,7 @@ my ($param, $action);
while (@ARGV) {
$_ = shift(@ARGV);
- if (m/^--(get|origin)$/) {
+ if (m/^--(get|origin|query-features)$/) {
usageerr(_g("two commands specified: --%s and --%s"), $1, $action)
if defined($action);
$action = $1;
@@ -115,6 +117,17 @@ if ($action eq "get") {
print $build_flags->get_origin($param) . "\n";
exit(0);
}
+} elsif ($action eq "query-features") {
+ if ($build_flags->has_features($param)) {
+ my %features = $build_flags->get_features($param);
+ my $para_shown = 0;
+ foreach my $feature (sort keys %features) {
+ print $para_shown++ ? "\n" : "";
+ printf "Feature: %s\n", $feature;
+ printf "Enabled: %s\n", $features{$feature} ? "yes" : "no";
+ }
+ exit(0);
+ }
} elsif ($action =~ m/^export-(.*)$/) {
my $export_type = $1;
foreach my $flag ($build_flags->list()) {
--
dpkg's main repository
--
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]