Skip to content

Commit 0510cff

Browse files
committed
Revert error-throwing wrappers for the printf family of functions.
This reverts commit 16304a0, except for its changes in src/port/snprintf.c; as well as commit cac18a7 which is no longer needed. Fujii Masao reported that the previous commit caused failures in psql on OS X, since if one exits the pager program early while viewing a query result, psql sees an EPIPE error from fprintf --- and the wrapper function thought that was reason to panic. (It's a bit surprising that the same does not happen on Linux.) Further discussion among the security list concluded that the risk of other such failures was far too great, and that the one-size-fits-all approach to error handling embodied in the previous patch is unlikely to be workable. This leaves us again exposed to the possibility of the type of failure envisioned in CVE-2015-3166. However, that failure mode is strictly hypothetical at this point: there is no concrete reason to believe that an attacker could trigger information disclosure through the supposed mechanism. In the first place, the attack surface is fairly limited, since so much of what the backend does with format strings goes through stringinfo.c or psprintf(), and those already had adequate defenses. In the second place, even granting that an unprivileged attacker could control the occurrence of ENOMEM with some precision, it's a stretch to believe that he could induce it just where the target buffer contains some valuable information. So we concluded that the risk of non-hypothetical problems induced by the patch greatly outweighs the security risks. We will therefore revert, and instead undertake closer analysis to identify specific calls that may need hardening, rather than attempt a universal solution. We have kept the portion of the previous patch that improved snprintf.c's handling of errors when it calls the platform's sprintf(). That seems to be an unalloyed improvement. Security: CVE-2015-3166
1 parent 2c2c7bc commit 0510cff

File tree

15 files changed

+45
-247
lines changed

15 files changed

+45
-247
lines changed

src/include/port.h

Lines changed: 25 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -155,21 +155,19 @@ extern unsigned char pg_tolower(unsigned char ch);
155155
extern unsigned char pg_ascii_toupper(unsigned char ch);
156156
extern unsigned char pg_ascii_tolower(unsigned char ch);
157157

158+
#ifdef USE_REPL_SNPRINTF
159+
158160
/*
159-
* Capture macro-compatible calls to printf() and friends, and redirect them
160-
* to wrappers that throw errors in lieu of reporting failure in a return
161-
* value. Versions of libintl >= 0.13 similarly redirect to versions that
162-
* understand the %$ format, so disable libintl macros first.
161+
* Versions of libintl >= 0.13 try to replace printf() and friends with
162+
* macros to their own versions that understand the %$ format. We do the
163+
* same, so disable their macros, if they exist.
163164
*/
164165
#ifdef vsnprintf
165166
#undef vsnprintf
166167
#endif
167168
#ifdef snprintf
168169
#undef snprintf
169170
#endif
170-
#ifdef vsprintf
171-
#undef vsprintf
172-
#endif
173171
#ifdef sprintf
174172
#undef sprintf
175173
#endif
@@ -183,61 +181,11 @@ extern unsigned char pg_ascii_tolower(unsigned char ch);
183181
#undef printf
184182
#endif
185183

186-
extern int
187-
vsnprintf_throw_on_fail(char *str, size_t count, const char *fmt, va_list args)
188-
__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 0)));
189-
extern int
190-
snprintf_throw_on_fail(char *str, size_t count, const char *fmt,...)
191-
__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
192-
extern int
193-
vsprintf_throw_on_fail(char *str, const char *fmt, va_list args)
194-
__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 0)));
195-
extern int
196-
sprintf_throw_on_fail(char *str, const char *fmt,...)
197-
__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
198-
extern int
199-
vfprintf_throw_on_fail(FILE *stream, const char *fmt, va_list args)
200-
__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 0)));
201-
extern int
202-
fprintf_throw_on_fail(FILE *stream, const char *fmt,...)
203-
__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
204-
extern int
205-
printf_throw_on_fail(const char *fmt,...)
206-
__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
207-
208-
/*
209-
* The GCC-specific code below prevents the __attribute__(... 'printf')
210-
* above from being replaced, and this is required because gcc doesn't
211-
* know anything about printf_throw_on_fail.
212-
*/
213-
#ifdef __GNUC__
214-
#define vsnprintf(...) vsnprintf_throw_on_fail(__VA_ARGS__)
215-
#define snprintf(...) snprintf_throw_on_fail(__VA_ARGS__)
216-
#define vsprintf(...) vsprintf_throw_on_fail(__VA_ARGS__)
217-
#define sprintf(...) sprintf_throw_on_fail(__VA_ARGS__)
218-
#define vfprintf(...) vfprintf_throw_on_fail(__VA_ARGS__)
219-
#define fprintf(...) fprintf_throw_on_fail(__VA_ARGS__)
220-
#define printf(...) printf_throw_on_fail(__VA_ARGS__)
221-
#else
222-
#define vsnprintf vsnprintf_throw_on_fail
223-
#define snprintf snprintf_throw_on_fail
224-
#define vsprintf vsprintf_throw_on_fail
225-
#define sprintf sprintf_throw_on_fail
226-
#define vfprintf vfprintf_throw_on_fail
227-
#define fprintf fprintf_throw_on_fail
228-
#define printf printf_throw_on_fail
229-
#endif
230-
231-
#ifdef USE_REPL_SNPRINTF
232-
233-
/* Code outside syswrap.c should not call these. */
234-
235184
extern int pg_vsnprintf(char *str, size_t count, const char *fmt, va_list args);
236185
extern int
237186
pg_snprintf(char *str, size_t count, const char *fmt,...)
238187
/* This extension allows gcc to check the format string */
239188
__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
240-
extern int pg_vsprintf(char *str, const char *fmt, va_list args);
241189
extern int
242190
pg_sprintf(char *str, const char *fmt,...)
243191
/* This extension allows gcc to check the format string */
@@ -252,6 +200,26 @@ pg_printf(const char *fmt,...)
252200
/* This extension allows gcc to check the format string */
253201
__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
254202

