bug-tar
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: [Bug-tar] gtar build error on solaris 2.5.1 (vsnprintf)


From: Nesius, Robert
Subject: RE: [Bug-tar] gtar build error on solaris 2.5.1 (vsnprintf)
Date: Wed, 6 Apr 2005 23:32:42 -0700

I think these two patches safely work around the absence of vsnprintf on
systems that don't have it.  Add -DSOL25 to CFLAGS and you're good to
go.  The patch tries two approaches to accomplishing what the original
code did.  The first approach uses a pipe and is, I think, secure.  If
however there's a problem with using the pipe it uses a big buffer and
hopes for the best.  If that's construed as a problem you can always
just remove the else clause from the big if-statement in the patch.  

The two files are in <src_root>/lib.  This is the first time I've
submitted diffs/patches so if I screwed something up let me know what
and I'll redo it. 

Technically, any system without vsnprintf could probably safely use this
technique. 

For 99% of the list readership, this probably isn't a problem. 

Feedbacks, comments, criticism welcome. 
-Rob

========================================================================
====
*** argp-namefrob.h     Sat Nov 29 05:37:46 2003
--- argp-namefrob.h.patch       Wed Apr  6 22:56:40 2005
***************
*** 98,106 ****
--- 98,111 ----
  #define __strerror_r strerror_r
  #undef __strndup
  #define __strndup strndup
+ 
+ /* This isn't so normal on solaris 2.5.1 */
+ #ifndef SOL25
  #undef __vsnprintf
  #define __vsnprintf vsnprintf
+ #endif
  
+ 
  #if defined(HAVE_DECL_CLEARERR_UNLOCKED) &&
!HAVE_DECL_CLEARERR_UNLOCKED
  # define clearerr_unlocked(x) clearerr (x)
  #endif
========================================================================
====
========================================================================
====
*** argp-fmtstream.c    Thu Sep 25 05:21:21 2003
--- argp-fmtstream.c.patch      Wed Apr  6 22:56:12 2005
***************
*** 29,34 ****
--- 29,38 ----
  #include <errno.h>
  #include <stdarg.h>
  #include <ctype.h>
+ #ifdef SOL25
+ #include <limits.h>
+ #include <unistd.h>
+ #endif
  
  #include "argp-fmtstream.h"
  #include "argp-namefrob.h"
***************
*** 42,49 ****
--- 46,55 ----
  #if defined _LIBC && defined USE_IN_LIBIO
  # include <wchar.h>
  # include <libio/libioP.h>
+ #ifndef SOL25
  # define __vsnprintf(s, l, f, a) _IO_vsnprintf (s, l, f, a)
  #endif
+ #endif
  
  #define INIT_BUF_SIZE 200
  #define PRINTF_SIZE_GUESS 150
***************
*** 410,419 ****
    size_t avail;
    size_t size_guess = PRINTF_SIZE_GUESS; /* How much space to reserve.
*/
  
    do
      {
        va_list args;
- 
        if (! __argp_fmtstream_ensure (fs, size_guess))
        return -1;
  
--- 416,465 ----
    size_t avail;
    size_t size_guess = PRINTF_SIZE_GUESS; /* How much space to reserve.
*/
  
+ #ifdef SOL25
+ /* This code makes the assumption that bufsize will never be too small
*/ 
+   int bufmult=2;
+   int bufsize=0;
+   int pfds[2]; 
+   FILE *WRITER = NULL;
+   FILE *READER = NULL; 
+   va_list args;
+  
+   /* Try using pipes - else use big buffer*/
+   pipe (pfds); 
+   WRITER = fdopen(pfds[1], "w"); 
+   READER = fdopen(pfds[0], "r"); 
+   if (WRITER != NULL)  { 
+     va_start (args, fmt);
+     /* Worst an attack can do here is hog resources - can't overflow
*/
+     /* No tmp file attack possible */
+     out = vfprintf (WRITER, fmt, args);
+     va_end (args);
+     fclose (WRITER); 
+     fclose (READER); 
+ 
+     if (! __argp_fmtstream_ensure (fs, out+1))
+       return -1;
+     
+     va_start (args, fmt);
+     out = vsprintf (fs->p, fmt, args);
+     va_end (args);
+   } else { 
+ 
+     bufsize = sizeof (char) * PATH_MAX * bufmult;
+ 
+     if (! __argp_fmtstream_ensure (fs, bufsize + 1))
+       return -1;
+ 
+     va_start (args, fmt);
+     out = vsprintf (fs->p, fmt, args);
+     va_end (args);
+   }
+ 
+ #else
    do
      {
        va_list args;
        if (! __argp_fmtstream_ensure (fs, size_guess))
        return -1;
  
***************
*** 421,435 ****
        avail = fs->end - fs->p;
        out = __vsnprintf (fs->p, avail, fmt, args);
        va_end (args);
        if ((size_t) out >= avail)
        size_guess = out + 1;
      }
    while ((size_t) out >= avail);
  
    fs->p += out;
- 
    return out;
  }
  #if 0
  /* Not exported.  */
  #ifdef weak_alias
