From: Geoff on
On Wed, 24 Mar 2010 19:09:23 -0400, Hector Santos
<sant9442(a)nospam.gmail.com> wrote:

>Geoff wrote:
>
>>
>> Two bugs exist.
>>
>> 1. You never initialize num, so executing num = Data[num] will access
>> a garbage address in debug mode and will attempt to read Data[0] in
>> release mode since the OS will zero-fill num for you.
>
>
>Hmmmmmm,
>
>Geoff, since when did Windows load low? What version of Windows? Is
>it chip related? The only variables initializes as zero are objects.
>Otherwise all nature types in C are not initialized and need to be
>programmatically initialize. So unless there is something new in
>Windows Vista/7 I am not aware of. If so, this would be new to me. If
>so, I don't know if this would be good or bad since it can hide or
>mask a more serious programming bug, but I can understand Microsoft
>making the security decision today to load low process memory when it
>starts. Probably a safe choice overall, but I still think it would
>perpetuate by programming like the way Peter did there, probably
>assuming that Windows does indeed always starts memory at zero loaded.

I am not sure what you mean by "load low".

In debug mode in my debugger uint32 num is 0xCCCCCCCC so using it as
an index into a un-sized vector<uint32> yields a GPF.

In release mode num is initialized from within the stack space
allocated at link time which would be zeroed in the binary image or
zeroed, presumably by Windows, before the binary was placed into
memory. I assumed this was for security and IIRC, was one of the
reasons Steve Maguire gave for the subtle bugs that appear when going
from debug build to release build and finding out your application
GPFs because you forgot to initialize a pointer.

I'm one of those who niggles at those little details that otherwise
escape the "big picture" boys who don't like to debug their code. :)
From: Geoff on
On Wed, 24 Mar 2010 19:09:23 -0400, Hector Santos
<sant9442(a)nospam.gmail.com> wrote:

>Geoff wrote:
>
>>
>> Two bugs exist.
>>
>> 1. You never initialize num, so executing num = Data[num] will access
>> a garbage address in debug mode and will attempt to read Data[0] in
>> release mode since the OS will zero-fill num for you.
>
>
>Hmmmmmm,
>
>Geoff, since when did Windows load low? What version of Windows? Is
>it chip related? The only variables initializes as zero are objects.
>Otherwise all nature types in C are not initialized and need to be
>programmatically initialize. So unless there is something new in
>Windows Vista/7 I am not aware of. If so, this would be new to me. If
>so, I don't know if this would be good or bad since it can hide or
>mask a more serious programming bug, but I can understand Microsoft
>making the security decision today to load low process memory when it
>starts. Probably a safe choice overall, but I still think it would
>perpetuate by programming like the way Peter did there, probably
>assuming that Windows does indeed always starts memory at zero loaded.

My version is Windows XP. Compiling in VC 6.0 in 32 bit just to check.

BTW, num is invariant over his loop, therefore he was loading from the
same location Max times, hardly a test of memory access speed,
wouldn't you say? In release mode a fully optimized version ran in 0.0
secs, the compiler deciding that it could obtain 100% core utilization
by getting rid of the memory access altogether. :)

From: Geoff on
On Wed, 24 Mar 2010 16:32:39 -0700 (PDT), Malachy Moses
<malachy.moses(a)gmail.com> wrote:

>I apologize for the ad hominem attack. Although it's unlike me, I am
>compelled by the vast quantities of fine resources (from the likes of
>Joe and Hector) that are being wasted on this stuff.

ditto

His style sucks too. I assumed he meant to write this:

typedef unsigned int uint32;

const uint32 size = 100000000;
std::vector<uint32> Data;
uint32 Max = 0x3fffffff;

void Process()
{
clock_t finish;
clock_t start;
double duration;
uint32 num;

Data.resize(size);
start = clock();

for (uint32 N = 0; N < size; N++)
num = Data[N];

finish = clock();
duration = (double)(finish - start) / CLOCKS_PER_SEC;
printf("%4.2f Seconds\n", duration);
}
From: Peter Olcott on

