diff options
Diffstat (limited to 'lib/Lintian/Check/Libraries/Shared')
-rw-r--r-- | lib/Lintian/Check/Libraries/Shared/Exit.pm | 72 | ||||
-rw-r--r-- | lib/Lintian/Check/Libraries/Shared/FilePermissions.pm | 72 | ||||
-rw-r--r-- | lib/Lintian/Check/Libraries/Shared/Links.pm | 167 | ||||
-rw-r--r-- | lib/Lintian/Check/Libraries/Shared/MultiArch.pm | 79 | ||||
-rw-r--r-- | lib/Lintian/Check/Libraries/Shared/Obsolete.pm | 56 | ||||
-rw-r--r-- | lib/Lintian/Check/Libraries/Shared/Relocation.pm | 58 | ||||
-rw-r--r-- | lib/Lintian/Check/Libraries/Shared/Soname.pm | 123 | ||||
-rw-r--r-- | lib/Lintian/Check/Libraries/Shared/Soname/Missing.pm | 73 | ||||
-rw-r--r-- | lib/Lintian/Check/Libraries/Shared/Stack.pm | 69 | ||||
-rw-r--r-- | lib/Lintian/Check/Libraries/Shared/Trigger/Ldconfig.pm | 131 |
10 files changed, 900 insertions, 0 deletions
diff --git a/lib/Lintian/Check/Libraries/Shared/Exit.pm b/lib/Lintian/Check/Libraries/Shared/Exit.pm new file mode 100644 index 0000000..5788808 --- /dev/null +++ b/lib/Lintian/Check/Libraries/Shared/Exit.pm @@ -0,0 +1,72 @@ +# libraries/shared/exit -- lintian check script -*- perl -*- + +# Copyright (C) 1998 Christian Schwarz +# Copyright (C) 2018-2019 Chris Lamb <lamby@debian.org> +# Copyright (C) 2021 Felix Lechner +# +# 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 https://www.gnu.org/copyleft/gpl.html, or write to the Free +# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, +# MA 02110-1301, USA. + +package Lintian::Check::Libraries::Shared::Exit; + +use v5.20; +use warnings; +use utf8; + +use List::SomeUtils qw(any none); + +use Moo; +use namespace::clean; + +with 'Lintian::Check'; + +# not presently used +#my $UNKNOWN_SHARED_LIBRARY_EXCEPTIONS +# = $self->data->load('shared-libs/unknown-shared-library-exceptions'); + +sub visit_installed_files { + my ($self, $item) = @_; + + return + unless $item->is_file; + + # shared library + return + unless @{$item->elf->{SONAME} // [] }; + + my @symbols = grep { $_->section eq '.text' || $_->section eq 'UND' } + @{$item->elf->{SYMBOLS} // []}; + + my @symbol_names = map { $_->name } @symbols; + + # If it has an INTERP section it might be an application with + # a SONAME (hi openjdk-6, see #614305). Also see the comment + # for "shared-library-is-executable" below. + $self->pointed_hint('exit-in-shared-library', $item->pointer) + if (any { m/^_?exit$/ } @symbol_names) + && (none { $_ eq 'fork' } @symbol_names) + && !length $item->elf->{INTERP}; + + return; +} + +1; + +# Local Variables: +# indent-tabs-mode: nil +# cperl-indent-level: 4 +# End: +# vim: syntax=perl sw=4 sts=4 sr et diff --git a/lib/Lintian/Check/Libraries/Shared/FilePermissions.pm b/lib/Lintian/Check/Libraries/Shared/FilePermissions.pm new file mode 100644 index 0000000..663205e --- /dev/null +++ b/lib/Lintian/Check/Libraries/Shared/FilePermissions.pm @@ -0,0 +1,72 @@ +# libraries/shared/file-permissions -- lintian check script -*- perl -*- + +# Copyright (C) 1998 Christian Schwarz +# Copyright (C) 2018-2019 Chris Lamb <lamby@debian.org> +# Copyright (C) 2021 Felix Lechner +# +# 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 https://www.gnu.org/copyleft/gpl.html, or write to the Free +# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, +# MA 02110-1301, USA. + +package Lintian::Check::Libraries::Shared::FilePermissions; + +use v5.20; +use warnings; +use utf8; + +use Const::Fast; + +use Moo; +use namespace::clean; + +with 'Lintian::Check'; + +const my $WIDELY_READABLE => oct(644); + +sub visit_installed_files { + my ($self, $item) = @_; + + return + unless $item->is_file; + + # shared library + return + unless @{$item->elf->{SONAME} // [] }; + + # Yes. But if the library has an INTERP section, it's + # designed to do something useful when executed, so don't + # report an error. Also give ld.so a pass, since it's + # special. + $self->pointed_hint('shared-library-is-executable', + $item->pointer, $item->octal_permissions) + if $item->is_executable + && !$item->elf->{INTERP} + && $item->name !~ m{^lib.*/ld-[\d.]+\.so$}; + + $self->pointed_hint('odd-permissions-on-shared-library', + $item->pointer, $item->octal_permissions) + if !$item->is_executable + && $item->operm != $WIDELY_READABLE; + + return; +} + +1; + +# Local Variables: +# indent-tabs-mode: nil +# cperl-indent-level: 4 +# End: +# vim: syntax=perl sw=4 sts=4 sr et diff --git a/lib/Lintian/Check/Libraries/Shared/Links.pm b/lib/Lintian/Check/Libraries/Shared/Links.pm new file mode 100644 index 0000000..e25d3fd --- /dev/null +++ b/lib/Lintian/Check/Libraries/Shared/Links.pm @@ -0,0 +1,167 @@ +# libraries/shared/links -- lintian check script -*- perl -*- + +# Copyright (C) 1998 Christian Schwarz +# Copyright (C) 2018-2019 Chris Lamb <lamby@debian.org> +# Copyright (C) 2021 Felix Lechner +# +# 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 https://www.gnu.org/copyleft/gpl.html, or write to the Free +# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, +# MA 02110-1301, USA. + +package Lintian::Check::Libraries::Shared::Links; + +use v5.20; +use warnings; +use utf8; + +use Const::Fast; +use List::SomeUtils qw(none); + +const my $ARROW => q{->}; + +use Moo; +use namespace::clean; + +with 'Lintian::Check'; + +has development_packages => ( + is => 'rw', + lazy => 1, + default => sub { + my ($self) = @_; + + my @development_packages; + + for my $installable ($self->group->get_installables) { + + push(@development_packages, $installable) + if $installable->name =~ /-dev$/ + && $installable->relation('strong') + ->satisfies($self->processable->name); + } + + return \@development_packages; + } +); + +sub visit_installed_files { + my ($self, $item) = @_; + + return + unless $item->is_file; + + # shared library + return + unless @{$item->elf->{SONAME} // [] }; + + my $soname = $item->elf->{SONAME}[0]; + + my @ldconfig_folders = @{$self->data->architectures->ldconfig_folders}; + return + if none { $item->dirname eq $_ } @ldconfig_folders; + + my $installed = $self->processable->installed; + + my $versioned_name = $item->dirname . $soname; + my $versioned_item = $installed->lookup($versioned_name); + + my $unversioned_name = $versioned_name; + # libtool "-release" variant + $unversioned_name =~ s/-[\d\.]+\.so$/.so/; + # determine shlib link name (w/o version) + $unversioned_name =~ s/\.so.+$/.so/; + + $self->pointed_hint('lacks-versioned-link-to-shared-library', + $item->pointer, $versioned_name) + unless defined $versioned_item; + + $self->pointed_hint( + 'ldconfig-symlink-referencing-wrong-file', + $versioned_item->pointer,'should point to', + $versioned_item->link,'instead of',$item->basename + ) + if $versioned_name ne $item->name + && defined $versioned_item + && $versioned_item->is_symlink + && $versioned_item->link ne $item->basename; + + $self->pointed_hint( + 'ldconfig-symlink-is-not-a-symlink', + $versioned_item->pointer,'should point to', + $item->name + ) + if $versioned_name ne $item->name + && defined $versioned_item + && !$versioned_item->is_symlink; + + # shlib symlink may not exist. + # if shlib doesn't _have_ a version, then $unversioned_name and + # $item->name will be equal, and it's not a development link, + # so don't complain. + $self->pointed_hint( + 'link-to-shared-library-in-wrong-package', + $installed->lookup($unversioned_name)->pointer, + $item->name + ) + if $unversioned_name ne $item->name + && defined $installed->lookup($unversioned_name); + + # If the shared library is in /lib, we have to look for + # the dev symlink in /usr/lib + $unversioned_name = "usr/$unversioned_name" + unless $item->name =~ m{^usr/}; + + my @dev_links; + for my $dev_installable (@{$self->development_packages}) { + for my $dev_item (@{$dev_installable->installed->sorted_list}) { + + next + unless $dev_item->is_symlink; + + next + unless $dev_item->name =~ m{^ usr/lib/ }x; + + # try absolute first + my $resolved = $installed->resolve_path($dev_item->link); + + # otherwise relative + $resolved + = $installed->resolve_path($dev_item->dirname . $dev_item->link) + unless defined $resolved; + + next + unless defined $resolved; + + push(@dev_links, $dev_item) + if $resolved->name eq $item->name; + } + } + + # found -dev package; library needs a symlink + $self->pointed_hint('lacks-unversioned-link-to-shared-library', + $item->pointer, "example: $unversioned_name") + if @{$self->development_packages} + && (none { $_->name =~ m{ [.]so $}x } @dev_links); + + return; +} + +1; + +# Local Variables: +# indent-tabs-mode: nil +# cperl-indent-level: 4 +# End: +# vim: syntax=perl sw=4 sts=4 sr et diff --git a/lib/Lintian/Check/Libraries/Shared/MultiArch.pm b/lib/Lintian/Check/Libraries/Shared/MultiArch.pm new file mode 100644 index 0000000..52c1bc5 --- /dev/null +++ b/lib/Lintian/Check/Libraries/Shared/MultiArch.pm @@ -0,0 +1,79 @@ +# libraries/shared/multi-arch -- lintian check script -*- perl -*- + +# Copyright (C) 1998 Christian Schwarz +# Copyright (C) 2018-2019 Chris Lamb <lamby@debian.org> +# Copyright (C) 2021 Felix Lechner +# +# 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 https://www.gnu.org/copyleft/gpl.html, or write to the Free +# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, +# MA 02110-1301, USA. + +package Lintian::Check::Libraries::Shared::MultiArch; + +use v5.20; +use warnings; +use utf8; + +use List::SomeUtils qw(none uniq); + +use Moo; +use namespace::clean; + +with 'Lintian::Check'; + +has shared_libraries => (is => 'rw', default => sub { [] }); + +sub visit_installed_files { + my ($self, $item) = @_; + + return + unless $item->is_file; + + return + unless $item->file_type =~ m{^ [^,]* \b ELF \b }x; + + return + unless $item->file_type + =~ m{(?: shared [ ] object | pie [ ] executable )}x; + + my @ldconfig_folders = @{$self->data->architectures->ldconfig_folders}; + return + if none { $item->dirname eq $_ } @ldconfig_folders; + + push(@{$self->shared_libraries}, $item->name); + + return; +} + +sub installable { + my ($self) = @_; + + $self->hint( + 'shared-library-is-multi-arch-foreign', + (sort +uniq @{$self->shared_libraries}) + ) + if @{$self->shared_libraries} + && $self->processable->fields->value('Multi-Arch') eq 'foreign'; + + return; +} + +1; + +# Local Variables: +# indent-tabs-mode: nil +# cperl-indent-level: 4 +# End: +# vim: syntax=perl sw=4 sts=4 sr et diff --git a/lib/Lintian/Check/Libraries/Shared/Obsolete.pm b/lib/Lintian/Check/Libraries/Shared/Obsolete.pm new file mode 100644 index 0000000..699b70c --- /dev/null +++ b/lib/Lintian/Check/Libraries/Shared/Obsolete.pm @@ -0,0 +1,56 @@ +# libraries/shared/obsolete -- lintian check script -*- perl -*- + +# Copyright (C) 2020 Mo Zhou +# +# 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 https://www.gnu.org/copyleft/gpl.html, or write to the Free +# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, +# MA 02110-1301, USA. + +package Lintian::Check::Libraries::Shared::Obsolete; + +use v5.20; +use warnings; +use utf8; + +use Moo; +use namespace::clean; + +with 'Lintian::Check'; + +sub visit_installed_files { + my ($self, $item) = @_; + + return + unless $item->is_file; + + return + unless $item->file_type =~ /^[^,]*\bELF\b/; + + my @needed = @{$item->elf->{NEEDED} // []}; + my @obsolete = grep { /^libcblas\.so\.\d/ } @needed; + + $self->pointed_hint('linked-with-obsolete-library', $item->pointer, $_) + for @obsolete; + + return; +} + +1; + +# Local Variables: +# indent-tabs-mode: nil +# cperl-indent-level: 4 +# End: +# vim: syntax=perl sw=4 sts=4 sr et diff --git a/lib/Lintian/Check/Libraries/Shared/Relocation.pm b/lib/Lintian/Check/Libraries/Shared/Relocation.pm new file mode 100644 index 0000000..8c3dac9 --- /dev/null +++ b/lib/Lintian/Check/Libraries/Shared/Relocation.pm @@ -0,0 +1,58 @@ +# libraries/shared/relocation -- lintian check script -*- perl -*- + +# Copyright (C) 1998 Christian Schwarz +# Copyright (C) 2018-2019 Chris Lamb <lamby@debian.org> +# Copyright (C) 2021 Felix Lechner +# +# 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 https://www.gnu.org/copyleft/gpl.html, or write to the Free +# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, +# MA 02110-1301, USA. + +package Lintian::Check::Libraries::Shared::Relocation; + +use v5.20; +use warnings; +use utf8; + +use Moo; +use namespace::clean; + +with 'Lintian::Check'; + +sub visit_installed_files { + my ($self, $item) = @_; + + return + unless $item->is_file; + + # shared library + return + unless @{$item->elf->{SONAME} // [] }; + + # Now that we're sure this is really a shared library, report on + # non-PIC problems. + $self->pointed_hint('specific-address-in-shared-library', $item->pointer) + if $item->elf->{TEXTREL}; + + return; +} + +1; + +# Local Variables: +# indent-tabs-mode: nil +# cperl-indent-level: 4 +# End: +# vim: syntax=perl sw=4 sts=4 sr et diff --git a/lib/Lintian/Check/Libraries/Shared/Soname.pm b/lib/Lintian/Check/Libraries/Shared/Soname.pm new file mode 100644 index 0000000..9887e3b --- /dev/null +++ b/lib/Lintian/Check/Libraries/Shared/Soname.pm @@ -0,0 +1,123 @@ +# libraries/shared/soname -- lintian check script -*- perl -*- + +# Copyright (C) 1998 Christian Schwarz and Richard Braakman +# Copyright (C) 2012 Kees Cook +# Copyright (C) 2017-2020 Chris Lamb <lamby@debian.org> +# Copyright (C) 2021 Felix Lechner +# +# 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 https://www.gnu.org/copyleft/gpl.html, or write to the Free +# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, +# MA 02110-1301, USA. + +package Lintian::Check::Libraries::Shared::Soname; + +use v5.20; +use warnings; +use utf8; + +use Const::Fast; +use List::SomeUtils qw(any none uniq); + +use Moo; +use namespace::clean; + +with 'Lintian::Check'; + +const my $SPACE => q{ }; +const my $SLASH => q{/}; + +has DEB_HOST_MULTIARCH => ( + is => 'rw', + lazy => 1, + default => sub { + my ($self) = @_; + + return $self->data->architectures->deb_host_multiarch; + } +); + +sub installable { + my ($self) = @_; + + return + if $self->processable->type eq 'udeb'; + + my $architecture = $self->processable->fields->value('Architecture'); + my $multiarch_component = $self->DEB_HOST_MULTIARCH->{$architecture}; + + my @common_folders = qw{lib usr/lib}; + push(@common_folders, map { "$_/$multiarch_component" } @common_folders) + if length $multiarch_component; + + my @duplicated; + for my $item (@{$self->processable->installed->sorted_list}) { + + # For the package naming check, filter out SONAMEs where all the + # files are at paths other than /lib, /usr/lib and /usr/lib/<MA-DIR>. + # This avoids false positives with plugins like Apache modules, + # which may have their own SONAMEs but which don't matter for the + # purposes of this check. + next + if none { $item->dirname eq $_ . $SLASH } @common_folders; + + # Also filter out nsswitch modules + next + if $item->basename =~ m{^ libnss_[^.]+\.so(?:\.\d+) $}x; + + push(@duplicated, @{$item->elf->{SONAME} // []}); + } + + my @sonames = uniq @duplicated; + + # try to strip transition strings + my $shortened_name = $self->processable->name; + $shortened_name =~ s/c102\b//; + $shortened_name =~ s/c2a?\b//; + $shortened_name =~ s/\dg$//; + $shortened_name =~ s/gf$//; + $shortened_name =~ s/v[5-6]$//; # GCC-5 / libstdc++6 C11 ABI breakage + $shortened_name =~ s/-udeb$//; + $shortened_name =~ s/^lib64/lib/; + + my $match_found = 0; + for my $soname (@sonames) { + + $soname =~ s/ ([0-9]) [.]so[.] /$1-/x; + $soname =~ s/ [.]so (?:[.]|\z) //x; + $soname =~ s/_/-/g; + + my $lowercase = lc $soname; + + $match_found = any { $lowercase eq $_ } + ($self->processable->name, $shortened_name); + + last + if $match_found; + } + + $self->hint('package-name-doesnt-match-sonames', + join($SPACE, sort @sonames)) + if @sonames && !$match_found; + + return; +} + +1; + +# Local Variables: +# indent-tabs-mode: nil +# cperl-indent-level: 4 +# End: +# vim: syntax=perl sw=4 sts=4 sr et diff --git a/lib/Lintian/Check/Libraries/Shared/Soname/Missing.pm b/lib/Lintian/Check/Libraries/Shared/Soname/Missing.pm new file mode 100644 index 0000000..a01a878 --- /dev/null +++ b/lib/Lintian/Check/Libraries/Shared/Soname/Missing.pm @@ -0,0 +1,73 @@ +# libraries/shared/soname/missing -- lintian check script -*- perl -*- + +# Copyright (C) 1998 Christian Schwarz +# Copyright (C) 2018-2019 Chris Lamb <lamby@debian.org> +# Copyright (C) 2021 Felix Lechner +# +# 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 https://www.gnu.org/copyleft/gpl.html, or write to the Free +# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, +# MA 02110-1301, USA. + +package Lintian::Check::Libraries::Shared::Soname::Missing; + +use v5.20; +use warnings; +use utf8; + +use List::SomeUtils qw(none); + +use Moo; +use namespace::clean; + +with 'Lintian::Check'; + +sub visit_installed_files { + my ($self, $item) = @_; + + return + unless $item->is_file; + + return + unless $item->file_type =~ m{^ [^,]* \b ELF \b }x; + + return + unless $item->file_type + =~ m{(?: shared [ ] object | pie [ ] executable )}x; + + # does not have SONAME + return + if @{$item->elf->{SONAME} // [] }; + + my @ldconfig_folders = @{$self->data->architectures->ldconfig_folders}; + return + if none { $item->dirname eq $_ } @ldconfig_folders; + + # disregard executables + $self->pointed_hint('sharedobject-in-library-directory-missing-soname', + $item->pointer) + if !$item->is_executable + || !defined $item->elf->{DEBUG} + || $item->name =~ / [.]so (?: [.] | $ ) /msx; + + return; +} + +1; + +# Local Variables: +# indent-tabs-mode: nil +# cperl-indent-level: 4 +# End: +# vim: syntax=perl sw=4 sts=4 sr et diff --git a/lib/Lintian/Check/Libraries/Shared/Stack.pm b/lib/Lintian/Check/Libraries/Shared/Stack.pm new file mode 100644 index 0000000..f3e1d03 --- /dev/null +++ b/lib/Lintian/Check/Libraries/Shared/Stack.pm @@ -0,0 +1,69 @@ +# libraries/shared/stack -- lintian check script -*- perl -*- + +# Copyright (C) 1998 Christian Schwarz +# Copyright (C) 2018-2019 Chris Lamb <lamby@debian.org> +# Copyright (C) 2021 Felix Lechner +# +# 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 https://www.gnu.org/copyleft/gpl.html, or write to the Free +# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, +# MA 02110-1301, USA. + +package Lintian::Check::Libraries::Shared::Stack; + +use v5.20; +use warnings; +use utf8; + +use Moo; +use namespace::clean; + +with 'Lintian::Check'; + +sub visit_installed_files { + my ($self, $item) = @_; + + return + unless $item->is_file; + + # shared library + return + unless @{$item->elf->{SONAME} // [] }; + + $self->pointed_hint('shared-library-lacks-stack-section',$item->pointer) + if $self->processable->fields->declares('Architecture') + && !exists $item->elf->{PH}{STACK}; + + $self->pointed_hint('executable-stack-in-shared-library', $item->pointer) + if exists $item->elf->{PH}{STACK} + && $item->elf->{PH}{STACK}{flags} ne 'rw-' + # Once the following line is removed again, please also remove + # the Test-Architectures line in + # t/recipes/checks/libraries/shared/stack/shared-libs-exec-stack/eval/desc + # and the MIPS-related notes in + # tags/e/executable-stack-in-shared-library.tag. See + # https://bugs.debian.org/1025436 and + # https://bugs.debian.org/1022787 for details + && $self->processable->fields->value('Architecture') !~ /mips/; + + return; +} + +1; + +# Local Variables: +# indent-tabs-mode: nil +# cperl-indent-level: 4 +# End: +# vim: syntax=perl sw=4 sts=4 sr et diff --git a/lib/Lintian/Check/Libraries/Shared/Trigger/Ldconfig.pm b/lib/Lintian/Check/Libraries/Shared/Trigger/Ldconfig.pm new file mode 100644 index 0000000..66f5961 --- /dev/null +++ b/lib/Lintian/Check/Libraries/Shared/Trigger/Ldconfig.pm @@ -0,0 +1,131 @@ +# libraries/shared/trigger/ldconfig -- lintian check script -*- perl -*- + +# Copyright (C) 1998 Christian Schwarz +# Copyright (C) 2018-2019 Chris Lamb <lamby@debian.org> +# Copyright (C) 2021 Felix Lechner +# +# 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 https://www.gnu.org/copyleft/gpl.html, or write to the Free +# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, +# MA 02110-1301, USA. + +package Lintian::Check::Libraries::Shared::Trigger::Ldconfig; + +use v5.20; +use warnings; +use utf8; + +use List::SomeUtils qw(any uniq); + +use Moo; +use namespace::clean; + +with 'Lintian::Check'; + +has soname_by_filename => ( + is => 'rw', + lazy => 1, + default => sub { + my ($self) = @_; + + my %soname_by_filename; + for my $item (@{$self->processable->installed->sorted_list}) { + + $soname_by_filename{$item->name}= $item->elf->{SONAME}[0] + if exists $item->elf->{SONAME}; + } + + return \%soname_by_filename; + } +); + +has must_call_ldconfig => (is => 'rw', default => sub { [] }); + +sub visit_installed_files { + my ($self, $item) = @_; + + my $resolved_name = $item->name; + $resolved_name = $item->link_normalized + if length $item->link; + + # Installed in a directory controlled by the dynamic + # linker? We have to strip off directories named for + # hardware capabilities. + # yes! so postinst must call ldconfig + push(@{$self->must_call_ldconfig}, $resolved_name) + if exists $self->soname_by_filename->{$resolved_name} + && $self->needs_ldconfig($item); + + return; +} + +sub installable { + my ($self) = @_; + + # determine if the package had an ldconfig trigger + my $triggers = $self->processable->control->resolve_path('triggers'); + + my $we_trigger_ldconfig = 0; + $we_trigger_ldconfig = 1 + if defined $triggers + && $triggers->decoded_utf8 + =~ /^ \s* activate-noawait \s+ ldconfig \s* $/mx; + + $self->hint('package-has-unnecessary-activation-of-ldconfig-trigger') + if !@{$self->must_call_ldconfig} + && $we_trigger_ldconfig + && $self->processable->type ne 'udeb'; + + $self->hint('lacks-ldconfig-trigger', + (sort +uniq @{$self->must_call_ldconfig})) + if @{$self->must_call_ldconfig} + && !$we_trigger_ldconfig + && $self->processable->type ne 'udeb'; + + return; +} + +sub needs_ldconfig { + my ($self, $item) = @_; + + # Libraries that should only be used in the presence of certain capabilities + # may be located in subdirectories of the standard ldconfig search path with + # one of the following names. + my $HWCAP_DIRS = $self->data->load('shared-libs/hwcap-dirs'); + my @ldconfig_folders = @{$self->data->architectures->ldconfig_folders}; + + my $dirname = $item->dirname; + my $encapsulator; + do { + $dirname =~ s{ ([^/]+) / $}{}x; + $encapsulator = $1; + + } while ($encapsulator && $HWCAP_DIRS->recognizes($encapsulator)); + + $dirname .= "$encapsulator/" if $encapsulator; + + # yes! so postinst must call ldconfig + return 1 + if any { $dirname eq $_ } @ldconfig_folders; + + return 0; +} + +1; + +# Local Variables: +# indent-tabs-mode: nil +# cperl-indent-level: 4 +# End: +# vim: syntax=perl sw=4 sts=4 sr et |