Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix buffer overflow in wcstombs_s() function #59

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/Windows/hsflowd/hsflowd.c
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ static bool initialiseProgramDataFiles(HSP *sp, wchar_t *programDataDir)
myLog(LOG_ERR, "initialiseProgramDataFiles: cannot open VM store file %S\n", vmStoreFile);
return false;
} else {
int cHandle = _open_osfhandle((long)fileHandle, _O_RDWR | _O_TEXT);
int cHandle = _open_osfhandle((intptr_t)fileHandle, _O_RDWR | _O_TEXT);
sp->f_vmStore = _fdopen(cHandle, "r+t");
}
fnLen = dirLen+wcslen(HSP_DEFAULT_PORTSTORE)+1;
Expand All @@ -459,7 +459,7 @@ static bool initialiseProgramDataFiles(HSP *sp, wchar_t *programDataDir)
myLog(LOG_ERR, "initialiseProgramDataFiles: cannot open VM store file %S\n", portStoreFile);
return false;
} else {
int cHandle = _open_osfhandle((long)fileHandle, _O_RDWR | _O_TEXT);
int cHandle = _open_osfhandle((intptr_t)fileHandle, _O_RDWR | _O_TEXT);
sp->f_portStore = _fdopen(cHandle, "r+t");
}
return true;
Expand Down Expand Up @@ -510,6 +510,7 @@ void main(int argc, char *argv[])
usage(argv[0]);
}
}

