Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit82b7393

Browse files
committed
Add error-throwing wrappers for the printf family of functions.
All known standard library implementations of these functions can failwith ENOMEM. A caller neglecting to check for failure would experiencemissing output, information exposure, or a crash. Check return valueswithin wrappers and code, currently just snprintf.c, that bypasses thewrappers. The wrappers do not return after an error, so their callersneed not check. Back-patch to 9.0 (all supported versions).Popular free software standard library implementations do take pains tobypass malloc() in simple cases, but they risk ENOMEM for floating pointnumbers, positional arguments, large field widths, and large precisions.No specification demands such caution, so this commit regards every callto a printf family function as a potential threat.Injecting the wrappers implicitly is a compromise between patch scopeand design goals. I would prefer to edit each call site to name awrapper explicitly. libpq and the ECPG libraries would, ideally, conveyerrors to the caller rather than abort(). All that would be painfullyinvasive for a back-patched security fix, hence this compromise.Security:CVE-2015-3166
1 parent1e6652a commit82b7393

File tree

16 files changed

+300
-93
lines changed

16 files changed

+300
-93
lines changed

‎src/include/port.h

Lines changed: 53 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -156,12 +156,11 @@ extern unsigned char pg_tolower(unsigned char ch);
156156
externunsignedcharpg_ascii_toupper(unsignedcharch);
157157
externunsignedcharpg_ascii_tolower(unsignedcharch);
158158

159-
#ifdefUSE_REPL_SNPRINTF
160-
161159
/*
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.
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.
165164
*/
166165
#ifdefvsnprintf
167166
#undef vsnprintf
@@ -185,6 +184,55 @@ extern unsigned char pg_ascii_tolower(unsigned char ch);
185184
#undef printf
186185
#endif
187186

