mirror of
https://git.savannah.gnu.org/git/inetutils.git
synced 2026-01-12 00:19:39 +08:00
Buffer overflow in tftp and tftpd.
Recent Gnu libc and Gcc inject checks for buffer size into strcpy(). These interfere with declarations in <arpa/tftp.h>. Issue was reported independently by Mike Gilbert and Ricardo Ribalda Delgado.
This commit is contained in:
17
ChangeLog
17
ChangeLog
@@ -1,3 +1,20 @@
|
||||
2020-02-04 Mats Erik Andersson <gnu@gisladisker.se>
|
||||
|
||||
Buffer overflow in tftp and tftpd.
|
||||
Recent versions of Gnu libc and Gcc are injecting buffer checks
|
||||
into strcpy(). Both executables, tftp and tftpd, are effectively
|
||||
copying into a formally declared `char th_msg[1]', ignorant of
|
||||
the underlying buffer being of size PKTSIZE.
|
||||
Problem was reported by Mike Gilbert and Ricardo Ribalda Delgado:
|
||||
https://lists.gnu.org/archive/html/bug-inetutils/2017-12/msg00001.html
|
||||
https://lists.gnu.org/archive/html/bug-inetutils/2019-07/msg00002.html
|
||||
|
||||
* src/tftp.c (nak): Replace strcpy() by memcpy(), after the
|
||||
needed calculation of string length.
|
||||
* src/tftpd.c (nak): Likewise.
|
||||
|
||||
* tests/tftp.sh: New compound test with multiple requests.
|
||||
|
||||
2020-02-03 Mats Erik Andersson <gnu@gisladisker.se>
|
||||
|
||||
whois: AUDA services Australia.
|
||||
|
||||
@@ -1294,8 +1294,8 @@ nak (int error)
|
||||
pe->e_msg = strerror (error - 100);
|
||||
tp->th_code = EUNDEF;
|
||||
}
|
||||
strcpy (tp->th_msg, pe->e_msg);
|
||||
length = strlen (pe->e_msg) + 4;
|
||||
memcpy (tp->th_msg, pe->e_msg, length - 3);
|
||||
if (trace)
|
||||
tpacket ("sent", tp, length);
|
||||
if (sendto (f, ackbuf, length, 0, (struct sockaddr *) &peeraddr,
|
||||
|
||||
@@ -862,8 +862,8 @@ nak (int error)
|
||||
pe->e_msg = strerror (error - 100);
|
||||
tp->th_code = EUNDEF; /* set 'undef' errorcode */
|
||||
}
|
||||
strcpy (tp->th_msg, pe->e_msg);
|
||||
length = strlen (pe->e_msg);
|
||||
memcpy (tp->th_msg, pe->e_msg, length);
|
||||
tp->th_msg[length] = '\0';
|
||||
length += 5;
|
||||
if (sendto (peer, buf, length, 0, (struct sockaddr *) &from, fromlen) != length)
|
||||
|
||||
@@ -386,7 +386,42 @@ get $name" | \
|
||||
SUCCESSES=`expr $SUCCESSES + 1`
|
||||
test -z "$VERBOSE" || echo "Successful comparison for $addr/$name." >&2
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
# Do a compound test with multiple requests.
|
||||
# Issue one request for locally renamed file.
|
||||
rm -f file-small _file-small_ missing-file
|
||||
EFFORTS=`expr $EFFORTS + 1`
|
||||
|
||||
cat <<-EOT |
|
||||
binary
|
||||
get file-small
|
||||
get missing-file
|
||||
get file-small _file-small_
|
||||
quit
|
||||
EOT
|
||||
eval $TFTP ${VERBOSE:+-v} "$addr" $PORT $bucket
|
||||
|
||||
if cmp "$TMPDIR/tftp-test/file-small" file-small 2>/dev/null \
|
||||
&& test ! -s missing-file \
|
||||
&& cmp "$TMPDIR/tftp-test/file-small" _file-small_ 2>/dev/null
|
||||
then
|
||||
SUCCESSES=`expr $SUCCESSES + 1`
|
||||
test -z "$VERBOSE" || echo "Successful compound test." >&2
|
||||
else
|
||||
echo "Failure during compound test." >&2
|
||||
|
||||
# Investigate probable causes.
|
||||
test -s _file-small_ ||
|
||||
echo "Third get request failed after file known to be missing." >&2
|
||||
{ test ! -f missing-file || test -s missing-file ; } &&
|
||||
echo "The missing file did not appear as empty." >&1
|
||||
test -s file-small ||
|
||||
echo "Not even the first request succeeded." >&2
|
||||
RESULT=1
|
||||
fi
|
||||
|
||||
rm -f file-small _file-small_ missing-file
|
||||
done
|
||||
|
||||
# Test the ability of inetd to reload configuration:
|
||||
|
||||
Reference in New Issue
Block a user