Ticket #39658

mingwrt 5.2.2 does not expose function rand_s?

Open Date: 2019-10-06 21:50 Last Update: 2019-10-12 21:12

Reporter:
Owner:
(None)
Type:
Status:
Open
Component:
MileStone:
(None)
Priority:
5 - Medium
Severity:
5 - Medium
Resolution:
None
File:
1
Vote
Score: 0
No votes
0.0% (0/0)
0.0% (0/0)

Details

Hi!

Windows introduced function rand_s some time and while I find mention of it in MinGW's msvcrt-xref.pdf I cannot find a signature for it in mingwrt 5.2.2 headers. Are there plans to add a prototype to MinGW? We're about to define a prototype in https://github.com/libexpat/libexpat/pull/356/files for MinGW in Expat ourselves now but it seems like the real fix would be to have it in MinGW for everyone — what do you think?

On a side note, msvcrt-xref.pdf says that rand_s is not contained in Windows XP but contained in Windows Vista an after. The way I read the MS docs they imply availability in Windows XP but it might be wishful thinking — if you know for sure, I'd be interested in more details.

Thanks and best, Sebastian

Ticket History (3/10 Histories)

2019-10-06 21:50 Updated by: sping
  • New Ticket "w32api 5.2.2 does not expose function rand_s?" created
2019-10-06 23:33 Updated by: sping
  • Details Updated
  • Summary Updated
2019-10-09 04:30 Updated by: keith
Comment

Reply To sping

We're about to define a prototype in https://github.com/libexpat/libexpat/pull/356/files for MinGW in Expat ourselves now but it seems like the real fix would be to have it in MinGW for everyone — what do you think?

Yes, it definitely makes sense that MinGW should declare rand_s() — in <stdlib.h> — but exposed only for _WIN32_WINNT >= _WIN32_WINNT_VISTA || __MSVCRT_VERSION__ >= __MSVCR80_DLL. However, don't be misled by Microsoft's (bogus) claims that rand_s() is somehow more "secure" than rand(). Yes, it may generate random numbers with much greater entropy — because, let's face it, rand() exhibits no entropy at all — but more "secure" it is not, (beyond securing a modicum of Microsoft lock-in, since it conforms to no portable standard whatsoever).

On a side note, msvcrt-xref.pdf says that rand_s is not contained in Windows XP but contained in Windows Vista an after.

What it actually says is that WinXP's MSVCRT.DLL exports no such symbol as rand_s(), and that is, in fact, the case.

The way I read the MS docs they imply availability in Windows XP but it might be wishful thinking — if you know for sure, I'd be interested in more details.

Nope. What Microsoft's docs actually say is that their rand_s() implementation depends on the RtlGenRandom() MS-Windows API, which itself was introduced in WinXP. rand_s() may be used on WinXP (and later) by linking with non-free MSVCR80.DLL (or later), but not when linking with system supplied MSVCRT.DLL, prior to Vista. On Win9x, or Win2K, rand_s() must fail, even if linked with MSVCR80.DLL, because the underlying RtlGenRandom() API is not supported. On WinXP, MinGW cannot offer rand_s() for (default) linking with MSVCRT.DLL; only from Vista onwards, can we offer it universally.

(Edited, 2019-10-09 06:29 Updated by: keith)
2019-10-10 01:21 Updated by: keith
Comment

I've attached a proposed patch, which I plan to add for mingwrt-5.3. This generally conforms to Microsoft documentation, insofar as it:—

  • requires the user to define the _CRT_RAND_S feature test macro;
  • requires linking with MSVCR80.DLL from WinXP onward, or Vista onward for linking with MSVCRT.DLL;
  • exhibits documented arguments signature.

It differs from Microsoft's documented prototype, in respect of returning int rather than errno_t; my rationale for this is:—

  • errno_t is not an ISO-C standard type;
  • all versions of ISO-C require that errno, itself, is of type int;
  • versions of ISO-C, prior to C11, make no reference of errno_t, and POSIX.1 neither requires, nor supports it;
  • although C11 and C18 do allow errno_t, as an optional typedef to int, neither requires it, but both do require the option to be enabled by use of the __STDC_WANT_LIB_EXT1__ feature test macro; Microsoft's usage contravenes these standards, by neglecting this requirement, (and the complementary requirement for the compiler implementation to define __STDC_LIB_EXT1__, to indicate availability of the option);
  • use of errno_t may, (and often does), conflict with GNU C's internal prototypes, (although unlikely in this particular instance);
  • elsewhere, MinGW always uses standard int, in place of non-standard errno_t.
(Edited, 2019-10-10 01:24 Updated by: keith)
2019-10-10 02:33 Updated by: sping
Comment

Sounds pretty good to me!

I wonder: Will I have a chance to distinguish versions of mingwrt declaring rand_s from those that don't on pre-processor level from within Expat code? I don't find anything like that at https://sourceforge.net/p/predef/wiki/Compilers/ . Are there mingwrt specific version defines that I can check for?

PS: Do you have links / sources about why rand_s and RtlGenRandom are not more secure than rand despite not being devoid of entropy, as you mention in the patch comment and above?

2019-10-10 02:44 Updated by: keith
Comment

Could someone please apply and test this for me; right now, I don't have a convenient Windows host to do so myself.

2019-10-10 03:18 Updated by: keith
Comment

Reply To sping

I wonder: Will I have a chance to distinguish versions of mingwrt declaring rand_s from those that don't on pre-processor level from within Expat code? I don't find anything like that at https://sourceforge.net/p/predef/wiki/Compilers/ . Are there mingwrt specific version defines that I can check for?

You can test the value of __MINGW32_VERSION, (a long integer value), which is defined in <_mingw.h>, (and thus always defined after any system header has been included). Its relationship to the mingwrt version is explained in <_mingw.h.in>; you will need to test for

  1. #if __MINGW32_VERSION >= 5003000L

PS: Do you have links / sources about why rand_s and RtlGenRandom are not more secure than rand despite not being devoid of entropy, as you mention in the patch comment and above?

In what way do you think rand() is insecure? In what respect would rand_s() be considered more secure? (Security implies user authentication — an operation which neither of these functions performs).

2019-10-12 07:15 Updated by: sping
Comment

Reply To keith

#if __MINGW32_VERSION >= 5003000L

Okay cool — thank you! I have opened a pull request to add a guard like that to Expat at https://github.com/libexpat/libexpat/pull/359 .

PS: Do you have links / sources about why rand_s and RtlGenRandom are not more secure than rand despite not being devoid of entropy, as you mention in the patch comment and above?

In what way do you think rand() is insecure? In what respect would rand_s() be considered more secure? (Security implies user authentication — an operation which neither of these functions performs).

To give an example where I would expect rand_s to be more secure than rand is protection against hash flooding where the entropy keeps an attacker from crafting a large number of strings that all hash to the same value and hence significantly degrade performance of the hash table in the processing application.

(Edited, 2019-10-12 21:18 Updated by: keith)
2019-10-12 21:12 Updated by: keith
Comment

Reply To sping

To give an example where I would expect rand_s to be more secure than rand is protection against hash flooding where the entropy keeps an attacker from crafting a large number of strings that all hash to the same value and hence significantly degrade performance of the hash table in the processing application.

Well, here we have a fundamental difference in perception. To me, that's just greater quality of implementation, not greater security. Sure, the greater QOI allows you (indirectly) to make your application more secure, but it isn't rand_s() itself which is more secure.

Attachment File List

Edit

Please login to add comment to this ticket » Login