473,322 Members | 1,232 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,322 software developers and data experts.

pointer past end of buffer

A lot of C++ code allocates a buffer and initializes
start and end pointers as follows:

+-------------------------------+
+ +
+-------------------------------+
^ ^
| |
pStart pEnd

setting pEnd = pStart + bufLen

But what if the buffer is allocated at the very end of memory
and just fits. Then pEnd == MEM_MAX + 1 == 0 and so
library users could tamper with code by creating a buffer
of suitable size. Can this happen in practice?

JG

Oct 30 '06 #1
12 3581
* John Goche:
A lot of C++ code allocates a buffer and initializes
start and end pointers as follows:

+-------------------------------+
+ +
+-------------------------------+
^ ^
| |
pStart pEnd

setting pEnd = pStart + bufLen

But what if the buffer is allocated at the very end of memory
and just fits. Then pEnd == MEM_MAX + 1 == 0 and so
library users could tamper with code by creating a buffer
of suitable size. Can this happen in practice?
The wrapping can not be a /problem/ with a conforming compiler.

And in practice such wrapping will not (be allowed to) happen.

But theoretically a compiler could allow that and make you unaware that
it happens unless you do low-level machine-specific things to inspect
the bit patterns of pointers.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Oct 30 '06 #2
John Goche wrote:
>A lot of C++ code allocates a buffer and initializes
start and end pointers as follows:

+-------------------------------+
+ +
+-------------------------------+
^ ^
| |
pStart pEnd

setting pEnd = pStart + bufLen

But what if the buffer is allocated at the very end of memory
and just fits. Then pEnd == MEM_MAX + 1 == 0 and so
library users could tamper with code by creating a buffer
of suitable size. Can this happen in practice?
The C++ Standard reputedly declares that pointing and indexing
one-off-the-end of an array is well-defined. (Copying out the value of that
bogus element is undefined, except if the element is a char, where it's
simply garbage.)

That means a C++ implementation may not, for example, place any array right
at the end of memory, such that its one-off-the-end location occupies an
overflowed pointer value, or a storage location protected by hardware.

This rule permits all the idioms you have noted, including all of STL's
"asymetric extents". The "start" of anything must be a valid element, and
the "end" must use -- to get to a valid element.

After you become familiar with this effect, it becomes vaguely elegant. But
also extremely useful!

--
Phlip
http://www.greencheese.us/ZeekLand <-- NOT a blog!!!
Oct 30 '06 #3
Alf P. Steinbach wrote:
* John Goche:

But what if the buffer is allocated at the very end of memory
and just fits. Then pEnd == MEM_MAX + 1 == 0 and so
library users could tamper with code by creating a buffer
of suitable size. Can this happen in practice?

The wrapping can not be a /problem/ with a conforming compiler.
Is there something in the C++ standard that states this?

Thanks,

JG

Oct 30 '06 #4
JG Posted:
A lot of C++ code allocates a buffer and initializes
start and end pointers as follows:

+-------------------------------+
+ +
+-------------------------------+
^ ^
| |
pStart pEnd

setting pEnd = pStart + bufLen

Indeed.

size_t const buf_size = 512;

char unsigned *const p = (char unsigned*)malloc(buf_size);
char unsigned const *const pover = p + buf_size;

But what if the buffer is allocated at the very end of memory
and just fits. Then pEnd == MEM_MAX + 1 == 0

That's a possible way of doing it, yes.

and so library users could tamper with code by creating a buffer of
suitable size. Can this happen in practice?

I don't understand what you're saying. . . how could they tamper with code?

