fbrosson | 533407a | 2018-04-04 21:44:29 +0000 | [diff] [blame] | 1 | #!/usr/bin/env perl |
Manuel Pégourié-Gonnard | fd60a5c | 2014-11-12 22:54:24 +0100 | [diff] [blame] | 2 | |
| 3 | # Find functions making recursive calls to themselves. |
| 4 | # (Multiple recursion where a() calls b() which calls a() not covered.) |
| 5 | # |
| 6 | # When the recursion depth might depend on data controlled by the attacker in |
| 7 | # an unbounded way, those functions should use interation instead. |
| 8 | # |
| 9 | # Typical usage: scripts/recursion.pl library/*.c |
| 10 | |
| 11 | use warnings; |
| 12 | use strict; |
| 13 | |
| 14 | use utf8; |
| 15 | use open qw(:std utf8); |
| 16 | |
| 17 | # exclude functions that are ok: |
Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 18 | # - mpi_write_hlp: bounded by size of mbedtls_mpi, a compile-time constant |
Jaeden Amero | e23737c | 2019-02-27 17:11:22 +0000 | [diff] [blame] | 19 | my $known_ok = qr/mpi_write_hlp/; |
Manuel Pégourié-Gonnard | fd60a5c | 2014-11-12 22:54:24 +0100 | [diff] [blame] | 20 | |
| 21 | my $cur_name; |
| 22 | my $inside; |
| 23 | my @funcs; |
| 24 | |
| 25 | die "Usage: $0 file.c [...]\n" unless @ARGV; |
| 26 | |
| 27 | while (<>) |
| 28 | { |
| 29 | if( /^[^\/#{}\s]/ && ! /\[.*]/ ) { |
| 30 | chomp( $cur_name = $_ ) unless $inside; |
| 31 | } elsif( /^{/ && $cur_name ) { |
| 32 | $inside = 1; |
| 33 | $cur_name =~ s/.* ([^ ]*)\(.*/$1/; |
| 34 | } elsif( /^}/ && $inside ) { |
| 35 | undef $inside; |
| 36 | undef $cur_name; |
| 37 | } elsif( $inside && /\b\Q$cur_name\E\([^)]/ ) { |
| 38 | push @funcs, $cur_name unless /$known_ok/; |
| 39 | } |
| 40 | } |
| 41 | |
| 42 | print "$_\n" for @funcs; |
| 43 | exit @funcs; |