Hi, On Mon, Oct 22, 2018 at 6:22 AM Lev Stipakov <lstipa...@gmail.com> wrote: > > From: Lev Stipakov <l...@openvpn.net> > > Every call to swprintf is followed by line which adds nul terminator. This > patch > introduces openvpn_swprintf() which guarantees nul termination for size > 0. > > Same approach as for snprintf / openvpn_snprintf. > > Signed-off-by: Lev Stipakov <l...@openvpn.net> > --- > v3: > - add missing function declaration > - fix indentation > > v2: > - rebase on top of master > > src/openvpn/buffer.c | 17 +++++++++++++++++ > src/openvpn/buffer.h | 11 +++++++++++ > src/openvpn/tun.c | 3 +-- > src/openvpnserv/common.c | 15 +++++++++++++++ > src/openvpnserv/interactive.c | 26 ++++++++++---------------- > src/openvpnserv/service.h | 2 ++ > src/openvpnserv/validate.c | 3 +-- > 7 files changed, 57 insertions(+), 20 deletions(-) > > diff --git a/src/openvpn/buffer.c b/src/openvpn/buffer.c > index 80fbb75..8ca189f 100644 > --- a/src/openvpn/buffer.c > +++ b/src/openvpn/buffer.c > @@ -37,6 +37,8 @@ > > #include "memdbg.h" > > +#include <wchar.h> > + > size_t > array_mult_safe(const size_t m1, const size_t m2, const size_t extra) > { > @@ -308,6 +310,21 @@ openvpn_snprintf(char *str, size_t size, const char > *format, ...) > return (len >= 0 && len < size); > } > > +bool > +openvpn_swprintf(wchar_t *const str, const size_t size, const wchar_t *const > format, ...) > +{ > + va_list arglist; > + int len = -1; > + if (size > 0) > + { > + va_start(arglist, format); > + len = vswprintf(str, size, format, arglist); > + va_end(arglist); > + str[size - 1] = L'\0'; > + } > + return (len >= 0 && len < size); > +} > + > /* > * write a string to the end of a buffer that was > * truncated by buf_printf > diff --git a/src/openvpn/buffer.h b/src/openvpn/buffer.h > index aab249f..c5b78a0 100644 > --- a/src/openvpn/buffer.h > +++ b/src/openvpn/buffer.h > @@ -448,6 +448,17 @@ __attribute__ ((format(__printf__, 3, 4))) > #endif > ; > > + > +/* > + * Like swprintf but guarantees null termination for size > 0 > + */ > +bool > +openvpn_swprintf(wchar_t *const str, const size_t size, const wchar_t *const > format, ...); > +/* > + * Unlike in openvpn_snprintf, we cannot use format attributes since > + * GCC doesn't support wprintf as archetype. > + */ > + > /* > * remove/add trailing characters > */ > diff --git a/src/openvpn/tun.c b/src/openvpn/tun.c > index 948fd17..c091401 100644 > --- a/src/openvpn/tun.c > +++ b/src/openvpn/tun.c > @@ -4472,8 +4472,7 @@ get_adapter_index_method_1(const char *guid) > DWORD index; > ULONG aindex; > wchar_t wbuf[256]; > - swprintf(wbuf, SIZE(wbuf), L"\\DEVICE\\TCPIP_%S", guid); > - wbuf [SIZE(wbuf) - 1] = 0; > + openvpn_swprintf(wbuf, SIZE(wbuf), L"\\DEVICE\\TCPIP_%S", guid); > if (GetAdapterIndex(wbuf, &aindex) != NO_ERROR) > { > index = TUN_ADAPTER_INDEX_INVALID; > diff --git a/src/openvpnserv/common.c b/src/openvpnserv/common.c > index 33a8097..fd51776 100644 > --- a/src/openvpnserv/common.c > +++ b/src/openvpnserv/common.c > @@ -57,6 +57,21 @@ openvpn_sntprintf(LPTSTR str, size_t size, LPCTSTR format, > ...) > return res; > } > > +BOOL > +openvpn_swprintf(wchar_t *const str, const size_t size, const wchar_t *const > format, ...) > +{ > + va_list arglist; > + int len = -1; > + if (size > 0) > + { > + va_start(arglist, format); > + len = vswprintf(str, size, format, arglist); > + va_end(arglist); > + str[size - 1] = L'\0'; > + } > + return (len >= 0 && len < size); > +} > + > static DWORD > GetRegString(HKEY key, LPCTSTR value, LPTSTR data, DWORD size, LPCTSTR > default_value) > { > diff --git a/src/openvpnserv/interactive.c b/src/openvpnserv/interactive.c > index 4a571f5..2dc152c 100644 > --- a/src/openvpnserv/interactive.c > +++ b/src/openvpnserv/interactive.c > @@ -276,8 +276,7 @@ ReturnProcessId(HANDLE pipe, DWORD pid, DWORD count, > LPHANDLE events) > * Same format as error messages (3 line string) with error = 0 in > * 0x%08x format, PID on line 2 and a description "Process ID" on line 3 > */ > - swprintf(buf, _countof(buf), L"0x%08x\n0x%08x\n%s", 0, pid, msg); > - buf[_countof(buf) - 1] = '\0'; > + openvpn_swprintf(buf, _countof(buf), L"0x%08x\n0x%08x\n%s", 0, pid, msg); > > WritePipeAsync(pipe, buf, (DWORD)(wcslen(buf) * 2), count, events); > } > @@ -402,9 +401,8 @@ ValidateOptions(HANDLE pipe, const WCHAR *workdir, const > WCHAR *options) > > if (!CheckOption(workdir, 2, argv_tmp, &settings)) > { > - swprintf(buf, _countof(buf), msg1, argv[0], workdir, > - settings.ovpn_admin_group); > - buf[_countof(buf) - 1] = L'\0'; > + openvpn_swprintf(buf, _countof(buf), msg1, argv[0], workdir, > + settings.ovpn_admin_group); > ReturnError(pipe, ERROR_STARTUP_DATA, buf, 1, &exit_event); > } > goto out; > @@ -421,16 +419,14 @@ ValidateOptions(HANDLE pipe, const WCHAR *workdir, > const WCHAR *options) > { > if (wcscmp(L"--config", argv[i]) == 0 && argc-i > 1) > { > - swprintf(buf, _countof(buf), msg1, argv[i+1], workdir, > - settings.ovpn_admin_group); > - buf[_countof(buf) - 1] = L'\0'; > + openvpn_swprintf(buf, _countof(buf), msg1, argv[i+1], > workdir, > + settings.ovpn_admin_group); > ReturnError(pipe, ERROR_STARTUP_DATA, buf, 1, &exit_event); > } > else > { > - swprintf(buf, _countof(buf), msg2, argv[i], > - settings.ovpn_admin_group); > - buf[_countof(buf) - 1] = L'\0'; > + openvpn_swprintf(buf, _countof(buf), msg2, argv[i], > + settings.ovpn_admin_group); > ReturnError(pipe, ERROR_STARTUP_DATA, buf, 1, &exit_event); > } > goto out; > @@ -950,8 +946,7 @@ RegisterDNS(LPVOID unused) > > HANDLE wait_handles[2] = {rdns_semaphore, exit_event}; > > - swprintf(ipcfg, _countof(ipcfg), L"%s\\%s", get_win_sys_path(), > L"ipconfig.exe"); > - ipcfg[_countof(ipcfg) - 1] = L'\0'; > + openvpn_swprintf(ipcfg, MAX_PATH, L"%s\\%s", get_win_sys_path(), > L"ipconfig.exe"); > > if (WaitForMultipleObjects(2, wait_handles, FALSE, timeout) == > WAIT_OBJECT_0) > { > @@ -1628,9 +1623,8 @@ RunOpenvpn(LPVOID p) > else if (exit_code != 0) > { > WCHAR buf[256]; > - swprintf(buf, _countof(buf), > - L"OpenVPN exited with error: exit code = %lu", exit_code); > - buf[_countof(buf) - 1] = L'\0'; > + openvpn_swprintf(buf, _countof(buf), > + L"OpenVPN exited with error: exit code = %lu", > exit_code); > ReturnError(pipe, ERROR_OPENVPN_STARTUP, buf, 1, &exit_event); > } > Undo(&undo_lists); > diff --git a/src/openvpnserv/service.h b/src/openvpnserv/service.h > index d7b7b3f..cb7020f 100644 > --- a/src/openvpnserv/service.h > +++ b/src/openvpnserv/service.h > @@ -86,6 +86,8 @@ BOOL openvpn_vsntprintf(LPTSTR str, size_t size, LPCTSTR > format, va_list arglist > > BOOL openvpn_sntprintf(LPTSTR str, size_t size, LPCTSTR format, ...); > > +BOOL openvpn_swprintf(wchar_t *const str, const size_t size, const wchar_t > *const format, ...); > + > DWORD GetOpenvpnSettings(settings_t *s); > > BOOL ReportStatusToSCMgr(SERVICE_STATUS_HANDLE service, SERVICE_STATUS > *status); > diff --git a/src/openvpnserv/validate.c b/src/openvpnserv/validate.c > index c576ac1..5506e90 100644 > --- a/src/openvpnserv/validate.c > +++ b/src/openvpnserv/validate.c > @@ -68,8 +68,7 @@ CheckConfigPath(const WCHAR *workdir, const WCHAR *fname, > const settings_t *s) > /* convert fname to full path */ > if (PathIsRelativeW(fname) ) > { > - swprintf(tmp, _countof(tmp), L"%s\\%s", workdir, fname); > - tmp[_countof(tmp)-1] = L'\0'; > + openvpn_swprintf(tmp, _countof(tmp), L"%s\\%s", workdir, fname); > config_file = tmp; > } > else
Acked-by: Selva Nair <selva.n...@gmail.com> _______________________________________________ Openvpn-devel mailing list Openvpn-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openvpn-devel