openssh-2.3.0p1 bug: vsprintf("%h") is broken

Dan Astoorian djast at
Thu Nov 9 06:00:44 EST 2000

I discovered this in openssh-2.3.0p1; it may affect earlier versions as

Platforms: Solaris 2.5.1 and 8, probably others.

Observed behaviour:
    With -v, when attempting to connect to a host which is not
    listening on the requested port, I noticed that the port number is
    reported as zero in the message:

	Secure connection to hostname on port 0 refused.

Apparent cause:
    At line 671 of ssh.c, the message is logged using a format string of

    It appears that the vsnprintf() implementation in /bsd-snprintf.c
    handles %hu incorrectly.  It does the following at line 262:
	if (cflags == DP_C_SHORT)
	    value = va_arg (args, short int);

    Similarly for %hd, %hi, %ho and %hx.

    The man page for va_arg under Solaris 8 indicates the following:

    |    It is non-portable to specify a second argument of  char  or
    |    short to  va_arg, because arguments seen by the called func-
    |    tion are not char or short.  C  converts   char  and   short
    |    arguments to  int before passing them to a function.

To reproduce:
    Compile the following against bsd-snprintf.o:

	#include <varargs.h>
	#include <stdio.h>

	char msgbuf[256];

	void foo(char *fmt, ...) {
	    va_list args;
	    va_start(args, fmt);
	    vsnprintf(msgbuf, sizeof(msgbuf), fmt, args);
	    printf("%s", msgbuf);

	main() {
	    int i = 10;
	    short j = 10;
	    foo("x %d x\n", i);
	    foo("x %hu x\n", i);
	    foo("x %d x\n", j);
	    foo("x %hu x\n", j);

    The resulting program prints "x 0 x" instead of "x 10 x" on the
    second and fourth lines.

    Presumably, change "short int" to "int", and "unsigned short int" at
    the relevant lines (263, 275, 287, 301 of bsd-snprintf.c).  If there
    are implementations which break the specification and fail to
    promote arguments of type short to an integer argument, it may be
    necessary to #ifdef around this on those platforms.

Security implications:
    None known.

Other notes:
    sshconnect.c line 59 (ssh_proxy_connect()) *may* suffer from the
    same bug:

	snprintf(strport, sizeof strport, "%hu", port);

Please let me know if you require further details.


--                          People shouldn't think that it's better to have
Dan Astoorian               loved and lost than never loved at all.  It's
Sysadmin, CSLab             not, it's better to have loved and won.  All
djast at        the other options really suck.    --Dan Redican

More information about the openssh-unix-dev mailing list