SERVICE_TABLE_ENTRY ServiceTable[2];
ServiceTable[0].lpServiceName = HSP_SERVICE_NAME;
ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
Expand Down Expand Up @@ -574,7 +575,7 @@ void ServiceMain(int argc, char** argv)
if (isService && *programDataDir != NULL) {
//set the log file name to the default.
size_t dirLen = 0;
if (0 == wcstombs_s(&dirLen, mbcLogFilename, MAX_PATH, programDataDir, wcslen(programDataDir))) {
if (0 == wcstombs_s(&dirLen, mbcLogFilename, MAX_PATH, programDataDir, _TRUNCATE)) {
PathAppend(mbcLogFilename, HSP_DEFAULT_LOGFILE);
logFilename = mbcLogFilename;
} else {
Expand Down
9 changes: 5 additions & 4 deletions src/Windows/hsflowd/hsflowd.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,20 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings" />
Expand Down Expand Up @@ -206,6 +206,7 @@
</ResourceCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\sflow\sflow_notifier.c" />
<ClCompile Include="hypervSwitch.c" />
<ClCompile Include="hypervUtil.c" />
<ClCompile Include="hypervVm.c" />
Expand Down
3 changes: 3 additions & 0 deletions src/Windows/hsflowd/hsflowd.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@
<ClCompile Include=".\dnsSD.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\sflow\sflow_notifier.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="hsflowd.h">
Expand Down
10 changes: 5 additions & 5 deletions src/Windows/hsflowd/hypervVm.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,19 +141,19 @@ BOOL readXmlInstance(IXmlReader *xmlReader, SFLHost_hid_counters *hid,
while (readXmlProperty(xmlReader, &nameVal, &dataVal)) {
if (nameVal != NULL) {
if (wcscmp(nameVal, XML_FQDN) == 0) {
wcstombs_s(&hnLen, hnamebuf, hnamebufLen, dataVal, wcslen(dataVal));
wcstombs_s(&hnLen, hnamebuf, hnamebufLen, dataVal, _TRUNCATE);
//don't count the NULL
if (hnLen > 0) {
hnLen--;
}
} else if (wcscmp(nameVal, XML_OSNAME) == 0) {
} else if (wcscmp(nameVal, XML_OSNAME) == 0) {
if (StrStrIW(dataVal, L"Windows") != NULL) {
osName = SFLOS_windows;
} else if (StrStrIW(dataVal, L"Linux") != NULL) {
osName = SFLOS_linux;
}
} else if (wcscmp(nameVal, XML_OSVERSION) == 0) {
wcstombs_s(&osrLen, osrelbuf, osrelbufLen, dataVal, wcslen(dataVal));
wcstombs_s(&osrLen, osrelbuf, osrelbufLen, dataVal, _TRUNCATE);
//don't count the NULL
if (osrLen > 0) {
osrLen--;
Expand Down Expand Up @@ -326,8 +326,8 @@ static void readVmHidCounters(HVSVmState *state, SFLHost_hid_counters *hid,
hid->hostname.str = "";
hid->hostname.len = 0;
} else {
size_t hnLen;
wcstombs_s(&hnLen, hnamebuf, hnamebufLen, punycode, wcslen(punycode));
size_t hnLen = 0;
wcstombs_s(&hnLen, hnamebuf, hnamebufLen, punycode, _TRUNCATE);
if (hnLen > 0) {
hnLen--;
}
Expand Down
44 changes: 35 additions & 9 deletions src/Windows/hsflowd/readHidCounters.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ extern "C" {
#endif

#include "hsflowd.h"
#include <VersionHelpers.h>

/**
* Populates the host_descr structure with, computer name for hostname,
Expand All @@ -30,17 +31,42 @@ void readHidCounters(HSP *sp, SFLHost_hid_counters *hid){

hid->os_name = SFLOS_windows;

if (GetComputerNameExA(ComputerNameDnsHostname, dnsBuf, &dnsLen)) {
uint32_t copyLen = dnsLen < SFL_MAX_HOSTNAME_CHARS ? dnsLen : SFL_MAX_HOSTNAME_CHARS;
memcpy(hid->hostname.str, dnsBuf, copyLen);
hid->hostname.str[copyLen] = '\0';
hid->hostname.len = copyLen;
}

hid->os_name = SFLOS_windows;

ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
dwRes = GetVersionEx(&osvi);
if (dwRes){
sprintf_s(hid->os_release.str, SFL_MAX_OSRELEASE_CHARS,"%d.%d.%d %s",
osvi.dwMajorVersion,
osvi.dwMinorVersion,
osvi.dwBuildNumber,
osvi.szCSDVersion);
hid->os_release.len = (uint32_t)strnlen(hid->os_release.str, SFL_MAX_OSRELEASE_CHARS);
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

if (IsWindows10OrGreater()) {
sprintf_s(hid->os_release.str, SFL_MAX_OSRELEASE_CHARS, "%s", "Windows 10 or later");
}
else if (IsWindows8Point1OrGreater()) {
sprintf_s(hid->os_release.str, SFL_MAX_OSRELEASE_CHARS, "%s", "Windows 8.1 or later");
}
else if (IsWindows8OrGreater()) {
sprintf_s(hid->os_release.str, SFL_MAX_OSRELEASE_CHARS, "%s", "Windows 8 or later");
}
else if (IsWindows7SP1OrGreater()) {
sprintf_s(hid->os_release.str, SFL_MAX_OSRELEASE_CHARS, "%s", "Windows 7 SP1 or later");
}
else if (IsWindowsVistaSP2OrGreater()) {
sprintf_s(hid->os_release.str, SFL_MAX_OSRELEASE_CHARS, "%s", "Windows Vista SP2 or later");
}
else {
sprintf_s(hid->os_release.str, SFL_MAX_OSRELEASE_CHARS, "%d.%d.%d %s",
osvi.dwMajorVersion,
osvi.dwMinorVersion,
osvi.dwBuildNumber,
osvi.szCSDVersion);
}

hid->os_release.len = (uint32_t)strnlen(hid->os_release.str, SFL_MAX_OSRELEASE_CHARS);

GetNativeSystemInfo(&si);
hid->machine_type = SFLMT_unknown;
Expand Down
6 changes: 3 additions & 3 deletions src/Windows/hsflowd/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ void *UTHeapQNew(size_t len)
utRealm.bufferLists[queueIdx] = utBuf->nxt;
} else {
// allocate a new one
utBuf = (UTHeapHeader *)my_os_calloc(1<<queueIdx);
utBuf = (UTHeapHeader*)my_os_calloc(static_cast<size_t>(1) << queueIdx);
utRealm.totalAllocatedBytes += (1<<queueIdx);
}
// remember the details so we know what to do on free (overwriting the nxt pointer)
Expand Down Expand Up @@ -225,7 +225,7 @@ void UTHeapQFree(void *buf)
// reference count reached zero, so it's time to free this buffer for real
// read the queue index before we overwrite it
uint16_t queueIdx = utBuf->h.queueIdx;
memset(utBuf, 0, 1 << queueIdx);
memset(utBuf, 0, static_cast<size_t>(1) << queueIdx);
// put it back on the queue
utBuf->nxt = (UTHeapHeader *)(utRealm.bufferLists[queueIdx]);
utRealm.bufferLists[queueIdx] = utBuf;
Expand Down Expand Up @@ -325,7 +325,7 @@ char *my_wcstombs(wchar_t *wcstr)
{
size_t wcslen = 1+wcsnlen_s(wcstr, UT_DEFAULT_MAX_STRLEN);
char *str = (char *)my_calloc(wcslen * sizeof(char));
size_t numConverted;
size_t numConverted = 0;
wcstombs_s(&numConverted, str, wcslen, wcstr, wcslen);
return str;
}
Expand Down
12 changes: 6 additions & 6 deletions src/Windows/installHelper/installHelper.vcxproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\version.targets" />
<ItemGroup Label="ProjectConfigurations">
<Import Project="..\version.targets" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
Expand Down Expand Up @@ -31,26 +31,26 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
Expand Down
8 changes: 4 additions & 4 deletions src/Windows/installer/installer.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -31,26 +31,26 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='win-debug|Win32'" Label="Configuration">
<ConfigurationType>Utility</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='win-debug|x64'" Label="Configuration">
<ConfigurationType>Utility</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='win|Win32'" Label="Configuration">
<ConfigurationType>Utility</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='win|x64'" Label="Configuration">
<ConfigurationType>Utility</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
Expand Down
11 changes: 10 additions & 1 deletion src/sflow/sflow.h
Original file line number Diff line number Diff line change
Expand Up @@ -839,7 +839,16 @@ typedef struct _SFLHost_par_counters {
uint32_t dsIndex; /* sFlowDataSource index */
} SFLHost_par_counters;

#define SFL_MAX_HOSTNAME_CHARS 64
/*
* From RFC1035
*
* 2.3.4. Size limits
* names 255 octets or less
*
* 3.1. Name space definitions
* To simplify implementations, the total length of a domain name (i.e., label octets and label length octets) is restricted to 255 octets or less.
*/
#define SFL_MAX_HOSTNAME_CHARS 255
#define SFL_MAX_OSRELEASE_CHARS 32

typedef struct _SFLHost_hid_counters {
Expand Down
2 changes: 1 addition & 1 deletion src/sflow/sflow_agent.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ void sfl_agent_set_address(SFLAgent *agent, SFLAddress *ip)

uint32_t sfl_agent_uptime_mS(SFLAgent *agent)
{
return ((agent->now - agent->bootTime) * 1000) + (agent->now_nS / 1000000);
return static_cast<uint32_t>((static_cast<uint64_t>(agent->now - agent->bootTime) * 1000) + (agent->now_nS / 1000000));
}

/*_________________---------------------------__________________
Expand Down
2 changes: 1 addition & 1 deletion src/sflow/sflow_notifier.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ void sfl_notifier_writeEventSample(SFLNotifier *notifier, SFLEvent_discarded_pac
es->sequence_number = ++notifier->seqNo;
/* copy the other header fields in - event samples always use expanded form */
es->ds_class = SFL_DS_CLASS(notifier->dsi);
es->ds_index = notifier->ds_alias ?: SFL_DS_INDEX(notifier->dsi);
es->ds_index = notifier->ds_alias ? notifier->ds_alias : SFL_DS_INDEX(notifier->dsi);
/* send to my receiver */
if(notifier->myReceiver)
sfl_receiver_writeEventSample(notifier->myReceiver, es);
Expand Down
2 changes: 1 addition & 1 deletion src/sflow/sflow_poller.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ void sfl_poller_writeCountersSample(SFLPoller *poller, SFL_COUNTERS_SAMPLE_TYPE
/* fill in the rest of the header fields, and send to the receiver */
cs->sequence_number = ++poller->countersSampleSeqNo;
uint32_t ds_class = SFL_DS_CLASS(poller->dsi);
uint32_t ds_index = poller->ds_alias ?: SFL_DS_INDEX(poller->dsi);
uint32_t ds_index = poller->ds_alias ? poller->ds_alias : SFL_DS_INDEX(poller->dsi);
#ifdef SFL_USE_32BIT_INDEX
cs->ds_class = ds_class;
cs->ds_index = ds_index;
Expand Down
6 changes: 3 additions & 3 deletions src/sflow/sflow_receiver.c
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,7 @@ static int computeFlowSampleElementsSize(SFLReceiver *receiver, SFLFlow_sample_e
{
SFLFlow_sample_element *elem;
uint32_t elemSiz;
uint siz = 4; /* num_elements */
int siz = 4; /* num_elements */
uint32_t num_elements = 0;
for(elem = elements; elem != NULL; elem = elem->nxt) {
num_elements++;
Expand Down Expand Up @@ -883,7 +883,7 @@ int sfl_receiver_writeFlowSample(SFLReceiver *receiver, SFL_FLOW_SAMPLE_TYPE *fs
}

// sanity check
int dgramSize = ((u_char *)receiver->sampleCollector.datap - (u_char *)receiver->sampleCollector.data);
int64_t dgramSize = ((u_char *)receiver->sampleCollector.datap - (u_char *)receiver->sampleCollector.data);
assert(dgramSize - receiver->sampleCollector.pktlen == packedSize);

// update the pktlen
Expand Down Expand Up @@ -959,7 +959,7 @@ int sfl_receiver_writeEventSample(SFLReceiver *receiver, SFLEvent_discarded_pack
}

// sanity check
int dgramSize = ((u_char *)receiver->sampleCollector.datap - (u_char *)receiver->sampleCollector.data);
int64_t dgramSize = ((u_char *)receiver->sampleCollector.datap - (u_char *)receiver->sampleCollector.data);
assert(dgramSize - receiver->sampleCollector.pktlen == packedSize);

// update the pktlen
Expand Down
2 changes: 1 addition & 1 deletion src/sflow/sflow_sampler.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ void sfl_sampler_writeFlowSample(SFLSampler *sampler, SFL_FLOW_SAMPLE_TYPE *fs)
fs->sequence_number = ++sampler->flowSampleSeqNo;
/* copy the other header fields in */
uint32_t ds_class = SFL_DS_CLASS(sampler->dsi);
uint32_t ds_index = sampler->ds_alias ?: SFL_DS_INDEX(sampler->dsi);
uint32_t ds_index = sampler->ds_alias ? sampler->ds_alias : SFL_DS_INDEX(sampler->dsi);
#ifdef SFL_USE_32BIT_INDEX
fs->ds_class = ds_class;
fs->ds_index = ds_index;
Expand Down