[Top][All Lists]
[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