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

Commit16304a0

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 parentcac18a7 commit16304a0

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
@@ -126,12 +126,11 @@ extern unsigned char pg_tolower(unsigned char ch);
126126
externunsignedcharpg_ascii_toupper(unsignedcharch);
127127
externunsignedcharpg_ascii_tolower(unsignedcharch);
128128

129-
#ifdefUSE_REPL_SNPRINTF
130-
131129
/*
132-
* Versions of libintl >= 0.13 try to replace printf() and friends with
133-
* macros to their own versions that understand the %$ format. We do the
134-
* same, so disable their macros, if they exist.
130+
* Capture macro-compatible calls to printf() and friends, and redirect them
131+
* to wrappers that throw errors in lieu of reporting failure in a return
132+
* value. Versions of libintl >= 0.13 similarly redirect to versions that
133+
* understand the %$ format, so disable libintl macros first.
135134
*/
136135
#ifdefvsnprintf
137136
#undef vsnprintf
@@ -155,36 +154,63 @@ extern unsigned char pg_ascii_tolower(unsigned char ch);
155154
#undef printf
156155
#endif
157156

158-
externintpg_vsnprintf(char*str,size_tcount,constchar*fmt,va_listargs);
159-
externintpg_snprintf(char*str,size_tcount,constchar*fmt,...)pg_attribute_printf(3,4);
160-
externintpg_vsprintf(char*str,constchar*fmt,va_listargs);
161-
externintpg_sprintf(char*str,constchar*fmt,...)pg_attribute_printf(2,3);
162-
externintpg_vfprintf(FILE*stream,constchar*fmt,va_listargs);
163-
externintpg_fprintf(FILE*stream,constchar*fmt,...)pg_attribute_printf(2,3);
164-
externintpg_printf(constchar*fmt,...)pg_attribute_printf(1,2);
157+
externint
158+
vsnprintf_throw_on_fail(char*str,size_tcount,constchar*fmt,va_listargs)
159+
pg_attribute_printf(3,0);
160+
externint
161+
snprintf_throw_on_fail(char*str,size_tcount,constchar*fmt,...)
162+
pg_attribute_printf(3,4);
163+
externint
164+
vsprintf_throw_on_fail(char*str,constchar*fmt,va_listargs)
165+
pg_attribute_printf(2,0);
166+
externint
167+
sprintf_throw_on_fail(char*str,constchar*fmt,...)
168+
pg_attribute_printf(2,3);
169+
externint
170+
vfprintf_throw_on_fail(FILE*stream,constchar*fmt,va_listargs)
171+
pg_attribute_printf(2,0);
172+
externint
173+
fprintf_throw_on_fail(FILE*stream,constchar*fmt,...)
174+
pg_attribute_printf(2,3);
175+
externint
176+
printf_throw_on_fail(constchar*fmt,...)
177+
pg_attribute_printf(1,2);
165178

166179
/*
167180
*The GCC-specific code below prevents the pg_attribute_printf above from
168181
*being replaced, and this is required because gcc doesn't know anything
169-
*aboutpg_printf.
182+
*aboutprintf_throw_on_fail.
170183
*/
171184
#ifdef__GNUC__
172-
#definevsnprintf(...)pg_vsnprintf(__VA_ARGS__)
173-
#definesnprintf(...)pg_snprintf(__VA_ARGS__)
174-
#definevsprintf(...)pg_vsprintf(__VA_ARGS__)
175-
#definesprintf(...)pg_sprintf(__VA_ARGS__)
176-
#definevfprintf(...)pg_vfprintf(__VA_ARGS__)
177-
#definefprintf(...)pg_fprintf(__VA_ARGS__)
178-
#defineprintf(...)pg_printf(__VA_ARGS__)
185+
#definevsnprintf(...)vsnprintf_throw_on_fail(__VA_ARGS__)
186+
#definesnprintf(...)snprintf_throw_on_fail(__VA_ARGS__)
187+
#definevsprintf(...)vsprintf_throw_on_fail(__VA_ARGS__)
188+
#definesprintf(...)sprintf_throw_on_fail(__VA_ARGS__)
189+
#definevfprintf(...)vfprintf_throw_on_fail(__VA_ARGS__)
190+
#definefprintf(...)fprintf_throw_on_fail(__VA_ARGS__)
191+
#defineprintf(...)printf_throw_on_fail(__VA_ARGS__)
179192
#else
180-
#definevsnprintfpg_vsnprintf
181-
#definesnprintfpg_snprintf
182-
#definevsprintfpg_vsprintf
183-
#definesprintfpg_sprintf
184-
#definevfprintfpg_vfprintf
185-
#definefprintfpg_fprintf
186-
#defineprintfpg_printf
193+
#definevsnprintfvsnprintf_throw_on_fail
194+
#definesnprintfsnprintf_throw_on_fail
195+
#definevsprintfvsprintf_throw_on_fail
196+
#definesprintfsprintf_throw_on_fail
197+
#definevfprintfvfprintf_throw_on_fail
198+
#definefprintffprintf_throw_on_fail
199+
#defineprintfprintf_throw_on_fail
187200
#endif
201+
202+
#ifdefUSE_REPL_SNPRINTF
203+
204+
/* Code outside syswrap.c should not call these. */
205+
206+
externintpg_vsnprintf(char*str,size_tcount,constchar*fmt,va_listargs);
207+
externintpg_snprintf(char*str,size_tcount,constchar*fmt,...)pg_attribute_printf(3,4);
208+
externintpg_vsprintf(char*str,constchar*fmt,va_listargs);
209+
externintpg_sprintf(char*str,constchar*fmt,...)pg_attribute_printf(2,3);
210+
externintpg_vfprintf(FILE*stream,constchar*fmt,va_listargs);
211+
externintpg_fprintf(FILE*stream,constchar*fmt,...)pg_attribute_printf(2,3);
212+
externintpg_printf(constchar*fmt,...)pg_attribute_printf(1,2);
213+
188214
#endif/* USE_REPL_SNPRINTF */
189215

