310 likes | 329 Views
Writing safer code with the Visual C++ 8.0 Libraries. Martyn Lovell Visual C++ Libraries Microsoft Corporation. Agenda. Overview Current Situation Security Problems Library impact Summary Q&A. Overview. The Visual C++ Team is creating new secure libraries in Whidbey
E N D
Writing safer code with the Visual C++ 8.0 Libraries Martyn Lovell Visual C++ Libraries Microsoft Corporation Confidential
Agenda • Overview • Current Situation • Security Problems • Library impact • Summary • Q&A Confidential
Overview • The Visual C++ Team is creating new secure libraries in Whidbey • Traditional, unsafe functions will be deprecated • strcpy • unchecked C++ iterators • New, safe alternatives will be provided for them • Over 400 in all • This presentation covers • Rationale and goals • Overview of the new functions • Examples of usage • Call to Action Confidential
Libraries History • Standard C Library initially evolved with Unix™ • Starting in 1970s • Public networking uncommon • Machines simpler, more constrained • First C language/library standard codified existing practice • High degree of compatibility with current use • Core set of required functions for C programmers • Everything has now changed • Much code that was previously unimportant now vulnerable to attack • Assume every software component might be attacked Confidential
Issues addressed • Interface problems • Function shape is dangerous • New function needed • Definition problems • Function requirements are dangerous • Existing function can change • Implementation problems • Need to implement existing definition better Confidential
Standards impact • Many of our functions come from standards • ISO C, C++ • We are taking these changes to the standards bodies • Already taken draft to C committee • Extremely positive response • Our changes extend far beyond the standard functions • _makepath as well as printf Confidential
Key security problems • Buffer overruns • Error reporting & validation • Parameter validation • File access rights • Static buffer results • File paths & permissions • Temporary files • Process creation • Stack overflow • Math Confidential
Work done before Version 8 • Visual C++ 7.1 includes great library security work • Implementations reviewed and improved • These changes were also ported to the system/VC6 CRT (msvcrt.dll) for W2k3 • These changes focused on doing the best possible job while not breaking compatibility • Our new effort takes things to the next level • We are willing to deprecate strcpy • This involves more pain for you • The cost of migration is larger • The potential gains are much larger Confidential
Interface problems • Lack of buffer size • gets • Lack of error return • Continue after error can be attackable • Callback context needed • Avoid static variables • Safe for reentrancy, threads • qsort, bsearch Confidential
Interface problems • Never use static result buffers • Can overrun • tmpnam Confidential
Definition problems • Returning unterminated strings • Predictable, but hard to get right • strncpy, sprintf • Need better math support • Multiply with overflow • Add functions for this • Likely for Orcas Confidential
Implementation problems • Parameter validation • Ensure errors reported • Provide way to catch errors • We will have handler function • assert in “debug” build • Stack usage • Avoid excessive usage • Stack overflow can be a denial of service attack Confidential
Implementation problems • File permissions • Create temporary files safely • Create all files by default with good permissions • Scanf • No totally safe way to implement this • Require passing buffer sizes • Long file path support • Don’t fail when given extended paths • Windows specific Confidential
Implementation Problems • Stack usage • Don’t absorb stack with alloca calls • Process creation • Don’t leak unnecessary permissions into child • Unchecked C++ iterators • Can allow walking past end of array Confidential
Insecure Functions Deprecation • Give the developer option to deprecate insecure functions • Deprecate by default • __declspec(deprecate) in VC++ • Causes a compiler warning • Allow deprecation to be removed • Using a #define • Makes us secure by default Confidential
Example function • Old: • size_t mbstowcs(wchar_t *wcstr, const char *mbstr, size_t count); • New: • errcode mbstowcs_s(size_t *pConvertedMBChars,wchar_t *wcstr, size_t sizeInWords, const char *mbstr, size_t count); Confidential
// Original wchar_t dest[20]; wcscpy(dest, src); wcscat(dest, L“ ...”); wprintf(L"%s", dest); // Basic remediation wchar_t dest[20]; wcscpy_s(dest, _countof(dest), src); wcscat_s(dest, _countof(dest), L“ ...”); wprintf(L"%s", dest); // Abort if we don't fit // assumes 20 really is a // good size Example code change Confidential
// Original wchar_t dest[20]; wcscpy(dest, src); wcscat(dest, L“ ...”); wprintf(L"%s", dest); // better wchar_t dest[SRC_SIZE+ELLIPSIS_SIZE]; wcscpy_s(dest, _countof(dest), src); wcscat_s(dest, _countof(dest), L“ ...”); wprintf(L"%s", dest); // Now we know we can fit // if SRC_SIZE is right Version 2 Confidential
// Original wchar_t dest[20]; wcscpy(dest, src); wcscat(dest, L“ ...”); wprintf(L"%s", dest); // Perhaps we don't know size wchar_t *dest=NULL; size_t len = wcslen(src) + (sizeof(L" ...")/ sizeof(wchar_t)); dest=_malloca(len); if(!dest) return E_FAIL; wcscpy_s(dest, len, src); wcscat_s(dest, len, L“ ...”); wprintf(L"%s", dest); _freea(dest); dest=NULL; // Assumes no exceptions Version 3 Confidential
// Original wchar_t dest[20]; wcscpy(dest, src); wcscat(dest, L“ ...”); wprintf(L"%s", dest); // Perhaps we are // actually C++ users and // have time for bigger // change std::wstringdest(src); dest+=L" ..."; cout << dest; Version 4 Confidential
Error Handling • Error return • C library error return is bad • errno widely detested • Easy to ignore errors • Hard to write prefast rules • New functions • return errno_t to indicate error - easy static analysis • Still set errno too • If you pass us an invalid parameter • We initiate watson and abort the process • This ensures bad data is never propagated • Previous code would have crashed or overrun in most of these cases • You can install your own handler • But we always end up aborting, to avoid an attack vector Confidential
Other design issues • Can’t check strings • Input strings are assumed to be NUL terminated • No way to validate • Use strnlen if you need some help in this area • All function pointers now stored using new OS function ::EncodePointer • Added at our request • Stops some kinds of second-stage attacks • scanf_s • We added extra parameters for lengths • Each usage requires more careful changes Confidential
C++ Library Changes • C++ Library • More abstracted • More modern • Requires less change • Optimised for minimal abstraction penalty • Now default to secure • Iterators are checked • Can’t operate directly on arrays of unknown size • Minimal source change required in general Confidential
// Original void helloworld(void) { wchar_t text[]=L"Hello world"; wchar_t buffer[20]=L""; std::copy( text, text+_countof(text), buffer ); // compiler warning std::wcout << buffer; } // simple remediation void helloworld2(void) { wchar_t text[]=L"Hello world"; wchar_t buffer[20]=L""; stdext::checked_array_iterator <wchar_t *> dest( buffer,_countof(buffer)); std::copy( text, text+_countof(text), dest); std::wcout << buffer; } C++ Example change Confidential
// Bug caught at run time void pointless(wchar_t *output, const wchar_t * src) { std::wstring str(L"Hello world"); std::wstring::iterator iter=str.begin(); for(int i=0; i<20; i++) { *iter=L'a'; // bug, runtime check invoked iter++; } } C++ Runtime check Confidential
Summary & Call to Action • Time to make the standard libraries secure • Help developers move their code forward to secure practices • Use this library in your code to help you build more secure C and C++ code • Not a Silver Bullet! Confidential
Questions? • Ask me anything about Visual Studio 8 • Follow-up: • MartynL@microsoft.com Confidential
Backup Confidential
Scope of changes • Most functions change implementation • For validation • For quality of implementation issues • >2000 functions change in some way • 37 standard functions have some interface shape change • Not time to review them all here • Details in my paper proposal • List on next page • >400 non-standard functions changing • When printf changes, so does whole family Confidential
Standard Functions changing • bsearch, qsort • Pass context • tmpnam, getenv, strtok, ctime • Don’t use static state • fgets, gets, vsprintf, strerror, strncat. Wcsncat, strncpy, wcsncpy, wcstombs, mbstowcs, strcat, strcpy, wcscat, wcscpy • Buffer size Confidential
Standard Functions changing • memcpy, wmemcpy, memmove, wmemmove • Separate dest size • fscanf, scanf, wscanf, sscanf, swscanf • scanf family problems • setbuf, sprintf • Deprecate • Better versions already in standard • _malloca • Does not use stack for large alloc • Requires call to _freea Confidential