Dpkg::Vendor::Ubuntu: Default to fortify level 3
[dpkg.git] / scripts / Dpkg / Vendor / Ubuntu.pm
blobb50da3711c720d43ea495238f23f95c76e207ec2
1 # Copyright © 2008 Ian Jackson <ijackson@chiark.greenend.org.uk>
2 # Copyright © 2008 Canonical, Ltd.
3 # written by Colin Watson <cjwatson@ubuntu.com>
4 # Copyright © 2008 James Westby <jw+debian@jameswestby.net>
5 # Copyright © 2009 Raphaël Hertzog <hertzog@debian.org>
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program. If not, see <https://www.gnu.org/licenses/>.
20 =encoding utf8
22 =head1 NAME
24 Dpkg::Vendor::Ubuntu - Ubuntu vendor class
26 =head1 DESCRIPTION
28 This vendor class customizes the behavior of dpkg scripts for Ubuntu
29 specific behavior and policies.
31 B<Note>: This is a private module, its API can change at any time.
33 =cut
35 package Dpkg::Vendor::Ubuntu 0.01;
37 use strict;
38 use warnings;
40 use List::Util qw(any);
42 use Dpkg::ErrorHandling;
43 use Dpkg::Gettext;
44 use Dpkg::Control::Types;
46 use parent qw(Dpkg::Vendor::Debian);
48 sub run_hook {
49 my ($self, $hook, @params) = @_;
51 if ($hook eq 'before-source-build') {
52 my $src = shift @params;
53 my $fields = $src->{fields};
55 # check that Maintainer/XSBC-Original-Maintainer comply to
56 # https://wiki.ubuntu.com/DebianMaintainerField
57 if (defined($fields->{'Version'}) and defined($fields->{'Maintainer'}) and
58 $fields->{'Version'} =~ /ubuntu/) {
59 if ($fields->{'Maintainer'} !~ /(?:ubuntu|canonical)/i) {
60 if (length $ENV{DEBEMAIL} and $ENV{DEBEMAIL} =~ /\@(?:ubuntu|canonical)\.com/) {
61 error(g_('Version number suggests Ubuntu changes, but Maintainer: does not have Ubuntu address'));
62 } else {
63 warning(g_('Version number suggests Ubuntu changes, but Maintainer: does not have Ubuntu address'));
66 unless ($fields->{'Original-Maintainer'}) {
67 warning(g_('Version number suggests Ubuntu changes, but there is no XSBC-Original-Maintainer field'));
70 } elsif ($hook eq 'package-keyrings') {
71 return ($self->SUPER::run_hook($hook),
72 '/usr/share/keyrings/ubuntu-archive-keyring.gpg');
73 } elsif ($hook eq 'archive-keyrings') {
74 return ($self->SUPER::run_hook($hook),
75 '/usr/share/keyrings/ubuntu-archive-keyring.gpg');
76 } elsif ($hook eq 'archive-keyrings-historic') {
77 return ($self->SUPER::run_hook($hook),
78 '/usr/share/keyrings/ubuntu-archive-removed-keys.gpg');
79 } elsif ($hook eq 'register-custom-fields') {
80 my @field_ops = $self->SUPER::run_hook($hook);
81 push @field_ops, [
82 'register', 'Launchpad-Bugs-Fixed',
83 CTRL_FILE_CHANGES | CTRL_CHANGELOG,
84 ], [
85 'insert_after', CTRL_FILE_CHANGES, 'Closes', 'Launchpad-Bugs-Fixed',
86 ], [
87 'insert_after', CTRL_CHANGELOG, 'Closes', 'Launchpad-Bugs-Fixed',
89 return @field_ops;
90 } elsif ($hook eq 'post-process-changelog-entry') {
91 my $fields = shift @params;
93 # Add Launchpad-Bugs-Fixed field
94 my $bugs = find_launchpad_closes($fields->{'Changes'} // '');
95 if (scalar(@$bugs)) {
96 $fields->{'Launchpad-Bugs-Fixed'} = join(' ', @$bugs);
98 } elsif ($hook eq 'update-buildflags') {
99 my $flags = shift @params;
101 # Run the Debian hook to add hardening flags
102 $self->SUPER::run_hook($hook, $flags);
104 # Per https://wiki.ubuntu.com/DistCompilerFlags
105 $flags->prepend('LDFLAGS', '-Wl,-Bsymbolic-functions');
106 } else {
107 return $self->SUPER::run_hook($hook, @params);
111 # Override Debian default features.
112 sub init_build_features {
113 my ($self, $use_feature, $builtin_feature) = @_;
115 $self->SUPER::init_build_features($use_feature, $builtin_feature);
117 require Dpkg::Arch;
118 my $arch = Dpkg::Arch::get_host_arch();
120 if (any { $_ eq $arch } qw(amd64 arm64 ppc64el s390x)) {
121 $use_feature->{optimize}{lto} = 1;
125 sub set_build_features {
126 my ($self, $flags) = @_;
128 $self->SUPER::set_build_features($flags);
130 require Dpkg::Arch;
131 my $arch = Dpkg::Arch::get_host_arch();
133 if ($arch eq 'ppc64el' && $flags->get_option_value('optimize-level') != 0) {
134 $flags->set_option_value('optimize-level', 3);
137 $flags->set_option_value('fortify-level', 3);
140 =head1 PUBLIC FUNCTIONS
142 =over
144 =item $bugs = Dpkg::Vendor::Ubuntu::find_launchpad_closes($changes)
146 Takes one string as argument and finds "LP: #123456, #654321" statements,
147 which are references to bugs on Launchpad. Returns all closed bug
148 numbers in an array reference.
150 =cut
152 sub find_launchpad_closes {
153 my $changes = shift;
154 my %closes;
156 while ($changes &&
157 ($changes =~ /lp:\s+\#\d+(?:,\s*\#\d+)*/pig)) {
158 $closes{$_} = 1 foreach (${^MATCH} =~ /\#?\s?(\d+)/g);
161 my @closes = sort { $a <=> $b } keys %closes;
163 return \@closes;
166 =back
168 =head1 CHANGES
170 =head2 Version 0.xx
172 This is a semi-private module. Only documented functions are public.
174 =cut