WebObjects: Crash in _doprnt() on Solaris 2.x

A bug in Solaris 2.x can cause WebObjects applications to crash under certain circumstances. This could affect any version of Portable Distributed Objects (PDO) or WebObjects 4.5.1 or earlier on Solaris. This document describes the problem and provides a patch WebObjects customers can use to avoid it on Solaris 2.5, 2.6, or 7.
Problem description

A Sun/Solaris bug in the function _doprnt() can cause a WebObjects application to crash if it passes a NULL string argument to printf() or NSLog(), or if any Apple framework is passing a NULL string argument to printf(). This is caused by a bug in the implementation of the _doprnt() function in the Solaris C library and does not occur on other platforms (MacOS X Server, Windows NT, and HP-UX). The Solaris _doprnt() function does not check whether the argument is NULL and causes a segmentation fault when receiving a NULL string. This bug has been assigned Apple bug number 2388853.

If a crash was caused by this bug, the backtrace will normally look something like this:

Program received signal SIGSEGV, Segmentation fault.
0xee624614 in strlen ()
(gdb) bt
#0  0xee624614 in strlen ()
#1  0xee65a4ac in _doprnt ()
#2  0xee663514 in _fprintf ()
#3  0xef4fc33c in global constructors keyed to WOStaticURLUtilities.m ()
#4  0xef4fb080 in global constructors keyed to
WOStaticURLUtilities.m ()
#5 0xef4f80d0 in global constructors keyed to
 _OBJC_METACLASS_WOResponseContentDataFault ()
#6  0xef4ffc78 in global constructors keyed to
_OBJC_METACLASS_WOSessionStore ()

Testing for the bug

To determine if your Solaris machine has the bug, you can run the following simple test program:

/* This is test.c */
#include <stdio.h>

main()
{
       printf("%s", NULL);
}

After compiling the test program, run and see if it crashes with a SIGSEGV. Run it again under gdb, and check if the backtrace looks similar to the one described above. So far, we have seen this bug on Solaris 2.5, 2.6, 7, and Solaris 8.

The patch

If you are using PDO or WebObjects 2.x to 4.x on Solaris 2.5, 2.6, or 7, you can download the patch from Apple's FTP site. The patch is built as a .o file for the SPARC-Solaris platform. It provides a new implementation of _doprnt(), which is robust against NULLs. This patch does not work on Solaris 8.

FTP:

ftp://download.info.apple.com/Apple_Support_Area/Apple_Software_Updates/MultiCountry/Enterprise/webobjects/patches/4.0.1/prntpatch.o

HTTP:

http://download.info.apple.com/Apple_Support_Area/Apple_Software_Updates/MultiCountry/Enterprise/webobjects/patches/4.0.1/prntpatch.o

To test the patch, recompile your test program and link it with the patch as follows:

gcc -o fixedtest test.c prntpatch.o

Rerun the test described above to confirm that the problem has been solved.

Using the patch in your project

Copy the patch file prntpatch.o into your project folder, and edit Makefile.preamble to include the patch at link time with the line:

OTHER_OFILES=prntpatch.o

As a safety measure, you may need to repeat this step for any custom-written frameworks that you are linking your application against.

Note: It is not necessary to include the patch file in the subprojects, if any, of your WebObjects application.

Disclaimers: There is no guarantee that this patch truly fixes the root of your problem. Even if the crash does not recur, you should still investigate whether your code is calling into a C string function with a NULL argument. Otherwise, your application may still generate exceptions even though this particular crashing problem is resolved.

This patch does not work on Solaris 8. (Although Apple has not qualified WebObjects 4.x on Solaris 8, most of WebObjects 4.x appears to work on Solaris 8; this patch is an exception.)

Published Date: Feb 18, 2012