cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

headers_check.pl (3819B)


      1#!/usr/bin/env perl
      2# SPDX-License-Identifier: GPL-2.0
      3#
      4# headers_check.pl execute a number of trivial consistency checks
      5#
      6# Usage: headers_check.pl dir arch [files...]
      7# dir:   dir to look for included files
      8# arch:  architecture
      9# files: list of files to check
     10#
     11# The script reads the supplied files line by line and:
     12#
     13# 1) for each include statement it checks if the
     14#    included file actually exists.
     15#    Only include files located in asm* and linux* are checked.
     16#    The rest are assumed to be system include files.
     17#
     18# 2) It is checked that prototypes does not use "extern"
     19#
     20# 3) Check for leaked CONFIG_ symbols
     21
     22use warnings;
     23use strict;
     24use File::Basename;
     25
     26my ($dir, $arch, @files) = @ARGV;
     27
     28my $ret = 0;
     29my $line;
     30my $lineno = 0;
     31my $filename;
     32
     33foreach my $file (@files) {
     34	$filename = $file;
     35
     36	open(my $fh, '<', $filename)
     37		or die "$filename: $!\n";
     38	$lineno = 0;
     39	while ($line = <$fh>) {
     40		$lineno++;
     41		&check_include();
     42		&check_asm_types();
     43		&check_sizetypes();
     44		&check_declarations();
     45		# Dropped for now. Too much noise &check_config();
     46	}
     47	close $fh;
     48}
     49exit $ret;
     50
     51sub check_include
     52{
     53	if ($line =~ m/^\s*#\s*include\s+<((asm|linux).*)>/) {
     54		my $inc = $1;
     55		my $found;
     56		$found = stat($dir . "/" . $inc);
     57		if (!$found) {
     58			$inc =~ s#asm/#asm-$arch/#;
     59			$found = stat($dir . "/" . $inc);
     60		}
     61		if (!$found) {
     62			printf STDERR "$filename:$lineno: included file '$inc' is not exported\n";
     63			$ret = 1;
     64		}
     65	}
     66}
     67
     68sub check_declarations
     69{
     70	# soundcard.h is what it is
     71	if ($line =~ m/^void seqbuf_dump\(void\);/) {
     72		return;
     73	}
     74	# drm headers are being C++ friendly
     75	if ($line =~ m/^extern "C"/) {
     76		return;
     77	}
     78	if ($line =~ m/^(\s*extern|unsigned|char|short|int|long|void)\b/) {
     79		printf STDERR "$filename:$lineno: " .
     80			      "userspace cannot reference function or " .
     81			      "variable defined in the kernel\n";
     82	}
     83}
     84
     85sub check_config
     86{
     87	if ($line =~ m/[^a-zA-Z0-9_]+CONFIG_([a-zA-Z0-9_]+)[^a-zA-Z0-9_]/) {
     88		printf STDERR "$filename:$lineno: leaks CONFIG_$1 to userspace where it is not valid\n";
     89	}
     90}
     91
     92my $linux_asm_types;
     93sub check_asm_types
     94{
     95	if ($filename =~ /types.h|int-l64.h|int-ll64.h/o) {
     96		return;
     97	}
     98	if ($lineno == 1) {
     99		$linux_asm_types = 0;
    100	} elsif ($linux_asm_types >= 1) {
    101		return;
    102	}
    103	if ($line =~ m/^\s*#\s*include\s+<asm\/types.h>/) {
    104		$linux_asm_types = 1;
    105		printf STDERR "$filename:$lineno: " .
    106		"include of <linux/types.h> is preferred over <asm/types.h>\n"
    107		# Warn until headers are all fixed
    108		#$ret = 1;
    109	}
    110}
    111
    112my $linux_types;
    113my %import_stack = ();
    114sub check_include_typesh
    115{
    116	my $path = $_[0];
    117	my $import_path;
    118
    119	my $fh;
    120	my @file_paths = ($path, $dir . "/" .  $path, dirname($filename) . "/" . $path);
    121	for my $possible ( @file_paths ) {
    122	    if (not $import_stack{$possible} and open($fh, '<', $possible)) {
    123		$import_path = $possible;
    124		$import_stack{$import_path} = 1;
    125		last;
    126	    }
    127	}
    128	if (eof $fh) {
    129	    return;
    130	}
    131
    132	my $line;
    133	while ($line = <$fh>) {
    134		if ($line =~ m/^\s*#\s*include\s+<linux\/types.h>/) {
    135			$linux_types = 1;
    136			last;
    137		}
    138		if (my $included = ($line =~ /^\s*#\s*include\s+[<"](\S+)[>"]/)[0]) {
    139			check_include_typesh($included);
    140		}
    141	}
    142	close $fh;
    143	delete $import_stack{$import_path};
    144}
    145
    146sub check_sizetypes
    147{
    148	if ($filename =~ /types.h|int-l64.h|int-ll64.h/o) {
    149		return;
    150	}
    151	if ($lineno == 1) {
    152		$linux_types = 0;
    153	} elsif ($linux_types >= 1) {
    154		return;
    155	}
    156	if ($line =~ m/^\s*#\s*include\s+<linux\/types.h>/) {
    157		$linux_types = 1;
    158		return;
    159	}
    160	if (my $included = ($line =~ /^\s*#\s*include\s+[<"](\S+)[>"]/)[0]) {
    161		check_include_typesh($included);
    162	}
    163	if ($line =~ m/__[us](8|16|32|64)\b/) {
    164		printf STDERR "$filename:$lineno: " .
    165		              "found __[us]{8,16,32,64} type " .
    166		              "without #include <linux/types.h>\n";
    167		$linux_types = 2;
    168		# Warn until headers are all fixed
    169		#$ret = 1;
    170	}
    171}