Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1334127

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 b3288a6 commit 1334127

File tree

16 files changed

+53
-251
lines changed

16 files changed

+53
-251
lines changed

src/include/port.h

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

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

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

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

258226
#if defined(WIN32)

src/interfaces/ecpg/compatlib/Makefile

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

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

src/interfaces/ecpg/ecpglib/.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,4 @@
55
/path.c
66
/pgstrcasecmp.c
77
/strlcpy.c
8-
/syswrap.c
98
/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
@@ -59,7 +59,7 @@ include $(top_srcdir)/src/Makefile.shlib
5959
# necessarily use the same object files as the backend uses. Instead,
6060
# symlink the source files in here and build our own object file.
6161

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

6565
misc.o: misc.c $(top_builddir)/src/port/pg_config_paths.h
@@ -76,6 +76,6 @@ uninstall: uninstall-lib
7676

7777
clean distclean: clean-lib
7878
rm -f $(OBJS)
79-
rm -f path.c pgstrcasecmp.c snprintf.c strlcpy.c syswrap.c thread.c win32setlocale.c
79+
rm -f path.c pgstrcasecmp.c snprintf.c strlcpy.c thread.c win32setlocale.c
8080

8181
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
@@ -3,4 +3,3 @@
33
/exports.list
44

55
/pgstrcasecmp.c
6-
/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
@@ -12,7 +12,6 @@
1212
/snprintf.c
1313
/strerror.c
1414
/strlcpy.c
15-
/syswrap.c
1615
/thread.c
1716
/win32error.c
1817
/win32setlocale.c

src/interfaces/libpq/Makefile

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

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

9595
ip.c md5.c: % : $(backend_src)/libpq/%
@@ -150,7 +150,7 @@ clean distclean: clean-lib
150150
# Might be left over from a Win32 client-only build
151151
rm -f pg_config_paths.h
152152
rm -f inet_net_ntop.c noblock.c pgstrcasecmp.c pqsignal.c thread.c
153-
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
153+
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
154154
rm -f pgsleep.c
155155
rm -f md5.c ip.c
156156
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

@@ -297,11 +295,6 @@ LINK32_FLAGS = -Gn -L$(BCB)\lib;$(INTDIR); -x -Tpd -v
297295
$(CPP_PROJ) /I"." ..\..\port\open.c
298296
<<
299297

300-
"$(INTDIR)\syswrap.obj" : ..\..\port\syswrap.c
301-
$(CPP) @<<
302-
$(CPP_PROJ) ..\..\port\syswrap.c
303-
<<
304-
305298
"$(INTDIR)\win32error.obj" : ..\..\port\win32error.c
306299
$(CPP) @<<
307300
$(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"
@@ -337,11 +335,6 @@ LINK32_OBJS= \
337335
$(CPP_PROJ) /I"." ..\..\port\open.c
338336
<<
339337

340-
"$(INTDIR)\syswrap.obj" : ..\..\port\syswrap.c
341-
$(CPP) @<<
342-
$(CPP_PROJ) ..\..\port\syswrap.c
343-
<<
344-
345338
"$(INTDIR)\win32error.obj" : ..\..\port\win32error.c
346339
$(CPP) @<<
347340
$(CPP_PROJ) /I"." ..\..\port\win32error.c

0 commit comments

Comments
 (0)