--- 467,483 ----
        avail = fs->end - fs->p;
        out = __vsnprintf (fs->p, avail, fmt, args);
        va_end (args);
+ 
        if ((size_t) out >= avail)
        size_guess = out + 1;
      }
    while ((size_t) out >= avail);
+ #endif
  
    fs->p += out;
    return out;
  }
+ 
  #if 0
  /* Not exported.  */
  #ifdef weak_alias
========================================================================
====

-----Original Message-----
From: address@hidden
[mailto:address@hidden On Behalf Of
Nesius, Robert
Sent: Wednesday, April 06, 2005 3:16 PM
To: address@hidden
Subject: [Bug-tar] gtar build error on solaris 2.5.1 (vsnprintf)


I ran into a build error on Solaris 2.5.1 with the latest gtar.  gtar
wants vsnprintf, which doesn't exist on solaris 2.5.1 (at least on the
box I have.) I googled on the error and found other projects running
into this problem on this platform, but no specific mention of gtar.  

I also went through the list archives before writing and came up blank.
It seems the code where vsnprintf is being used relies on the
bounds-protection of svnprintf to not overflow a buffer.  Are there any
known workarounds for this?  Or, is there a compatability library out
there that implements vsnprintf functionality on systems that don't have
it?  Seems like tar shouldn't rely vsnprintf if it doesn't exist.  

Thanks in advance hints/ideas/workarounds,
-Rob

The error:
gmake[2]: Nothing to be done for `all'.
Making all in src
/usr/intel/pkgs/gcc/3.2/bin/gcc  -L/usr/intel/pkgs/libgettext/0.14.3/lib
-I/usr/intel/pkgs/libgettext/0.14.3/lib -O2   -o tar  buffer.o compare.o
create.o delete.o extract.o xheader.o incremen.o list.o mangle.o misc.o
names.o sparse.o system.o tar.o update.o utf8.o ../lib/libtar.a -lintl
-lposix4 
../lib/libtar.a(argp-fmtstream.o): In function `argp_fmtstream_printf':
argp-fmtstream.o(.text+0x7a8): undefined reference to `vsnprintf'
collect2: ld returned 1 exit status
gmake[2]: *** [tar] Error 1
gmake[1]: *** [all-recursive] Error 1
gmake: *** [all] Error 2
[psus0102]-> /fs3/comp.apps_build.1/gtar/sol25/tar-1.15.1 >

The code: 
lib/argp-fmtstream.c
     42 #if defined _LIBC && defined USE_IN_LIBIO
     43 # include <wchar.h>
     44 # include <libio/libioP.h>
     45 # define __vsnprintf(s, l, f, a) _IO_vsnprintf (s, l, f, a)
     46 #endif 
...
    406 ssize_t
    407 __argp_fmtstream_printf (struct argp_fmtstream *fs, const char
*fmt, ...)
    408 {
    409   int out;
    410   size_t avail;
    411   size_t size_guess = PRINTF_SIZE_GUESS; /* How much space to
reserve. */
    412
    413   do
    414     {
    415       va_list args;
    416
    417       if (! __argp_fmtstream_ensure (fs, size_guess))
    418         return -1;
    419
    420       va_start (args, fmt);
    421       avail = fs->end - fs->p;
--> 422       out = __vsnprintf (fs->p, avail, fmt, args);
    423       va_end (args);
    424       if ((size_t) out >= avail)
    425         size_guess = out + 1;
    426     }
    427   while ((size_t) out >= avail);
    428
    429   fs->p += out;
    430
    431   return out;
    432 }

_______________________________________________
Bug-tar mailing list
address@hidden
http://lists.gnu.org/mailman/listinfo/bug-tar



reply via email to

[Prev in Thread] Current Thread [Next in Thread]