"Hector Santos" <sant9442(a)nospam.gmail.com> wrote in message
news:uxSdCP6yKHA.5132(a)TK2MSFTNGP05.phx.gbl...
> Peter Olcott wrote:
>
>> void Process() {
>> clock_t finish;
>> clock_t start = clock();
>> double duration;
>> uint32 num;
>> for (uint32 N = 0; N < Max; N++)
>> num = Data[num];
>> finish = clock();
>> duration = (double)(finish - start) / CLOCKS_PER_SEC;
>> printf("%4.2f Seconds\n", duration);
>> }
>>
>
>
> All I can see is that you have an uninitialized num
> variable. When not initialized it can be an random number
> including one that exceeds Max.
>
> So initialize it:
>
> uint32 num = 0;
> for (uint32 N = 0; N < Max; N++)
> num = Data[num];
>
> and see if that solved it for you.
>
> Under Windows, it doesn't have a idea of "Load High" or
> "Load Low" some mainframe folks are use to where your
> process memory will be guaranteed to be non-zero (high) or
> zero (low). In C/C++ *natural or native type* variables
> MUST be initialized before referenced otherwise you will
> intermittent issues. It didn't happen before only because
> you lucked out the memory was still low, it wasn't dirty
> and num started at zero. But it was bound to rear its
> head once dirty, and there again, it had to be a reference
> out of range or into protected memory.
>
>
> --
> HLS

Of course that was it, and the compiler even warned me about
this. The only reason that it worked is sometimes the random
garbage fit into the allocation size.


From: Hector Santos on
Geoff wrote:

> I am not sure what you mean by "load low".


Its the old mainframe term for "zero fill"

> In debug mode in my debugger uint32 num is 0xCCCCCCCC so using it as
> an index into a un-sized vector<uint32> yields a GPF.


right.

> In release mode num is initialized from within the stack space
> allocated at link time which would be zeroed in the binary image or
> zeroed, presumably by Windows, before the binary was placed into
> memory.


Ahhhhhhh, the stack ok, I think I did hear MS say there would doing
something along these lines to resolve the #1 SECURITY problem:

stack based buffer overruns

The #1 exploit hackers look for when overloading an input source
looking for the right size that would trigger maybe a:

EXCEPTION_CONTINUE_EXECUTION

at the precise point where the virus is piggy backing on the
overflowing buffer.

xxxxxxxxxx|zzzzzzzzzz|virus
acceptable| overflow |continue address

So what we are talking about it, I'm sure, its Microsoft new Stack
protection technology now implemented in newer Windows but it long
promised since 2000 since the first CodeRed incident that provided the
proof of concept for all the other CodeRed-like viruses to follow.

I have personal experience with this as we were one of the first
corporate CodeRed victims back in 2001 along with other big corporate
sites. This was the first FBI Computer Crimes case for then new South
East Florida FBI Computer Crime Division just open and I immediately
got them involved. Microsoft was calling us practically every day
about the situation once we got the FBI involved (I should of SUED,
but I was nice. <g>) We were both laying unethical blame for E-Eye
Security people getting a name for themselves by threathening MS to
get a fix in X time, but stupidly released the exploit code and within
hours/days a Russian hacker got into our then IIS 4.0 server installed
a back door getting access to entire network.

Trust me, it was one of the worst nightmares me and my network guy
ever went thru, staying up for three full days not knowing how far,
how deep they got in, how much our million dollars investment in
software was stolen or not. All we knew as a result was that the
Russion "FBI" Division was involved and it was reported they arrested
the hacker. Anyway, I recall my conversations with the MS Security
Manager and FBI liaison telling me how MS was going to address the
stack buffer overflow problem at the OS - that was 2001 when Windows
2000 was the current OS.

> I assumed this was for security and IIRC, was one of the
> reasons Steve Maguire gave for the subtle bugs that appear when going
> from debug build to release build and finding out your application
> GPFs because you forgot to initialize a pointer.


Yes, I am sure it is part of MS stack protection. I knew the compiler
has these switches:

/Ge force stack checking for all funcs
/Gs[num] control stack checking calls

But I had the idea that MS did more with Windows Longhorn
(2008/VISTA/7) at the OS level.

> I'm one of those who niggles at those little details that otherwise
> escape the "big picture" boys who don't like to debug their code. :)


Me too, but I always initialize my code by nature now, even if it a
object. :)

--
HLS