190216
#if defined(WIN32)

‎src/interfaces/ecpg/compatlib/Makefile

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

51+
# XXX This library uses no symbols from snprintf.c.
5152
snprintf.c:% :$(top_srcdir)/src/port/%
5253
rm -f$@&&$(LN_S)$<.
5354

‎src/interfaces/ecpg/ecpglib/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
/pgstrcasecmp.c
66
/snprintf.c
77
/strlcpy.c
8+
/syswrap.c
89
/thread.c
910
/win32setlocale.c
1011
/isinf.c

‎src/interfaces/ecpg/ecpglib/Makefile

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

2828
OBJS= execute.o typename.o descriptor.o sqlda.o data.o error.o prepare.o memory.o\
29-
connect.o misc.o path.o pgstrcasecmp.o\
29+
connect.o misc.o path.o pgstrcasecmp.osyswrap.o\
3030
$(filter snprintf.o strlcpy.o win32setlocale.o isinf.o,$(LIBOBJS))$(WIN32RES)
3131

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

58-
path.cpgstrcasecmp.csnprintf.cstrlcpy.cthread.cwin32setlocale.cisinf.c:% :$(top_srcdir)/src/port/%
58+
path.cpgstrcasecmp.csnprintf.cstrlcpy.csyswrap.cthread.cwin32setlocale.cisinf.c:% :$(top_srcdir)/src/port/%
5959
rm -f$@&&$(LN_S)$<.
6060

6161
misc.o: misc.c$(top_builddir)/src/port/pg_config_paths.h
@@ -72,6 +72,6 @@ uninstall: uninstall-lib
7272

7373
cleandistclean: clean-lib
7474
rm -f$(OBJS)
75-
rm -f path.c pgstrcasecmp.c snprintf.c strlcpy.c thread.c win32setlocale.c isinf.c
75+
rm -f path.c pgstrcasecmp.c snprintf.c strlcpy.csyswrap.cthread.c win32setlocale.c isinf.c
7676

7777
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
@@ -4,3 +4,4 @@
44
/pgstrcasecmp.c
55
/rint.c
66
/snprintf.c
7+
/syswrap.c

‎src/interfaces/ecpg/pgtypeslib/Makefile

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

3232
OBJS= numeric.o datetime.o common.o dt_common.o timestamp.o interval.o\
33-
pgstrcasecmp.o\
33+
pgstrcasecmp.osyswrap.o\
3434
$(filter rint.o snprintf.o,$(LIBOBJS))$(WIN32RES)
3535

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

46-
pgstrcasecmp.crint.csnprintf.c:% :$(top_srcdir)/src/port/%
46+
pgstrcasecmp.crint.csnprintf.csyswrap.c:% :$(top_srcdir)/src/port/%
4747
rm -f$@&&$(LN_S)$<.
4848

4949
install: all installdirs install-lib
@@ -53,6 +53,6 @@ installdirs: installdirs-lib
5353
uninstall: uninstall-lib
5454

5555
cleandistclean: clean-lib
56-
rm -f$(OBJS) pgstrcasecmp.c rint.c snprintf.c
56+
rm -f$(OBJS) pgstrcasecmp.c rint.c snprintf.c syswrap.c
5757

5858
maintainer-clean: distclean maintainer-clean-lib

