[SRU] Buffer overflow in check_ntp_peer - Nagios can't check time servers in Intrepid

Bug #291265 reported by Anderson
10
Affects Status Importance Assigned to Milestone
nagios-plugins (Debian)
Fix Released
Unknown
nagios-plugins (Ubuntu)
Fix Released
Medium
Unassigned
Intrepid
Fix Released
Undecided
Thierry Carrez

Bug Description

Binary package hint: nagios-plugins-basic

I just upgraded my Nagios server from Ubuntu Hardy to Ubuntu Intrepid and now, time server checks can't be done because of a problem in check_ntp_peer:

$ /usr/lib/nagios/plugins/check_ntp_peer -H time.cefetrs.tche.br
*** buffer overflow detected ***: /usr/lib/nagios/plugins/check_ntp_peer terminated
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x48)[0xb7f0b558]
/lib/tls/i686/cmov/libc.so.6[0xb7f09680]
/lib/tls/i686/cmov/libc.so.6(__read_chk+0x50)[0xb7f09b40]
/usr/lib/nagios/plugins/check_ntp_peer[0x8049ea1]
/usr/lib/nagios/plugins/check_ntp_peer[0x804a96e]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe5)[0xb7e27685]
/usr/lib/nagios/plugins/check_ntp_peer[0x8048e31]
======= Memory map: ========
08048000-0804f000 r-xp 00000000 08:07 20658 /usr/lib/nagios/plugins/check_ntp_peer
0804f000-08050000 r--p 00006000 08:07 20658 /usr/lib/nagios/plugins/check_ntp_peer
08050000-08051000 rw-p 00007000 08:07 20658 /usr/lib/nagios/plugins/check_ntp_peer
09628000-09649000 rw-p 09628000 00:00 0 [heap]
b7cbe000-b7ccb000 r-xp 00000000 08:07 2513 /lib/libgcc_s.so.1
b7ccb000-b7ccc000 r--p 0000c000 08:07 2513 /lib/libgcc_s.so.1
b7ccc000-b7ccd000 rw-p 0000d000 08:07 2513 /lib/libgcc_s.so.1
b7ccd000-b7cd1000 r-xp 00000000 08:07 32918 /lib/tls/i686/cmov/libnss_dns-2.8.90.so
b7cd1000-b7cd2000 r--p 00003000 08:07 32918 /lib/tls/i686/cmov/libnss_dns-2.8.90.so
b7cd2000-b7cd3000 rw-p 00004000 08:07 32918 /lib/tls/i686/cmov/libnss_dns-2.8.90.so
b7cd3000-b7cdd000 r-xp 00000000 08:07 32919 /lib/tls/i686/cmov/libnss_files-2.8.90.so
b7cdd000-b7cde000 r--p 00009000 08:07 32919 /lib/tls/i686/cmov/libnss_files-2.8.90.so
b7cde000-b7cdf000 rw-p 0000a000 08:07 32919 /lib/tls/i686/cmov/libnss_files-2.8.90.so
b7ce3000-b7d22000 r--p 00000000 08:07 5215 /usr/lib/locale/pt_BR.utf8/LC_CTYPE
b7d22000-b7d23000 r--p 00000000 08:07 21334 /usr/lib/locale/pt_BR.utf8/LC_NUMERIC
b7d23000-b7d24000 r--p 00000000 08:07 21339 /usr/lib/locale/pt_BR.utf8/LC_TIME
b7d24000-b7e05000 r--p 00000000 08:07 7786 /usr/lib/locale/pt_BR.utf8/LC_COLLATE
b7e05000-b7e06000 r--p 00000000 08:07 21341 /usr/lib/locale/pt_BR.utf8/LC_MONETARY
b7e06000-b7e07000 r--p 00000000 08:07 21343 /usr/lib/locale/pt_BR.utf8/LC_MESSAGES/SYS_LC_MESSAGES
b7e07000-b7e08000 r--p 00000000 08:07 9892 /usr/lib/locale/pt_BR.utf8/LC_PAPER
b7e08000-b7e09000 r--p 00000000 08:07 10099 /usr/lib/locale/pt_BR.utf8/LC_NAME
b7e09000-b7e10000 r--s 00000000 08:07 1745 /usr/lib/gconv/gconv-modules.cache
b7e10000-b7e11000 rw-p b7e10000 00:00 0
b7e11000-b7f69000 r-xp 00000000 08:07 32906 /lib/tls/i686/cmov/libc-2.8.90.so
b7f69000-b7f6b000 r--p 00158000 08:07 32906 /lib/tls/i686/cmov/libc-2.8.90.so
b7f6b000-b7f6c000 rw-p 0015a000 08:07 32906 /lib/tls/i686/cmov/libc-2.8.90.so
b7f6c000-b7f6f000 rw-p b7f6c000 00:00 0
b7f6f000-b7f93000 r-xp 00000000 08:07 32912 /lib/tls/i686/cmov/libm-2.8.90.so
b7f93000-b7f94000 r--p 00023000 08:07 32912 /lib/tls/i686/cmov/libm-2.8.90.so
b7f94000-b7f95000 rw-p 00024000 08:07 32912 /lib/tls/i686/cmov/libm-2.8.90.so
b7f95000-b7fa5000 r-xp 00000000 08:07 32925 /lib/tls/i686/cmov/libresolv-2.8.90.so
b7fa5000-b7fa6000 r--p 0000f000 08:07 32925 /lib/tls/i686/cmov/libresolv-2.8.90.so
b7fa6000-b7fa7000 rw-p 00010000 08:07 32925 /lib/tls/i686/cmov/libresolv-2.8.90.so
b7fa7000-b7fa9000 rw-p b7fa7000 00:00 0
b7fa9000-b7fbe000 r-xp 00000000 08:07 32916 /lib/tls/i686/cmov/libnsl-2.8.90.so
b7fbe000-b7fbf000 r--p 00014000 08:07 32916 /lib/tls/i686/cmov/libnsl-2.8.90.so
b7fbf000-b7fc0000 rw-p 00015000 08:07 32916 /lib/tls/i686/cmov/libnsl-2.8.90.so
b7fc0000-b7fc3000 rw-p b7fc0000 00:00 0
b7fc3000-b7fc4000 r--p 00000000 08:07 21344 /usr/lib/locale/pt_BR.utf8/LC_ADDRESS
b7fc4000-b7fc5000 r--p 00000000 08:07 21345 /usr/lib/locale/pt_BR.utf8/LC_TELEPHONE
b7fc5000-b7fc6000 r--p 00000000 08:07 10102 /usr/lib/locale/pt_BR.utf8/LC_MEASUREMENT
b7fc6000-b7fc7000 r--p 00000000 08:07 21346 /usr/lib/locale/pt_BR.utf8/LC_IDENTIFICATION
b7fc7000-b7fc8000 rw-p b7fc7000 00:00 0
b7fc8000-b7fe2000 r-xp 00000000 08:07 20446 /lib/ld-2.8.90.so
b7fe2000-b7fe3000 r-xp b7fe2000 00:00 0 [vdso]
b7fe3000-b7fe4000 r--p 0001a000 08:07 20446 /lib/ld-2.8.90.so
b7fe4000-b7fe5000 rw-p 0001b000 08:07 20446 /lib/ld-2.8.90.so
bfed0000-bfee5000 rw-p bffeb000 00:00 0 [stack]
Aborted

Revision history for this message
Thierry Carrez (ttx) wrote :

Confirmed, something gets caught by the stack smashing police.
Regression in intrepid, as it was working well in hardy.

Changed in nagios-plugins:
importance: Undecided → High
status: New → Confirmed
Revision history for this message
Thierry Carrez (ttx) wrote :

It fails on line 264 on
if(read(conn, &req, SIZEOF_NTPCM(req)) == -1)

Upstream bug is:
http://sourceforge.net/tracker/?func=detail&atid=397597&aid=1999319&group_id=29880

It's closed by saying the bug is in _FORTIFY_SOURCE, as the author checked that the "read" call should not exceed allocated value.

"check_ntp" doesn't fail so it can be used as a workaround.

Changed in nagios-plugins:
importance: High → Medium
Revision history for this message
Jamie Strandboge (jdstrand) wrote :

I looked at this a bit, and the math seems to be wrong in this line:
#define SIZEOF_NTPCM(m) (12+ntohs(m.count)+((m.count)?4-(ntohs(m.count)%4):0))

In ntp_request we have (where MAX_CM_SIZE is defined as 468):
req.count=htons(MAX_CM_SIZE);

Which makes req.count = 54273. Later, we have:
if(read(conn, &req, SIZEOF_NTPCM(req)) == -1)

So the nbytes for read() ends up being:
(12 + 468 + (4 - 0)) = 484

However, a sizeof(req) reveals that it is 480 bytes (this can also be seen by looking at the ntp_control_message struct (1+1+2+2+2+2+2+468)). This is not security relevant, because the 4 bytes that are overwritten end up being the 'conn' file descriptor (as seen from gdb), which triggers read() to:

read(3, 0xbffff850, 484) = ? ERESTARTSYS (To be restarted)
--- SIGALRM (Alarm clock) @ 0 (0) ---

resulting in check_ntp_peer to error out with:
CRITICAL - Socket timeout after 10 seconds

This is a bug whether or not _FORTIFY_SOURCE is used, because read() may SIGALRM. You'll also notice that check_ntp.c suffers from the same problem (the code in question is identical), as seen with:
$ /usr/lib/nagios/plugins/check_ntp -H foo -j 1

Revision history for this message
Thomas Guyot-Sionnest (dermoth) wrote :

Thanks Jamie, this will be fixed soon in SVN. See the sourceforge tracker (Comment #2) for more details and updates.

FYI this bug is present in all version of check_ntp (in "plugins/" only) and check_ntp_peer (from which the code was taken), it's just that for some reasons it doesn't get triggered. The SIZEOF_NTPCM formula was broken in the very first versions of check_ntp (note though that very old versions of nagios-plugins shipped a Perl version of check_ntp, found in "plugins-scripts/").

Revision history for this message
Thierry Carrez (ttx) wrote :
Changed in nagios-plugins:
assignee: nobody → tcarrez
status: Confirmed → In Progress
Revision history for this message
Thierry Carrez (ttx) wrote :

Debdiff to fix this in the current development release

nagios-plugins (1.4.12-4ubuntu2) jaunty; urgency=low

  * Added 99_check_ntp_segfaults.dpatch: Fix for check_ntp and check_ntp_peer
    segfaults (LP: #291265)

Changed in nagios-plugins:
assignee: tcarrez → nobody
status: In Progress → Confirmed
Revision history for this message
Launchpad Janitor (janitor) wrote :

This bug was fixed in the package nagios-plugins - 1.4.12-4ubuntu2

---------------
nagios-plugins (1.4.12-4ubuntu2) jaunty; urgency=low

  * Added 99_check_ntp_segfaults.dpatch: Fix for check_ntp and check_ntp_peer
    segfaults (LP: #291265)

 -- Thierry Carrez <email address hidden> Wed, 19 Nov 2008 16:44:27 +0000

Changed in nagios-plugins:
status: Confirmed → Fix Released
Revision history for this message
Anderson (amg1127) wrote :

Thank you for the job, mantainers and developers!

Revision history for this message
Thierry Carrez (ttx) wrote :

SRU report

Bug impact: Make Nagios ntp_check and ntp_check_peer plugins unusable under Intrepid. This is a regression, as this didn't trigger any error on previous releases.

Jaunty bugfix: fixed released in 1.4.12-4ubuntu2

Minimal patch: see below.

TEST CASE:
$ sudo apt-get install nagios-plugins-basic
With an affected version:
$ /usr/lib/nagios/plugins/check_ntp -H spork.qfe3.net -j 1
$ /usr/lib/nagios/plugins/check_ntp_peer -H spork.qfe3.net
both return a *** buffer overflow detected *** error stack
With a fixed version:
$ /usr/lib/nagios/plugins/check_ntp -H spork.qfe3.net -j 1
NTP OK: Décalage -0,006611943245 secs, jitter=0,000000|offset=-0,006612s;60,000000;120,000000; jitter=0,000000s;1,000000;10000,000000;0,000000
$ /usr/lib/nagios/plugins/check_ntp_peer -H spork.qfe3.net
NTP OK: Décalage -0,002 secs|offset=-0,002000s;60,000000;120,000000;

Regression potential:
The patch only affects those two plugins, and they are completely unusable without the fix.

Revision history for this message
Thierry Carrez (ttx) wrote :

Debdiff for Intrepid SRU

nagios-plugins (1.4.11-2ubuntu2.1) intrepid-proposed; urgency=low

  * Added 99_check_ntp_segfaults.dpatch: Fix for check_ntp and check_ntp_peer
    segfaults (LP: #291265)

Revision history for this message
Martin Pitt (pitti) wrote :

Approved for SRU, please upload.

Changed in nagios-plugins:
assignee: nobody → tcarrez
status: New → In Progress
Revision history for this message
Martin Pitt (pitti) wrote :

Accepted into intrepid-proposed, please test and give feedback here. Please see https://wiki.ubuntu.com/Testing/EnableProposed for documentation how to enable and use -proposed. Thank you in advance!

Changed in nagios-plugins:
status: In Progress → Fix Committed
Revision history for this message
Anderson (amg1127) wrote :

check_ntp_peer works now:

Before stopping time server...

# /usr/lib/nagios/plugins/check_ntp_peer -H time.cefetrs.tche.br
NTP OK: Offset -0,002 secs|offset=-0,002000s;60,000000;120,000000;

After stopping time server...

# /usr/lib/nagios/plugins/check_ntp_peer -H time.cefetrs.tche.br
NTP CRITICAL: No response from NTP server

After starting time server again...

# /usr/lib/nagios/plugins/check_ntp_peer -H time.cefetrs.tche.br
NTP CRITICAL: Server not synchronized, Offset unknown|

# /usr/lib/nagios/plugins/check_ntp_peer -H time.cefetrs.tche.br
NTP OK: Offset -0,002 secs|offset=-0,002000s;60,000000;120,000000;

Revision history for this message
Launchpad Janitor (janitor) wrote :

This bug was fixed in the package nagios-plugins - 1.4.11-2ubuntu2.1

---------------
nagios-plugins (1.4.11-2ubuntu2.1) intrepid-proposed; urgency=low

  * Added 99_check_ntp_segfaults.dpatch: Fix for check_ntp and check_ntp_peer
    segfaults (LP: #291265)

 -- Thierry Carrez <email address hidden> Thu, 20 Nov 2008 09:51:51 +0100

Changed in nagios-plugins:
status: Fix Committed → Fix Released
Revision history for this message
Martin Pitt (pitti) wrote :

Copied to intrepid-updates.

Changed in nagios-plugins (Debian):
status: Unknown → Confirmed
Artur Rona (ari-tczew)
Changed in nagios-plugins (Debian):
importance: Unknown → Undecided
status: Confirmed → New
importance: Undecided → Unknown
status: New → Unknown
Changed in nagios-plugins (Debian):
status: Unknown → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.