[binutils-gdb] The procedure to find an unused port for the debuginfod tests is susceptible to a TOCTOU failure. C

Nick Clifton nickc@sourceware.org
Mon Mar 2 12:47:00 GMT 2020


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=b312fea191f0118c2438198f5069d25b0b527178

commit b312fea191f0118c2438198f5069d25b0b527178
Author: Aaron Merey <amerey@redhat.com>
Date:   Mon Mar 2 12:46:47 2020 +0000

    The procedure to find an unused port for the debuginfod tests is susceptible to a TOCTOU failure.  Change port finding in order to avoid this. Also use 'expect' to interact with the server process since we now use the server's output to determine whether a port is in use.
    
    	* binutils/testsuite/binutils-all/debuginfod.exp: Improve port
    	selection.

Diff:
---
 binutils/ChangeLog                             |  5 +++
 binutils/testsuite/binutils-all/debuginfod.exp | 54 +++++++++++++-------------
 2 files changed, 31 insertions(+), 28 deletions(-)

diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 479061d..e1cec98 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,8 @@
+2020-03-02  Aaron Merey  <amerey@redhat.com>
+
+	* binutils/testsuite/binutils-all/debuginfod.exp: Improve port
+	selection.
+
 2020-03-02  Nick Clifton  <nickc@redhat.com>
 
 	PR 25543
diff --git a/binutils/testsuite/binutils-all/debuginfod.exp b/binutils/testsuite/binutils-all/debuginfod.exp
index 7e1c638..5b59d19 100644
--- a/binutils/testsuite/binutils-all/debuginfod.exp
+++ b/binutils/testsuite/binutils-all/debuginfod.exp
@@ -1,4 +1,4 @@
-# Copyright (C) 2002-2019 Free Software Foundation, Inc.
+# Copyright (C) 2002-2020 Free Software Foundation, Inc.
 
 # 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
@@ -72,9 +72,6 @@ if { ![binutils_assemble $srcdir/$subdir/linkdebug.s tmpdir/linkdebug.debug] } {
     fail "$test (assemble linkdebug)"
 }
 
-# Find an unused port
-set port [exec sh -c "while true; do PORT=`expr '(' \$RANDOM % 1000 ')' + 9000`; ss -atn | fgrep \":\$PORT\" || break; done; echo \$PORT"]
-
 set cache [file join [pwd] "tmpdir/.debuginfod_cache"]
 set db [file join [pwd] "tmpdir/.debuginfod.db"]
 
@@ -99,34 +96,36 @@ file delete -force $db
 set conf_objdump [binutils_run $OBJDUMP "-WK tmpdir/testprog"]
 set conf_readelf [binutils_run $READELF "-wK tmpdir/testprog"]
 
-set debuginfod_pid 0
-
-# Kill the server if we abort early
-proc sigint_handler {} {
-    global debuginfod_pid
+# Find an unused port
+set port 7999
+set found 0
+while { ! $found } {
+  incr port
+  if { $port == 65536 } {
+    untested "$test (no available ports)"
+    return
+  }
 
-    if { $debuginfod_pid != 0 } {
-        catch {exec kill -INT $debuginfod_pid}
+  spawn debuginfod -vvvv -d $db -p $port -F tmpdir/dbg
+  expect {
+    "started http server on IPv4 IPv6 port=$port" {
+      set found 1
     }
-
-    exit
-}
-
-trap sigint_handler INT
-
-# Start a debuginfod server.
-set debuginfod_pid [exec debuginfod -d $db -p $port -F tmpdir/dbg 2>/dev/null &]
-
-if { !$debuginfod_pid } {
-    fail "$test (server init)"
-    return
+    "Failed to bind to port" {
+      exec kill -INT -[exp_pid]
+      catch {close}; catch {wait -i $spawn_id}
+    }
+    timeout {
+      fail "$test (find port timeout)"
+      return
+    }
+  }
 }
 
 set metrics [list "ready 1" \
              "thread_work_total{role=\"traverse\"} 1" \
              "thread_work_pending{role=\"scan\"} 0" \
-             "thread_busy{role=\"scan\"} 0" \
-             "groom{statistic=\"buildids\"} 2"]
+             "thread_busy{role=\"scan\"} 0"]
 
 # Check server metrics to confirm init has completed.
 foreach m $metrics {
@@ -145,7 +144,8 @@ foreach m $metrics {
 
   if { $timelim == 0 } {
     fail "$test (server init timeout)"
-    catch {exec kill -INT $debuginfod_pid}
+    exec kill -INT -[exp_pid]
+    catch {close}; catch {wait -i $spawn_id}
     return
   }
 }
@@ -196,5 +196,3 @@ if { [regexp ".*DEBUGINFOD.*" $conf_readelf] } {
 } else {
     untested "$test (readelf not configured with debuginfod)"
 }
-
-catch {exec kill -INT $debuginfod_pid}



More information about the Binutils-cvs mailing list