Phlip:
The C++ Standard reputedly declares that pointing and indexing
one-off-the-end of an array is well-defined. (Copying out the value of
that bogus element is undefined, except if the element is a char, where
it's simply garbage.)

That's incorrect; the behaviour of the following is undefined:

int main()
{
char buf[12];

buf[12];
}

That means a C++ implementation may not, for example, place any array
right at the end of memory, such that its one-off-the-end location
occupies an overflowed pointer value, or a storage location protected by
hardware.

The C++ Standard imposes no such restriction.

The whole "pointer to one past last" concept has been discussed in depth
many times. Things to note are:

(1) The null pointer value need not be represented by all bits zero.
(2) Pointer arithmetic need not be calculated internally in the same
fashion that unsigned arithmetic is (i.e. wrap-around overflow).
(3) The "pointer to one past last" may compare equal to null.

This leaves the door wide open for implementors, just so long as the code
behaves as it should.

--

Frederick Gotham
Oct 30 '06 #5
"John Goche" <jo*******@gmail.comwrote in message
news:11**********************@h48g2000cwc.googlegr oups.com...
Alf P. Steinbach wrote:
>* John Goche:
>
But what if the buffer is allocated at the very end of memory
and just fits. Then pEnd == MEM_MAX + 1 == 0 and so
library users could tamper with code by creating a buffer
of suitable size. Can this happen in practice?

The wrapping can not be a /problem/ with a conforming compiler.

Is there something in the C++ standard that states this?
Yes.
Oct 30 '06 #6
Jim Langston wrote:
"John Goche" <jo*******@gmail.comwrote in message
news:11**********************@h48g2000cwc.googlegr oups.com...
Alf P. Steinbach wrote:
* John Goche:

But what if the buffer is allocated at the very end of memory
and just fits. Then pEnd == MEM_MAX + 1 == 0 and so
library users could tamper with code by creating a buffer
of suitable size. Can this happen in practice?

The wrapping can not be a /problem/ with a conforming compiler.
Is there something in the C++ standard that states this?

Yes.
So I understand that for a buffer of length buflen 0 we can
assume that p < q so long as q is set to a value q <= p + buflen.
In the case where we set q p + buflen then it is not guaranteed
that p < q holds due to possible pointer overflow. Is this correct?

Thanks,

JG

Oct 30 '06 #7
Phlip wrote:
That means a C++ implementation may not, for example, place any array right
at the end of memory, such that its one-off-the-end location occupies an
overflowed pointer value, or a storage location protected by hardware.
It can be a protected location if the protection is limited to accessing
the memory at that location. If you get a trap for just having that
address in a pointer (very uncommon) well then it's not allowed.
Oct 31 '06 #8
"John Goche" <jo*******@gmail.comwrote in message
news:11**********************@m73g2000cwd.googlegr oups.com...
So I understand that for a buffer of length buflen 0 we can
buflen >= 0 (which could happen if the buffer is dynamically allocated)
assume that p < q so long as q is set to a value q <= p + buflen.
we can assume that p <= q (because buflen might be 0) so long as
p <= q <= p + buflen (i.e. you can't have q < p and still expect p < q
:-) )
In the case where we set q p + buflen then it is not guaranteed
that p < q holds due to possible pointer overflow. Is this correct?
Correct. In that case you're not even assured that you can evaluate p<q.
Nov 2 '06 #9
"Phlip" <ph******@yahoo.comwrote in message
news:Ns******************@newssvr21.news.prodigy.c om...
The C++ Standard reputedly declares that pointing and indexing
one-off-the-end of an array is well-defined. (Copying out the value of
that bogus element is undefined, except if the element is a char, where
it's simply garbage.)
Unsigned char, I think.
This rule permits all the idioms you have noted, including all of STL's
"asymetric extents". The "start" of anything must be a valid element, and
the "end" must use -- to get to a valid element.
The "start" of anything must be a valid element as long as it's not equal to
the "end", which is how you would indicate an empty sequence.

In other words, if c is an empty container, c.begin() == c.end() will be
true, but you are not assured of being able to evaluate *c.begin().
Nov 2 '06 #10
Andrew Koenig wrote:
"John Goche" <jo*******@gmail.comwrote:
In the case where we set q p + buflen then it is not guaranteed
that p < q holds due to possible pointer overflow. Is this correct?

Correct. In that case you're not even assured that you can evaluate p<q.
5.9#2 says that p<q is unspecified in this case (ie. you can
evaluate it but it could evaluate to either true or false).

In the C language, the behaviour is undefined.

Nov 2 '06 #11
Old Wolf wrote:
Andrew Koenig wrote:
"John Goche" <jo*******@gmail.comwrote:
In the case where we set q p + buflen then it is not guaranteed
that p < q holds due to possible pointer overflow. Is this correct?
Correct. In that case you're not even assured that you can evaluate p<q.

5.9#2 says that p<q is unspecified in this case (ie. you can
evaluate it but it could evaluate to either true or false).
Of course it is also undefined if q no longer points to a valid
object, which I believe we are currently debating in c.l.c ;)

Nov 2 '06 #12
Andrew Koenig wrote:
"Phlip" <ph******@yahoo.comwrote in message
news:Ns******************@newssvr21.news.prodigy.c om...
>The C++ Standard reputedly declares that pointing and indexing
one-off-the-end of an array is well-defined. (Copying out the value of
that bogus element is undefined, except if the element is a char, where
it's simply garbage.)

Unsigned char, I think.
It's still undefined.

You're mistaking the rule that says you can use a char pointer to
access all the ALLOCATED bytes comprising any object. Once you
get outside the bounds of an object, your in undefined land.
>
Nov 3 '06 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

21
by: MOvetsky | last post by:
Is the following code ISO C++ standard compliant? If yes, is it guaranteed that it will not crash on compliant platforms? If yes, will it print "Pointers are equal" on any compliant platform? Will...
19
by: Sergey Koveshnikov | last post by:
Hello, If my function return a pointer on a memory area, where do I free it? e.x.: char *foo() { char *p; p = malloc(10); strcpy(p, "something"); return(p); }
10
by: Martin Andert | last post by:
Why ist the following code not working? I want to initialize a string in function, but I am getting those STATUS_ACCESS_VIOLATION exceptions. #include <stdio.h> #include <stdlib.h> void...
5
by: ben | last post by:
Hello All, I am trying to make sense of a bit of syntax, is there a guru out there that can clear this up for me. I have a buffer declared as static volatile u8 buffer; and I have a...
23
by: Kenneth Brody | last post by:
Given the following: char *ptr1, *ptr2; size_t n; ptr2 = ptr1 + n; Assuming ptr1 is a valid pointer, is the following guaranteed to be true? (ptr2 - ptr1) == n
9
by: shaun | last post by:
Dear all, I realized an error in a previous post, I reproduce it here because I'm still not sure how to solve it: I want to make a templated function which points to one-past-the-end of a...
7
by: william | last post by:
My question is: Specific memory block where my pointer pointing to changed strangely, seemingly that no statement changed it. Here are two examples I got: ***********1***************** I was...
1
by: =?utf-8?B?5Lq66KiA6JC95pel5piv5aSp5rav77yM5pyb5p6B | last post by:
first, I'm try the POINTER to convesion the pointer type. but failed. class STUDENT(Structure): _fields_ = buffer = c_byte * 1024 student_p = cast(buffer, POINTER(STUDENT)) The parameter...
17
by: let_the_best_man_win | last post by:
How do I print a pointer address into a string buffer and then read it back on a 64 bit machine ? Compulsion is to use string (char * buffer) only. printing with %d does not capture the full...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.