187+
externint
188+
vsnprintf_throw_on_fail(char*str,size_tcount,constchar*fmt,va_listargs)
189+
__attribute__((format(PG_PRINTF_ATTRIBUTE,3,0)));
190+
externint
191+
snprintf_throw_on_fail(char*str,size_tcount,constchar*fmt,...)
192+
__attribute__((format(PG_PRINTF_ATTRIBUTE,3,4)));
193+
externint
194+
vsprintf_throw_on_fail(char*str,constchar*fmt,va_listargs)
195+
__attribute__((format(PG_PRINTF_ATTRIBUTE,2,0)));
196+
externint
197+
sprintf_throw_on_fail(char*str,constchar*fmt,...)
198+
__attribute__((format(PG_PRINTF_ATTRIBUTE,2,3)));
199+
externint
200+
vfprintf_throw_on_fail(FILE*stream,constchar*fmt,va_listargs)
201+
__attribute__((format(PG_PRINTF_ATTRIBUTE,2,0)));
202+
externint
203+
fprintf_throw_on_fail(FILE*stream,constchar*fmt,...)
204+
__attribute__((format(PG_PRINTF_ATTRIBUTE,2,3)));
205+
externint
206+
printf_throw_on_fail(constchar*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+
#definevsnprintf(...)vsnprintf_throw_on_fail(__VA_ARGS__)
216+
#definesnprintf(...)snprintf_throw_on_fail(__VA_ARGS__)
217+
#definevsprintf(...)vsprintf_throw_on_fail(__VA_ARGS__)
218+
#definesprintf(...)sprintf_throw_on_fail(__VA_ARGS__)
219+
#definevfprintf(...)vfprintf_throw_on_fail(__VA_ARGS__)
220+
#definefprintf(...)fprintf_throw_on_fail(__VA_ARGS__)
221+
#defineprintf(...)printf_throw_on_fail(__VA_ARGS__)
222+
#else
223+
#definevsnprintfvsnprintf_throw_on_fail
224+
#definesnprintfsnprintf_throw_on_fail
225+
#definevsprintfvsprintf_throw_on_fail
226+
#definesprintfsprintf_throw_on_fail
227+
#definevfprintfvfprintf_throw_on_fail
228+
#definefprintffprintf_throw_on_fail
229+
#defineprintfprintf_throw_on_fail
230+
#endif
231+
232+
#ifdefUSE_REPL_SNPRINTF
233+
234+
/* Code outside syswrap.c should not call these. */
235+
188236
externintpg_vsnprintf(char*str,size_tcount,constchar*fmt,va_listargs);
189237
externint
190238
pg_snprintf(char*str,size_tcount,constchar*fmt,...)
@@ -205,28 +253,6 @@ pg_printf(const char *fmt,...)
205253
/* This extension allows gcc to check the format string */
206254
__attribute__((format(PG_PRINTF_ATTRIBUTE,1,2)));
207255

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 pg_printf.
212-
*/
213-
#ifdef__GNUC__
214-
#definevsnprintf(...)pg_vsnprintf(__VA_ARGS__)
215-
#definesnprintf(...)pg_snprintf(__VA_ARGS__)
216-
#definevsprintf(...)pg_vsprintf(__VA_ARGS__)
217-
#definesprintf(...)pg_sprintf(__VA_ARGS__)
218-
#definevfprintf(...)pg_vfprintf(__VA_ARGS__)
219-
#definefprintf(...)pg_fprintf(__VA_ARGS__)
220-
#defineprintf(...)pg_printf(__VA_ARGS__)
221-
#else
222-
#definevsnprintfpg_vsnprintf
223-
#definesnprintfpg_snprintf
224-
#definevsprintfpg_vsprintf
225-
#definesprintfpg_sprintf
226-
#definevfprintfpg_vfprintf
227-
#definefprintfpg_fprintf
228-
#defineprintfpg_printf
229-
#endif
230256
#endif/* USE_REPL_SNPRINTF */
231257

232258
#if defined(WIN32)

‎src/interfaces/ecpg/compatlib/Makefile

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

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

‎src/interfaces/ecpg/ecpglib/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@
55
/path.c
66
/pgstrcasecmp.c
77
/strlcpy.c
8+
/syswrap.c
89
/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\
28+
connect.o misc.o path.o pgstrcasecmp.osyswrap.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.cpgstrcasecmp.csnprintf.cstrlcpy.cthread.cwin32setlocale.cisinf.c:% :$(top_srcdir)/src/port/%
60+
path.cpgstrcasecmp.csnprintf.cstrlcpy.csyswrap.cthread.cwin32setlocale.cisinf.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
cleandistclean: clean-lib
7676
rm -f$(OBJS)
77-
rm -f path.c pgstrcasecmp.c snprintf.c strlcpy.c thread.c win32setlocale.c
77+
rm -f path.c pgstrcasecmp.c snprintf.c strlcpy.csyswrap.cthread.c win32setlocale.c
7878

7979
maintainer-clean: distclean maintainer-clean-lib

‎src/interfaces/ecpg/pgtypeslib/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
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\
32+
pgstrcasecmp.osyswrap.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.crint.csnprintf.c:% :$(top_srcdir)/src/port/%
45+
pgstrcasecmp.crint.csnprintf.csyswrap.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
cleandistclean: clean-lib
55-
rm -f$(OBJS) pgstrcasecmp.c rint.c snprintf.c
55+
rm -f$(OBJS) pgstrcasecmp.c rint.c snprintf.c syswrap.c
5656

5757
maintainer-clean: distclean maintainer-clean-lib

‎src/interfaces/libpq/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
/snprintf.c
1212
/strerror.c
1313
/strlcpy.c
14+
/syswrap.c
1415
/thread.c
1516
/win32error.c
1617
/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 thread.o
38+
OBJS += chklocale.o inet_net_ntop.o noblock.o pgstrcasecmp.osyswrap.othread.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.ccrypt.cgetaddrinfo.cgetpeereid.cinet_aton.cinet_net_ntop.cnoblock.copen.cpgsleep.cpgstrcasecmp.csnprintf.cstrerror.cstrlcpy.cthread.cwin32error.cwin32setlocale.c:% :$(top_srcdir)/src/port/%
91+
chklocale.ccrypt.cgetaddrinfo.cgetpeereid.cinet_aton.cinet_net_ntop.cnoblock.copen.cpgsleep.cpgstrcasecmp.csnprintf.cstrerror.cstrlcpy.csyswrap.cthread.cwin32error.cwin32setlocale.c:% :$(top_srcdir)/src/port/%
9292
rm -f$@&&$(LN_S)$<.
9393

9494
ip.cmd5.c:% :$(backend_src)/libpq/%
@@ -149,7 +149,7 @@ clean distclean: clean-lib
149149
# Might be left over from a Win32 client-only build
150150
rm -f pg_config_paths.h
151151
rm -f inet_net_ntop.c noblock.c pgstrcasecmp.c thread.c
152-
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
152+
rm -f chklocale.c crypt.c getaddrinfo.c getpeereid.c inet_aton.c open.c snprintf.c strerror.c strlcpy.csyswrap.cwin32error.c win32setlocale.c
153153
rm -f pgsleep.c
154154
rm -f md5.c ip.c
155155
rm -f encnames.c wchar.c

‎src/interfaces/libpq/bcc32.mak

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ CLEAN :
106106
-@erase"$(INTDIR)\dirmod.obj"
107107
-@erase"$(INTDIR)\pgsleep.obj"
108108
-@erase"$(INTDIR)\open.obj"
109+
-@erase"$(INTDIR)\syswrap.obj"
109110
-@erase"$(INTDIR)\win32error.obj"
110111
-@erase"$(OUTDIR)\$(OUTFILENAME).lib"
111112
-@erase"$(OUTDIR)\$(OUTFILENAME)dll.lib"
@@ -149,6 +150,7 @@ LIB32_OBJS= \
149150
"$(INTDIR)\dirmod.obj"\
150151
"$(INTDIR)\pgsleep.obj"\
151152
"$(INTDIR)\open.obj"\
153+
"$(INTDIR)\syswrap.obj"\
152154
"$(INTDIR)\win32error.obj"\
153155
"$(INTDIR)\pthread-win32.obj"
154156

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

292+
"$(INTDIR)\syswrap.obj" : ..\..\port\syswrap.c
293+
$(CPP) @<<
294+
$(CPP_PROJ) ..\..\port\syswrap.c
295+
<<
296+
290297
"$(INTDIR)\win32error.obj" : ..\..\port\win32error.c
291298
$(CPP) @<<
292299
$(CPP_PROJ) /I"." ..\..\port\win32error.c

‎src/interfaces/libpq/win32.mak

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ CLEAN :
113113
-@erase"$(INTDIR)\dirmod.obj"
114114
-@erase"$(INTDIR)\pgsleep.obj"
115115
-@erase"$(INTDIR)\open.obj"
116+
-@erase"$(INTDIR)\syswrap.obj"
116117
-@erase"$(INTDIR)\win32error.obj"
117118
-@erase"$(INTDIR)\win32setlocale.obj"
118119
-@erase"$(OUTDIR)\$(OUTFILENAME).lib"
@@ -159,6 +160,7 @@ LIB32_OBJS= \
159160
"$(INTDIR)\dirmod.obj"\
160161
"$(INTDIR)\pgsleep.obj"\
161162
"$(INTDIR)\open.obj"\
163+
"$(INTDIR)\syswrap.obj"\
162164
"$(INTDIR)\win32error.obj"\
163165
"$(INTDIR)\win32setlocale.obj"\
164166
"$(INTDIR)\pthread-win32.obj"
@@ -327,6 +329,11 @@ LINK32_OBJS= \
327329
$(CPP_PROJ) /I"." ..\..\port\open.c
328330
<<
329331

332+
"$(INTDIR)\syswrap.obj" : ..\..\port\syswrap.c
333+
$(CPP) @<<
334+
$(CPP_PROJ) ..\..\port\syswrap.c
335+
<<
336+
330337
"$(INTDIR)\win32error.obj" : ..\..\port\win32error.c
331338
$(CPP) @<<
332339
$(CPP_PROJ) /I"." ..\..\port\win32error.c

‎src/pl/plperl/plperl.h

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

42-
#ifdefUSE_REPL_SNPRINTF
4342
#undef snprintf
4443
#undef vsnprintf
45-
#endif
4644

4745

4846
/* required for perl API */
@@ -51,21 +49,19 @@
5149
#include"XSUB.h"
5250

5351
/* put back our snprintf and vsnprintf */
54-
#ifdefUSE_REPL_SNPRINTF
5552
#ifdefsnprintf
5653
#undef snprintf
5754
#endif
5855
#ifdefvsnprintf
5956
#undef vsnprintf
6057
#endif
6158
#ifdef__GNUC__
62-
#definevsnprintf(...)pg_vsnprintf(__VA_ARGS__)
63-
#definesnprintf(...)pg_snprintf(__VA_ARGS__)
59+
#definevsnprintf(...)vsnprintf_throw_on_fail(__VA_ARGS__)
60+
#definesnprintf(...)snprintf_throw_on_fail(__VA_ARGS__)
6461
#else
65-
#definevsnprintfpg_vsnprintf
66-
#definesnprintfpg_snprintf
62+
#definevsnprintfvsnprintf_throw_on_fail
63+
#definesnprintfsnprintf_throw_on_fail
6764
#endif/* __GNUC__ */
68-
#endif/* USE_REPL_SNPRINTF */
6965

7066
/* perl version and platform portability */
7167
#defineNEED_eval_pv

‎src/pl/plpython/plpython.h

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

38-
#ifdefUSE_REPL_SNPRINTF
3938
#undef snprintf
4039
#undef vsnprintf
41-
#endif
4240

4341
#if defined(_MSC_VER)&& defined(_DEBUG)
4442
/* Python uses #pragma to bring in a non-default libpython on VC++ if
@@ -124,21 +122,19 @@ typedef int Py_ssize_t;
124122
#include<eval.h>
125123

126124
/* put back our snprintf and vsnprintf */
127-
#ifdefUSE_REPL_SNPRINTF
128125
#ifdefsnprintf
129126
#undef snprintf
130127
#endif
131128
#ifdefvsnprintf
132129
#undef vsnprintf
133130
#endif
134131
#ifdef__GNUC__
135-
#definevsnprintf(...)pg_vsnprintf(__VA_ARGS__)
136-
#definesnprintf(...)pg_snprintf(__VA_ARGS__)
132+
#definevsnprintf(...)vsnprintf_throw_on_fail(__VA_ARGS__)
133+
#definesnprintf(...)snprintf_throw_on_fail(__VA_ARGS__)
137134
#else
138-
#definevsnprintfpg_vsnprintf
139-
#definesnprintfpg_snprintf
135+
#definevsnprintfvsnprintf_throw_on_fail
136+
#definesnprintfsnprintf_throw_on_fail
140137
#endif/* __GNUC__ */
141-
#endif/* USE_REPL_SNPRINTF */
142138

143139
/*
144140
* Used throughout, and also by the Python 2/3 porting layer, so it's easier to

‎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 erand48.o exec.o fls.o inet_net_ntop.o\
3434
noblock.o path.o pgcheckdir.o pg_crc.o pgmkdirp.o pgsleep.o\
35-
pgstrcasecmp.o qsort.o qsort_arg.o sprompt.o thread.o
35+
pgstrcasecmp.o qsort.o qsort_arg.o sprompt.osyswrap.othread.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)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp