lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Message-ID: <152261526940.30503.3933152630838784113.stgit@warthog.procyon.org.uk> Date: Sun, 01 Apr 2018 21:41:09 +0100 From: David Howells <dhowells@...hat.com> To: linux-kernel@...r.kernel.org Subject: [PATCH 09/45] C++: x86: Fix the x86 syscall table production for C++ Fix the x86 syscall table production for C++ to not miss out any slots in the syscall table as this would otherwise cause errors from the compiler. Signed-off-by: David Howells <dhowells@...hat.com> --- arch/x86/entry/syscalls/Makefile | 8 +-- arch/x86/entry/syscalls/syscallhdr.pl | 73 +++++++++++++++++++++++++ arch/x86/entry/syscalls/syscalltbl.pl | 95 +++++++++++++++++++++++++++++++++ arch/x86/kernel/asm-offsets_32.c | 1 arch/x86/kernel/asm-offsets_64.c | 1 5 files changed, 174 insertions(+), 4 deletions(-) create mode 100644 arch/x86/entry/syscalls/syscallhdr.pl create mode 100644 arch/x86/entry/syscalls/syscalltbl.pl diff --git a/arch/x86/entry/syscalls/Makefile b/arch/x86/entry/syscalls/Makefile index 6fb9b57ed5ba..18d87b98e3e3 100644 --- a/arch/x86/entry/syscalls/Makefile +++ b/arch/x86/entry/syscalls/Makefile @@ -9,16 +9,16 @@ _dummy := $(shell [ -d '$(out)' ] || mkdir -p '$(out)') \ syscall32 := $(srctree)/$(src)/syscall_32.tbl syscall64 := $(srctree)/$(src)/syscall_64.tbl -syshdr := $(srctree)/$(src)/syscallhdr.sh -systbl := $(srctree)/$(src)/syscalltbl.sh +syshdr := $(srctree)/$(src)/syscallhdr.pl +systbl := $(srctree)/$(src)/syscalltbl.pl quiet_cmd_syshdr = SYSHDR $@ - cmd_syshdr = $(CONFIG_SHELL) '$(syshdr)' '$<' '$@' \ + cmd_syshdr = perl '$(syshdr)' '$<' '$@' \ '$(syshdr_abi_$(basetarget))' \ '$(syshdr_pfx_$(basetarget))' \ '$(syshdr_offset_$(basetarget))' quiet_cmd_systbl = SYSTBL $@ - cmd_systbl = $(CONFIG_SHELL) '$(systbl)' $< $@ + cmd_systbl = perl '$(systbl)' $< $@ quiet_cmd_hypercalls = HYPERCALLS $@ cmd_hypercalls = $(CONFIG_SHELL) '$<' $@ $(filter-out $<,$^) diff --git a/arch/x86/entry/syscalls/syscallhdr.pl b/arch/x86/entry/syscalls/syscallhdr.pl new file mode 100644 index 000000000000..2e16a1c9c48a --- /dev/null +++ b/arch/x86/entry/syscalls/syscallhdr.pl @@ -0,0 +1,73 @@ +#!/usr/bin/perl -w +# SPDX-License-Identifier: GPL-2.0 +use strict; + +my ($in, $out, $abi_list, $prefix, $offset) = @ARGV; + +$offset = "" + if ($#ARGV < 4); + +# +# Parse the table file +# +my %syscalls = (); +my $highest_nr = 0; +open TBL, "<$in" || die $in; +while (my $line = <TBL>) { + if ($line =~ m/^[0-9A-Fa-fXx]+[[:space:]]/) { + my @bits = split(" ", $line); + my $nr = int($bits[0]); + $syscalls{$nr} = { + nr => $nr, + abi => $bits[1], + name => $bits[2], + sys => $bits[3], + sys32 => $bits[4], + }; + $highest_nr = $nr + if ($nr > $highest_nr); + } +} +close TBL || die $in; + +# +# Determine which ABIs we are interested in +# +my %my_abis = (); +foreach (split(",", $abi_list)) { + $my_abis{$_} = 1; +} + +# +# Generate the output +# +my $fileguard = $out; +$fileguard =~ s!.*/!!; +$fileguard = "_ASM_X86_" . $fileguard; +$fileguard =~ y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/; +$fileguard =~ s/[^A-Z0-9_]/_/g; +$fileguard =~ s/__/_/g; + +open OUT, ">$out" || die $out; +print OUT "#ifndef ${fileguard}\n"; +print OUT "#define ${fileguard} 1\n"; +print OUT "\n"; + +for (my $i = 0; $i <= $highest_nr; $i++) { + next unless exists($syscalls{$i}); + + my $c = $syscalls{$i}; + next unless exists($my_abis{$c->{abi}}); + + if ($offset eq "") { + print OUT "#define __NR_" . $prefix . $c->{name} . " " . $c->{nr} . "\n"; + } else { + print OUT "#define __NR_" . $prefix . $c->{name} . " (" . $offset . "+" . $c->{nr} . ")\n"; + } +} + +print OUT "\n"; +print OUT "#endif /* ${fileguard} */\n"; +close OUT || die $out; + +exit 0; diff --git a/arch/x86/entry/syscalls/syscalltbl.pl b/arch/x86/entry/syscalls/syscalltbl.pl new file mode 100644 index 000000000000..71664f3aa78d --- /dev/null +++ b/arch/x86/entry/syscalls/syscalltbl.pl @@ -0,0 +1,95 @@ +#!/usr/bin/perl -w +# SPDX-License-Identifier: GPL-2.0 +use strict; + +my ($in, $out) = @ARGV; + +# +# Parse the table file +# +my %syscalls = (); +my $highest_nr = 0; +open TBL, "<$in" || die $in; +while (my $line = <TBL>) { + if ($line =~ m/^[0-9A-Fa-fXx]+[[:space:]]/) { + my @bits = split(" ", $line); + push @bits, "" if ($#bits == 2); + push @bits, "" if ($#bits == 3); + my $nr = int($bits[0]); + $syscalls{$nr} = { + nr => $nr, + abi => $bits[1], + name => $bits[2], + entry => $bits[3], + compat => $bits[4], + }; + $highest_nr = $nr + if ($nr > $highest_nr); + } +} +close TBL || die $in; + +# +# Generate the output +# +sub syscall_macro($$$) { + my ($abi, $nr, $entry) = @_; + + # Entry can be either just a function name or "function/qualifier" + my @pieces = split("/", $entry); + my ($func, $qualifier) = @pieces; + $qualifier = "" unless ($#pieces == 1); + + return "__SYSCALL_" . $abi . "(" . $nr . ", " . $func . ", " . $qualifier . ")"; +} + +sub emit($$$$) { + my ($abi, $nr, $entry, $compat) = @_; + + die "a compat entry for a 64-bit syscall makes no sense" + if ($abi eq "64" && $compat); + + if ($compat eq "") { + if ($entry) { + print OUT syscall_macro($abi, $nr, $entry), "\n" + } else { + print OUT "__NO_SYSCALL_(" . $nr . ")\n"; + } + } else { + print OUT "#ifdef CONFIG_X86_32\n"; + print OUT syscall_macro($abi, $nr, $entry), "\n" + if ($entry); + print OUT "#else\n"; + print OUT syscall_macro($abi, $nr, $compat), "\n"; + print OUT "#endif\n"; + } +} + +open OUT, ">$out" || die $out; +for (my $i = 0; $i <= $highest_nr; $i++) { + if (!exists($syscalls{$i})) { + print OUT "__NO_SYSCALL_(" . $i . ")\n"; + next; + } + + my $c = $syscalls{$i}; + my $abi = uc($c->{abi}); + if ($abi eq "COMMON" || $abi eq "64") { + # COMMON is the same as 64, except that we don't expect X32 + # programs to use it. Our expectation has nothing to do with + # any generated code, so treat them the same. + emit(64, $c->{nr}, $c->{entry}, $c->{compat}); + } elsif ($abi eq "X32") { + # X32 is equivalent to 64 on an X32-compatible kernel. + print OUT "#ifdef CONFIG_X86_X32_ABI\n"; + emit(64, $c->{nr}, $c->{entry}, $c->{compat}); + print OUT "#endif\n"; + } elsif ($abi eq "I386") { + emit($abi, $c->{nr}, $c->{entry}, $c->{compat}); + } else { + die "Unknown abi $abi"; + } +} +close OUT || die $out; + +exit 0; diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c index f91ba53e06c8..d83af227d373 100644 --- a/arch/x86/kernel/asm-offsets_32.c +++ b/arch/x86/kernel/asm-offsets_32.c @@ -6,6 +6,7 @@ #include <asm/ucontext.h> #define __SYSCALL_I386(nr, sym, qual) [nr] = 1, +#define __NO_SYSCALL(nr, sym, qual) [nr] = 0, static char syscalls[] = { #include <asm/syscalls_32.h> }; diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c index bf51e51d808d..8f507236fec5 100644 --- a/arch/x86/kernel/asm-offsets_64.c +++ b/arch/x86/kernel/asm-offsets_64.c @@ -5,6 +5,7 @@ #include <asm/ia32.h> +#define __NO_SYSCALL_(nr) [nr] = 0, #define __SYSCALL_64(nr, sym, qual) [nr] = 1, static char syscalls_64[] = { #include <asm/syscalls_64.h>
Powered by blists - more mailing lists