203+
/*
204+
* The GCC-specific code below prevents the __attribute__(... 'printf')
205+
* above from being replaced, and this is required because gcc doesn't
206+
* know anything about pg_printf.
207+
*/
208+
#ifdef __GNUC__
209+
#define vsnprintf(...) pg_vsnprintf(__VA_ARGS__)
210+
#define snprintf(...) pg_snprintf(__VA_ARGS__)
211+
#define sprintf(...) pg_sprintf(__VA_ARGS__)
212+
#define vfprintf(...) pg_vfprintf(__VA_ARGS__)
213+
#define fprintf(...) pg_fprintf(__VA_ARGS__)
214+
#define printf(...) pg_printf(__VA_ARGS__)
215+
#else
216+
#define vsnprintf pg_vsnprintf
217+
#define snprintf pg_snprintf
218+
#define sprintf pg_sprintf
219+
#define vfprintf pg_vfprintf
220+
#define fprintf pg_fprintf
221+
#define printf pg_printf
222+
#endif
255223
#endif /* USE_REPL_SNPRINTF */
256224

257225
#if defined(WIN32)

src/interfaces/ecpg/compatlib/Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ submake-pgtypeslib:
4545
# Shared library stuff
4646
include $(top_srcdir)/src/Makefile.shlib
4747

48-
# XXX This library uses no symbols from snprintf.c.
4948
snprintf.c: % : $(top_srcdir)/src/port/%
5049
rm -f $@ && $(LN_S) $< .
5150

src/interfaces/ecpg/ecpglib/.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,4 @@
77
/path.c
88
/pgstrcasecmp.c
99
/strlcpy.c
10-
/syswrap.c
1110
/thread.c

src/interfaces/ecpg/ecpglib/Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ override CFLAGS += $(PTHREAD_CFLAGS)
2525
LIBS := $(filter-out -lpgport, $(LIBS))
2626

2727
OBJS= execute.o typename.o descriptor.o sqlda.o data.o error.o prepare.o memory.o \
28-
connect.o misc.o path.o pgstrcasecmp.o syswrap.o \
28+
connect.o misc.o path.o pgstrcasecmp.o \
2929
$(filter snprintf.o strlcpy.o win32setlocale.o isinf.o, $(LIBOBJS))
3030

3131
# thread.c is needed only for non-WIN32 implementation of path.c
@@ -57,7 +57,7 @@ include $(top_srcdir)/src/Makefile.shlib
5757
# necessarily use the same object files as the backend uses. Instead,
5858
# symlink the source files in here and build our own object file.
5959

60-
path.c pgstrcasecmp.c snprintf.c strlcpy.c syswrap.c thread.c win32setlocale.c isinf.c: % : $(top_srcdir)/src/port/%
60+
path.c pgstrcasecmp.c snprintf.c strlcpy.c thread.c win32setlocale.c isinf.c: % : $(top_srcdir)/src/port/%
6161
rm -f $@ && $(LN_S) $< .
6262

6363
misc.o: misc.c $(top_builddir)/src/port/pg_config_paths.h
@@ -74,6 +74,6 @@ uninstall: uninstall-lib
7474

7575
clean distclean: clean-lib
7676
rm -f $(OBJS)
77-
rm -f path.c pgstrcasecmp.c snprintf.c strlcpy.c syswrap.c thread.c win32setlocale.c
77+
rm -f path.c pgstrcasecmp.c snprintf.c strlcpy.c thread.c win32setlocale.c
7878

7979
maintainer-clean: distclean maintainer-clean-lib

src/interfaces/ecpg/pgtypeslib/.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,3 @@
55
/exports.list
66

77
/pgstrcasecmp.c
8-
/syswrap.c

src/interfaces/ecpg/pgtypeslib/Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ SHLIB_LINK += -lm
2929
SHLIB_EXPORTS = exports.txt
3030

3131
OBJS= numeric.o datetime.o common.o dt_common.o timestamp.o interval.o \
32-
pgstrcasecmp.o syswrap.o \
32+
pgstrcasecmp.o \
3333
$(filter rint.o snprintf.o, $(LIBOBJS))
3434

3535
all: all-lib
@@ -42,7 +42,7 @@ include $(top_srcdir)/src/Makefile.shlib
4242
# necessarily use the same object files as the backend uses. Instead,
4343
# symlink the source files in here and build our own object file.
4444

45-
pgstrcasecmp.c rint.c snprintf.c syswrap.c: % : $(top_srcdir)/src/port/%
45+
pgstrcasecmp.c rint.c snprintf.c: % : $(top_srcdir)/src/port/%
4646
rm -f $@ && $(LN_S) $< .
4747

4848
install: all installdirs install-lib
@@ -52,6 +52,6 @@ installdirs: installdirs-lib
5252
uninstall: uninstall-lib
5353

5454
clean distclean: clean-lib
55-
rm -f $(OBJS) pgstrcasecmp.c rint.c snprintf.c syswrap.c
55+
rm -f $(OBJS) pgstrcasecmp.c rint.c snprintf.c
5656

5757
maintainer-clean: distclean maintainer-clean-lib

src/interfaces/libpq/.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
/snprintf.c
1212
/strerror.c
1313
/strlcpy.c
14-
/syswrap.c
1514
/thread.c
1615
/win32error.c
1716
/win32setlocale.c

src/interfaces/libpq/Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ OBJS= fe-auth.o fe-connect.o fe-exec.o fe-misc.o fe-print.o fe-lobj.o \
3535
fe-protocol2.o fe-protocol3.o pqexpbuffer.o pqsignal.o fe-secure.o \
3636
libpq-events.o
3737
# libpgport C files we always use
38-
OBJS += chklocale.o inet_net_ntop.o noblock.o pgstrcasecmp.o syswrap.o thread.o
38+
OBJS += chklocale.o inet_net_ntop.o noblock.o pgstrcasecmp.o thread.o
3939
# libpgport C files that are needed if identified by configure
4040
OBJS += $(filter crypt.o getaddrinfo.o getpeereid.o inet_aton.o open.o snprintf.o strerror.o strlcpy.o win32error.o win32setlocale.o, $(LIBOBJS))
4141
# backend/libpq
@@ -88,7 +88,7 @@ backend_src = $(top_srcdir)/src/backend
8888
# For some libpgport modules, this only happens if configure decides
8989
# the module is needed (see filter hack in OBJS, above).
9090

91-
chklocale.c crypt.c getaddrinfo.c getpeereid.c inet_aton.c inet_net_ntop.c noblock.c open.c pgsleep.c pgstrcasecmp.c snprintf.c strerror.c strlcpy.c syswrap.c thread.c win32error.c win32setlocale.c: % : $(top_srcdir)/src/port/%
91+
chklocale.c crypt.c getaddrinfo.c getpeereid.c inet_aton.c inet_net_ntop.c noblock.c open.c pgsleep.c pgstrcasecmp.c snprintf.c strerror.c strlcpy.c thread.c win32error.c win32setlocale.c: % : $(top_srcdir)/src/port/%
9292
rm -f $@ && $(LN_S) $< .
9393

9494
ip.c md5.c: % : $(backend_src)/libpq/%
@@ -145,7 +145,7 @@ clean distclean: clean-lib
145145
# Might be left over from a Win32 client-only build
146146
rm -f pg_config_paths.h
147147
rm -f inet_net_ntop.c noblock.c pgstrcasecmp.c thread.c
148-
rm -f chklocale.c crypt.c getaddrinfo.c getpeereid.c inet_aton.c open.c snprintf.c strerror.c strlcpy.c syswrap.c win32error.c win32setlocale.c
148+
rm -f chklocale.c crypt.c getaddrinfo.c getpeereid.c inet_aton.c open.c snprintf.c strerror.c strlcpy.c win32error.c win32setlocale.c
149149
rm -f pgsleep.c
150150
rm -f md5.c ip.c
151151
rm -f encnames.c wchar.c

src/interfaces/libpq/bcc32.mak

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,6 @@ CLEAN :
106106
-@erase "$(INTDIR)\dirmod.obj"
107107
-@erase "$(INTDIR)\pgsleep.obj"
108108
-@erase "$(INTDIR)\open.obj"
109-
-@erase "$(INTDIR)\syswrap.obj"
110109
-@erase "$(INTDIR)\win32error.obj"
111110
-@erase "$(OUTDIR)\$(OUTFILENAME).lib"
112111
-@erase "$(OUTDIR)\$(OUTFILENAME)dll.lib"
@@ -150,7 +149,6 @@ LIB32_OBJS= \
150149
"$(INTDIR)\dirmod.obj" \
151150
"$(INTDIR)\pgsleep.obj" \
152151
"$(INTDIR)\open.obj" \
153-
"$(INTDIR)\syswrap.obj" \
154152
"$(INTDIR)\win32error.obj" \
155153
"$(INTDIR)\pthread-win32.obj"
156154

@@ -289,11 +287,6 @@ LINK32_FLAGS = -Gn -L$(BCB)\lib;$(INTDIR); -x -Tpd -v
289287
$(CPP_PROJ) /I"." ..\..\port\open.c
290288
<<
291289

292-
"$(INTDIR)\syswrap.obj" : ..\..\port\syswrap.c
293-
$(CPP) @<<
294-
$(CPP_PROJ) ..\..\port\syswrap.c
295-
<<
296-
297290
"$(INTDIR)\win32error.obj" : ..\..\port\win32error.c
298291
$(CPP) @<<
299292
$(CPP_PROJ) /I"." ..\..\port\win32error.c

src/interfaces/libpq/win32.mak

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,6 @@ CLEAN :
113113
-@erase "$(INTDIR)\dirmod.obj"
114114
-@erase "$(INTDIR)\pgsleep.obj"
115115
-@erase "$(INTDIR)\open.obj"
116-
-@erase "$(INTDIR)\syswrap.obj"
117116
-@erase "$(INTDIR)\win32error.obj"
118117
-@erase "$(INTDIR)\win32setlocale.obj"
119118
-@erase "$(OUTDIR)\$(OUTFILENAME).lib"
@@ -160,7 +159,6 @@ LIB32_OBJS= \
160159
"$(INTDIR)\dirmod.obj" \
161160
"$(INTDIR)\pgsleep.obj" \
162161
"$(INTDIR)\open.obj" \
163-
"$(INTDIR)\syswrap.obj" \
164162
"$(INTDIR)\win32error.obj" \
165163
"$(INTDIR)\win32setlocale.obj" \
166164
"$(INTDIR)\pthread-win32.obj"
@@ -329,11 +327,6 @@ LINK32_OBJS= \
329327
$(CPP_PROJ) /I"." ..\..\port\open.c
330328
<<
331329

332-
"$(INTDIR)\syswrap.obj" : ..\..\port\syswrap.c
333-
$(CPP) @<<
334-
$(CPP_PROJ) ..\..\port\syswrap.c
335-
<<
336-
337330
"$(INTDIR)\win32error.obj" : ..\..\port\win32error.c
338331
$(CPP) @<<
339332
$(CPP_PROJ) /I"." ..\..\port\win32error.c

src/pl/plperl/plperl.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,10 @@
3939
* So we undefine them here and redefine them after it's done its dirty deed.
4040
*/
4141

42+
#ifdef USE_REPL_SNPRINTF
4243
#undef snprintf
4344
#undef vsnprintf
45+
#endif
4446

4547

4648
/* required for perl API */
@@ -49,19 +51,21 @@
4951
#include "XSUB.h"
5052

5153
/* put back our snprintf and vsnprintf */
54+
#ifdef USE_REPL_SNPRINTF
5255
#ifdef snprintf
5356
#undef snprintf
5457
#endif
5558
#ifdef vsnprintf
5659
#undef vsnprintf
5760
#endif
5861
#ifdef __GNUC__
59-
#define vsnprintf(...) vsnprintf_throw_on_fail(__VA_ARGS__)
60-
#define snprintf(...) snprintf_throw_on_fail(__VA_ARGS__)
62+
#define vsnprintf(...) pg_vsnprintf(__VA_ARGS__)
63+
#define snprintf(...) pg_snprintf(__VA_ARGS__)
6164
#else
62-
#define vsnprintf vsnprintf_throw_on_fail
63-
#define snprintf snprintf_throw_on_fail
65+
#define vsnprintf pg_vsnprintf
66+
#define snprintf pg_snprintf
6467
#endif /* __GNUC__ */
68+
#endif /* USE_REPL_SNPRINTF */
6569

6670
/* perl version and platform portability */
6771
#define NEED_eval_pv

src/port/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ LIBS += $(PTHREAD_LIBS)
3232

3333
OBJS = $(LIBOBJS) chklocale.o dirmod.o exec.o inet_net_ntop.o noblock.o \
3434
path.o pgcheckdir.o pgmkdirp.o pgsleep.o pgstrcasecmp.o \
35-
qsort.o qsort_arg.o sprompt.o syswrap.o thread.o
35+
qsort.o qsort_arg.o sprompt.o thread.o
3636

3737
# foo_srv.o and foo.o are both built from foo.c, but only foo.o has -DFRONTEND
3838
OBJS_SRV = $(OBJS:%.o=%_srv.o)

src/port/snprintf.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@
9999
/* Prevent recursion */
100100
#undef vsnprintf
101101
#undef snprintf
102-
#undef vsprintf
103102
#undef sprintf
104103
#undef vfprintf
105104
#undef fprintf
@@ -176,7 +175,7 @@ pg_snprintf(char *str, size_t count, const char *fmt,...)
176175
return len;
177176
}
178177

179-
int
178+
static int
180179
pg_vsprintf(char *str, const char *fmt, va_list args)
181180
{
182181
PrintfTarget target;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy