Why do I have to pass a valid page protection value to VirtualAlloc even if it ignores it?


The Virtual­Alloc function accepts a flProtect value, and even though the value is not used by MEM_RESET or MEM_RESET_UNDO, you still have to pass a valid value. (The documentation suggests PAGE_NO­ACCESS.)

Why do you have to pass a valid value even if the system doesn't use it?

This is an artifact of how the front-end parameter validation is done. The Virtual­Alloc function does parameter validation by checking each parameter individually to confirm that the value is among the valid values.

For flAllocationType the code makes sure that a valid combination of flags is passed.

For flProtect, the code makes sure that the page protection value is one of the valid values.

This validation is not contextual, however. When the Virtual­Alloc function validates the flProtect parameter, it doesn't take the flAllocationType into account.

After the front-end validation is done, the code starts breaking down the cases and performs additional validation as necessary.

But what you don't see is a parameter validation short-circuit.

So by the time the code realizes that it's in a case where the flProtect value is not used, it has already validated it.

So make sure your parameters are valid, even if you're calling the function in a way where the parameter is not used.

Bonus chatter: You would think that the flProtect would not be used when reserving address space with MEM_RESERVE, but you'd be wrong. If reserving regular address space, then the protection should be PAGE_NO­ACCESS. This first rule isn't surprising. If you are reserving the space but haven't allocated anything yet, then naturally you don't have access to anything there, since there's nothing there to access.

The odd bit is that if you are reserving address space for Address Windowing Extensions (AWE), then your allocation type is MEM_RESERVE | MEM_PHYSICAL, and the protection must be PAGE_READ­WRITE. Yes, there's no memory there yet, but you still have read/write access to it. (I don't know what that means either, but that's the rule.)

Comments (4)
  1. hyperman says:

    Being naturally curious especially when raimond doesnt know what something means, I googled AWE. It seems to be the 32bit equivalent of EMS from good old DOS times. Trying to Extrapolate from MSDN (A.k.a. I make this up here and now), there are multiple potential bytes available for each virtual address in the AWE window. When you specify which of these bytes is active for now with MapUserPhysicalPages , there is no protection argument. So I guess you just have to specify the protection flags when you create the window, not when you put memory in it.

    1. hyperman says:

      Oops. Sorry Raymond, I misspelled your name. Probably a shooting offence on this blog. I would of course write it 100 times correctly with pens of differently colors in this post, but then you’d ban me for spamming.

  2. Dave Bacher says:

    “The odd bit is that if you are reserving address space for Address Windowing Extensions (AWE), then your allocation type is MEM_RESERVE | MEM_PHYSICAL, and the protection must be PAGE_READ­WRITE. Yes, there’s no memory there yet, but you still have read/write access to it. (I don’t know what that means either, but that’s the rule.)”

    What’s so odd about that.

    I have four threads in a pool, each thread calls VirtualAlloc and they’re sharing a copy of a table in AWE. AWE doesn’t want to have to do a per-thread first time initialization, or track page status — and the assumption is the entire data structure in AWE has a similar protection level requirement for the thread — so you set it once on the address range, and then move the window across the data structure(s) as required.

    There’s a security concern if AWE doesn’t correctly limit the window to only memory that AWE has allocated — but that’s a much easier problem than tracking protection level for pages. At least in theory.

    Sorry if this is a double post, my Internet connection is bad and I don’t know if you’re moderating me or if my post didn’t take.

    1. Rick C says:

      We won’t know unless he replies, but it could be “I don’t know what that means” means “you have read/write access to memory that doesn’t exist is kind of like ‘what is the sound of one hand clapping?'”

Comments are closed.

Skip to main content