‎src/interfaces/libpq/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
/strerror.c
1414
/strlcpy.c
1515
/system.c
16+
/syswrap.c
1617
/thread.c
1718
/win32error.c
1819
/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-
thread.o
39+
syswrap.othread.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 system.o snprintf.o strerror.o strlcpy.o win32error.o win32setlocale.o,$(LIBOBJS))
4242
# backend/libpq
@@ -93,7 +93,7 @@ backend_src = $(top_srcdir)/src/backend
9393
# For some libpgport modules, this only happens if configure decides
9494
# the module is needed (see filter hack in OBJS, above).
9595

96-
chklocale.ccrypt.cgetaddrinfo.cgetpeereid.cinet_aton.cinet_net_ntop.cnoblock.copen.csystem.cpgsleep.cpgstrcasecmp.cpqsignal.csnprintf.cstrerror.cstrlcpy.cthread.cwin32error.cwin32setlocale.c:% :$(top_srcdir)/src/port/%
96+
chklocale.ccrypt.cgetaddrinfo.cgetpeereid.cinet_aton.cinet_net_ntop.cnoblock.copen.csystem.cpgsleep.cpgstrcasecmp.cpqsignal.csnprintf.cstrerror.cstrlcpy.csyswrap.cthread.cwin32error.cwin32setlocale.c:% :$(top_srcdir)/src/port/%
9797
rm -f$@&&$(LN_S)$<.
9898

9999
ip.cmd5.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 pqsignal.c thread.c
148-
rm -f chklocale.c crypt.c getaddrinfo.c getpeereid.c inet_aton.c open.c system.c snprintf.c strerror.c strlcpy.c win32error.c win32setlocale.c
148+
rm -f chklocale.c crypt.c getaddrinfo.c getpeereid.c inet_aton.c open.c system.c snprintf.c strerror.c strlcpy.csyswrap.cwin32error.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: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ CLEAN :
107107
-@erase"$(INTDIR)\pgsleep.obj"
108108
-@erase"$(INTDIR)\open.obj"
109109
-@erase"$(INTDIR)\system.obj"
110+
-@erase"$(INTDIR)\syswrap.obj"
110111
-@erase"$(INTDIR)\win32error.obj"
111112
-@erase"$(OUTDIR)\$(OUTFILENAME).lib"
112113
-@erase"$(OUTDIR)\$(OUTFILENAME)dll.lib"
@@ -151,6 +152,7 @@ LIB32_OBJS= \
151152
"$(INTDIR)\pgsleep.obj"\
152153
"$(INTDIR)\open.obj"\
153154
"$(INTDIR)\system.obj"\
155+
"$(INTDIR)\syswrap.obj"\
154156
"$(INTDIR)\win32error.obj"\
155157
"$(INTDIR)\pthread-win32.obj"
156158

@@ -302,6 +304,11 @@ LINK32_FLAGS = -Gn -L$(BCB)\lib;$(INTDIR); -x -Tpd -v
302304
$(CPP_PROJ) /I"." ..\..\port\system.c
303305
<<
304306

307+
"$(INTDIR)\syswrap.obj" : ..\..\port\syswrap.c
308+
$(CPP) @<<
309+
$(CPP_PROJ) ..\..\port\syswrap.c
310+
<<
311+
305312
"$(INTDIR)\win32error.obj" : ..\..\port\win32error.c
306313
$(CPP) @<<
307314
$(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
@@ -114,6 +114,7 @@ CLEAN :
114114
-@erase"$(INTDIR)\pgsleep.obj"
115115
-@erase"$(INTDIR)\open.obj"
116116
-@erase"$(INTDIR)\system.obj"
117+
-@erase"$(INTDIR)\syswrap.obj"
117118
-@erase"$(INTDIR)\win32error.obj"
118119
-@erase"$(INTDIR)\win32setlocale.obj"
119120
-@erase"$(OUTDIR)\$(OUTFILENAME).lib"
@@ -164,6 +165,7 @@ LIB32_OBJS= \
164165
"$(INTDIR)\pgsleep.obj"\
165166
"$(INTDIR)\open.obj"\
166167
"$(INTDIR)\system.obj"\
168+
"$(INTDIR)\syswrap.obj"\
167169
"$(INTDIR)\win32error.obj"\
168170
"$(INTDIR)\win32setlocale.obj"\
169171
"$(INTDIR)\pthread-win32.obj"
@@ -348,6 +350,11 @@ LINK32_OBJS= \
348350
$(CPP_PROJ) /I"." ..\..\port\system.c
349351
<<
350352

353+
"$(INTDIR)\syswrap.obj" : ..\..\port\syswrap.c
354+
$(CPP) @<<
355+
$(CPP_PROJ) ..\..\port\syswrap.c
356+
<<
357+
351358
"$(INTDIR)\win32error.obj" : ..\..\port\win32error.c
352359
$(CPP) @<<
353360
$(CPP_PROJ) /I"." ..\..\port\win32error.c

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp