提交 e863d920 编写于 作者: M Matt Caswell

Don't export internal symbols

On Linux when creating the .so file we were exporting all symbols. We should
only be exporting public symbols. This commit fixes the issue. It is only
applicable to linux currently although the same technique may work for other
platforms (e.g. Solaris should work the same way).

This also adds symbol version information to our exported symbols.
Reviewed-by: NRichard Levitte <levitte@openssl.org>
上级 ea09088e
......@@ -82,6 +82,8 @@ tags
TAGS
cscope.out
*.d
crypto.map
ssl.map
# Windows
/tmp32
......
......@@ -170,6 +170,17 @@ link_a.gnu:
link_app.gnu:
@ $(DO_GNU_APP); $(LINK_APP)
link_a.linux-shared:
@if [ $(LIBNAME) != "crypto" -a $(LIBNAME) != "ssl" ]; then echo libname is $(LIBNAME); sleep 2; $(DO_GNU_SO); else \
$(PERL) util/mkdef.pl $(LIBNAME) linux >$(LIBNAME).map; \
$(CALC_VERSIONS); \
SHLIB=lib$(LIBNAME).so; \
SHLIB_SUFFIX=; \
ALLSYMSFLAGS='-Wl,--whole-archive,--version-script=$(LIBNAME).map'; \
NOALLSYMSFLAGS='-Wl,--no-whole-archive'; \
SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared -Wl,-Bsymbolic -Wl,-soname=$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX"; \
fi; $(LINK_SO_A)
link_o.bsd:
@if $(DETECT_GNU_LD); then $(DO_GNU_SO); else \
$(CALC_VERSIONS); \
......@@ -566,7 +577,7 @@ symlink.cygwin symlink.alpha-osf1 symlink.tru64 symlink.tru64-rpath:
# Compatibility targets
link_o.bsd-gcc-shared link_o.linux-shared link_o.gnu-shared: link_o.gnu
link_a.bsd-gcc-shared link_a.linux-shared link_a.gnu-shared: link_a.gnu
link_a.bsd-gcc-shared link_a.gnu-shared: link_a.gnu
link_app.bsd-gcc-shared link_app.linux-shared link_app.gnu-shared: link_app.gnu
symlink.bsd-gcc-shared symlink.bsd-shared symlink.linux-shared symlink.gnu-shared: symlink.gnu
link_o.bsd-shared: link_o.bsd
......
......@@ -292,7 +292,7 @@ int main(int argc, char *argv[])
goto err;
(void)BIO_flush(out);
#ifdef OPENSSL_SYS_WIN32
#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_LINUX)
message(out, "Probable prime generation with coprimes disabled");
#else
message(out, "Probable prime generation with coprimes");
......@@ -1859,7 +1859,8 @@ int test_small_prime(BIO *bp, BN_CTX *ctx)
return ret;
}
#ifndef OPENSSL_SYS_WIN32
/* We can't test this on platforms where local symbols aren't exported */
#if !defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_SYS_LINUX)
int test_probable_prime_coprime(BIO *bp, BN_CTX *ctx)
{
int i, j, ret = 0;
......
......@@ -75,17 +75,17 @@ sub testordinals
while (my $line = <$fh>) {
my @tokens = split(/(?:\s+|\s*:\s*)/, $line);
#Check the line looks sane
if ($#tokens < 4 || $#tokens > 5) {
if ($#tokens < 5 || $#tokens > 6) {
print STDERR "Invalid line:\n$line\n";
$ret = 0;
last;
}
if ($tokens[2] eq "NOEXIST") {
if ($tokens[3] eq "NOEXIST") {
#Ignore this line
next;
}
#Some ordinals can be repeated, e.g. if one is VMS and another is !VMS
$newqual = $tokens[3];
$newqual = $tokens[4];
$newqual =~ s/!//g;
if ($cnt > $tokens[1]
|| ($cnt == $tokens[1] && ($qualifier ne $newqual
......
此差异已折叠。
......@@ -8,10 +8,11 @@
# Intermediary files are created, call libeay.num and ssleay.num,
# The format of these files is:
#
# routine-name nnnn info
# routine-name nnnn vers info
#
# and the "info" part is actually a colon-separated string of fields with
# the following meaning:
# The "nnnn" and "vers" fields are the numeric id and version for the symbol
# respectively. The "info" part is actually a colon-separated string of fields
# with the following meaning:
#
# existence:platform:kind:algorithms
#
......@@ -57,6 +58,7 @@ my $VMS=0;
my $W32=0;
my $NT=0;
my $OS2=0;
my $linux=0;
# Set this to make typesafe STACK definitions appear in DEF
my $safe_stack_def = 0;
......@@ -157,6 +159,9 @@ foreach (@ARGV, split(/ /, $options))
$VMS=1;
$VMSNonVAX=1;
}
if ($_ eq "linux") {
$linux=1;
}
$VMS=1 if $_ eq "VMS";
$OS2=1 if $_ eq "OS2";
$fips=1 if /^fips/;
......@@ -248,7 +253,7 @@ if (!$libname) {
}
# If no platform is given, assume WIN32
if ($W32 + $VMS + $OS2 == 0) {
if ($W32 + $VMS + $OS2 + $linux == 0) {
$W32 = 1;
}
......@@ -1299,25 +1304,28 @@ sub print_def_file
my $version = get_version();
my $what = "OpenSSL: implementation of Secure Socket Layer";
my $description = "$what $version, $name - http://$http_vendor";
my $prevsymversion = "", $prevprevsymversion = "";
if ($W32)
{ $libname.="32"; }
elsif ($OS2)
{ # DLL names should not clash on the whole system.
# However, they should not have any particular relationship
# to the name of the static library. Chose descriptive names
# (must be at most 8 chars).
my %translate = (ssl => 'open_ssl', crypto => 'cryptssl');
$libname = $translate{$name} || $name;
$liboptions = <<EOO;
if (!$linux)
{
if ($W32)
{ $libname.="32"; }
elsif ($OS2)
{ # DLL names should not clash on the whole system.
# However, they should not have any particular relationship
# to the name of the static library. Chose descriptive names
# (must be at most 8 chars).
my %translate = (ssl => 'open_ssl', crypto => 'cryptssl');
$libname = $translate{$name} || $name;
$liboptions = <<EOO;
INITINSTANCE
DATA MULTIPLE NONSHARED
EOO
# Vendor field can't contain colon, drat; so we omit http://
$description = "\@#$http_vendor:$version#\@$what; DLL for library $name. Build for EMX -Zmtd";
}
# Vendor field can't contain colon, drat; so we omit http://
$description = "\@#$http_vendor:$version#\@$what; DLL for library $name. Build for EMX -Zmtd";
}
print OUT <<"EOF";
print OUT <<"EOF";
;
; Definition file for the DLL version of the $name library from OpenSSL
;
......@@ -1326,39 +1334,74 @@ LIBRARY $libname $liboptions
EOF
print "EXPORTS\n";
print "EXPORTS\n";
}
(@e)=grep(/^SSLeay(\{[0-9]+\})?\\.*?:.*?:FUNCTION/,@symbols);
(@r)=grep(/^\w+(\{[0-9]+\})?\\.*?:.*?:FUNCTION/ && !/^SSLeay(\{[0-9]+\})?\\.*?:.*?:FUNCTION/,@symbols);
(@r)=grep(/^\w+(\{[0-9]+\})?\\.*?:.*?:FUNCTION/,@symbols);
(@v)=grep(/^\w+(\{[0-9]+\})?\\.*?:.*?:VARIABLE/,@symbols);
@symbols=((sort @e),(sort @r), (sort @v));
foreach $sym (@symbols) {
(my $s, my $i) = $sym =~ /^(.*?)\\(.*)$/;
my $v = 0;
$v = 1 if $i =~ /^.*?:.*?:VARIABLE/;
if (!defined($nums{$s})) {
printf STDERR "Warning: $s does not have a number assigned\n"
if(!$do_update);
my ($baseversion, $currversion) = get_openssl_version();
my $thisversion;
do {
if (!defined($thisversion)) {
$thisversion = $baseversion;
} else {
(my $n, my $dummy) = split /\\/, $nums{$s};
my %pf = ();
my $p = ($i =~ /^[^:]*:([^:]*):/,$1);
my $a = ($i =~ /^[^:]*:[^:]*:[^:]*:([^:]*)/,$1);
if (is_valid($p,1) && is_valid($a,0)) {
my $s2 = ($s =~ /^(.*?)(\{[0-9]+\})?$/, $1);
if ($prev eq $s2) {
print STDERR "Warning: Symbol '",$s2,"' redefined. old=",($nums{$prev} =~ /^(.*?)\\/,$1),", new=",($nums{$s2} =~ /^(.*?)\\/,$1),"\n";
}
$prev = $s2; # To warn about duplicates...
if($v && !$OS2) {
printf OUT " %s%-39s @%-8d DATA\n",($W32)?"":"_",$s2,$n;
} else {
printf OUT " %s%-39s @%d\n",($W32||$OS2)?"":"_",$s2,$n;
$thisversion = get_next_version($thisversion);
}
foreach $sym (@symbols) {
(my $s, my $i) = $sym =~ /^(.*?)\\(.*)$/;
my $v = 0;
$v = 1 if $i =~ /^.*?:.*?:VARIABLE/;
if (!defined($nums{$s})) {
die "Error: $s does not have a number assigned\n"
if(!$do_update);
} else {
(my $n, my $symversion, my $dummy) = split /\\/, $nums{$s};
next if $symversion ne $thisversion;
my %pf = ();
my $p = ($i =~ /^[^:]*:([^:]*):/,$1);
my $a = ($i =~ /^[^:]*:[^:]*:[^:]*:([^:]*)/,$1);
if (is_valid($p,1) && is_valid($a,0)) {
my $s2 = ($s =~ /^(.*?)(\{[0-9]+\})?$/, $1);
if ($prev eq $s2) {
print STDERR "Warning: Symbol '",$s2,
"' redefined. old=",($nums{$prev} =~ /^(.*?)\\/,$1),
", new=",($nums{$s2} =~ /^(.*?)\\/,$1),"\n";
}
$prev = $s2; # To warn about duplicates...
if($linux) {
if ($symversion ne $prevsymversion) {
if ($prevsymversion ne "") {
if ($prevprevsymversion ne "") {
print OUT "} OPENSSL_"
."$prevprevsymversion;\n\n";
} else {
print OUT "};\n\n";
}
}
print OUT "OPENSSL_$symversion {\n global:\n";
$prevprevsymversion = $prevsymversion;
$prevsymversion = $symversion;
}
print OUT " $s2;\n";
} elsif($v && !$OS2) {
printf OUT " %s%-39s @%-8d DATA\n",
($W32)?"":"_",$s2,$n;
} else {
printf OUT " %s%-39s @%d\n",
($W32||$OS2)?"":"_",$s2,$n;
}
}
}
}
} while ($thisversion ne $currversion);
if ($linux) {
if ($prevprevsymversion ne "") {
print OUT " local: *;\n} OPENSSL_$prevprevsymversion;\n\n";
} else {
print OUT " local: *;\n};\n\n";
}
}
printf OUT "\n";
}
......@@ -1367,12 +1410,15 @@ sub load_numbers
{
my($name)=@_;
my(@a,%ret);
my $prevversion;
$max_num = 0;
$num_noinfo = 0;
$prev = "";
$prev_cnt = 0;
my ($baseversion, $currversion) = get_openssl_version();
open(IN,"<$name") || die "unable to open $name:$!\n";
while (<IN>) {
chop;
......@@ -1402,7 +1448,13 @@ sub load_numbers
$ret{$a[0]}=$a[1];
$num_noinfo++;
} else {
$ret{$a[0]}=$a[1]."\\".$a[2]; # \\ is a special marker
#Sanity check the version number
if (defined $prevversion) {
check_version_lte($prevversion, $a[2]);
}
check_version_lte($a[2], $currversion);
$prevversion = $a[2];
$ret{$a[0]}=$a[1]."\\".$a[2]."\\".$a[3]; # \\ is a special marker
}
$max_num = $a[1] if $a[1] > $max_num;
$prev=$a[0];
......@@ -1551,3 +1603,133 @@ sub count_parens
return $open - $close;
}
#Parse opensslv.h to get the current version number. Also work out the base
#version, i.e. the lowest version number that is binary compatible with this
#version
sub get_openssl_version()
{
open (IN, "include/openssl/opensslv.h") || die "Can't open opensslv.h";
while(<IN>) {
if (/OPENSSL_VERSION_TEXT\s+"OpenSSL (\d\.\d\.)(\d[a-z]*)(-| )/) {
my $suffix = $2;
my $baseversion = $1 =~ s/\./_/gr;
close IN;
return ($baseversion."0", $baseversion.$suffix);
}
}
die "Can't find OpenSSL version number\n";
}
#Given an OpenSSL version number, calculate the next version number. If the
#version number gets to a.b.czz then we go to a.b.(c+1)
sub get_next_version()
{
my $thisversion = shift;
my ($base, $letter) = $thisversion =~ /^(\d_\d_\d)([a-z]{0,2})$/;
if ($letter eq "zz") {
my $lastnum = substr($base, -1);
return substr($base, 0, length($base)-1).(++$lastnum);
}
return $base.get_next_letter($letter);
}
#Given the letters off the end of an OpenSSL version string, calculate what
#the letters for the next release would be.
sub get_next_letter()
{
my $thisletter = shift;
my $baseletter = "";
my $endletter;
if ($thisletter eq "") {
return "a";
}
if ((length $thisletter) > 1) {
($baseletter, $endletter) = $thisletter =~ /([a-z]+)([a-z])/;
} else {
$endletter = $thisletter;
}
if ($endletter eq "z") {
return $thisletter."a";
} else {
return $baseletter.(++$endletter);
}
}
#Check if a version is less than or equal to the current version. Its a fatal
#error if not. They must also only differ in letters, or the last number (i.e.
#the first two numbers must be the same)
sub check_version_lte()
{
my ($testversion, $currversion) = @_;
my $lentv;
my $lencv;
my $cvbase;
my ($cvnums) = $currversion =~ /^(\d_\d_\d)[a-z]*$/;
my ($tvnums) = $testversion =~ /^(\d_\d_\d)[a-z]*$/;
#Die if we can't parse the version numbers or they don't look sane
die "Invalid version number: $testversion and $currversion\n"
if (!defined($cvnums) || !defined($tvnums)
|| length($cvnums) != 5
|| length($tvnums) != 5);
#If the base versions (without letters) don't match check they only differ
#in the last number
if ($cvnums ne $tvnums) {
die "Invalid version number: $testversion "
."for current version $currversion\n"
if (substr($cvnums, -1) < substr($tvnums, -1)
|| substr($cvnums, 0, 4) ne substr($tvnums, 0, 4));
return;
}
#If we get here then the base version (i.e. the numbers) are the same - they
#only differ in the letters
$lentv = length $testversion;
$lencv = length $currversion;
#If the testversion has more letters than the current version then it must
#be later (or malformed)
if ($lentv > $lencv) {
die "Invalid version number: $testversion "
."is greater than $currversion\n";
}
#Get the last letter from the current version
my ($cvletter) = $currversion =~ /([a-z])$/;
if (defined $cvletter) {
($cvbase) = $currversion =~ /(\d_\d_\d[a-z]*)$cvletter$/;
} else {
$cvbase = $currversion;
}
die "Unable to parse version number $currversion" if (!defined $cvbase);
my $tvbase;
my ($tvletter) = $testversion =~ /([a-z])$/;
if (defined $tvletter) {
($tvbase) = $testversion =~ /(\d_\d_\d[a-z]*)$tvletter$/;
} else {
$tvbase = $testversion;
}
die "Unable to parse version number $testversion" if (!defined $tvbase);
if ($lencv > $lentv) {
#If current version has more letters than testversion then testversion
#minus the final letter must be a substring of the current version
die "Invalid version number $testversion "
."is greater than $currversion or is invalid\n"
if (index($cvbase, $tvbase) != 0);
} else {
#If both versions have the same number of letters then they must be
#equal up to the last letter, and the last letter in testversion must
#be less than or equal to the last letter in current version.
die "Invalid version number $testversion "
."is greater than $currversion\n"
if (($cvbase ne $tvbase) && ($tvletter gt $cvletter));
}
}
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册