473,497 Members | 2,190 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Seting unsigned long value causes coredump

I think I'm missing something fundamental here. I'm trying to set an
unsigned long value via a u_long pointer, however it coredumps
everytime I get to that instruction. Here is a sample program that
demonstrates the issue:

--- snip ---
#include <unistd.h>

int main() {
char buf[512];
u_char *char_p;
u_long *long_p;

memset(buf, 0x0, sizeof(buf));
memset(buf, 'A', 50);

char_p=buf;
long_p = (unsigned long *) (char_p+=strlen(buf));

*long_p = 0xffaa00dd;
}
--- snip ---

I've even debuged it right up to the store call:

--- session ---
[sundev2: user]~$ gdb blah
GNU gdb 6.0
Copyright 2003 Free Software Foundation, Inc.
....
(gdb) disassemble main
Dump of assembler code for function main:
....
0x00010708 <main+104>: sethi %hi(0xffaa0000), %g1
0x0001070c <main+108>: or %g1, 0xdd, %g1 ! 0xffaa00dd
0x00010710 <main+112>: st %g1, [ %o5 ]
0x00010714 <main+116>: mov %g1, %i0
0x00010718 <main+120>: ret
0x0001071c <main+124>: restore
End of assembler dump.
(gdb) break *0x00010710
Breakpoint 1 at 0x10710: file blah.c, line 14.
(gdb) run
Starting program: /export/home/s182301/labroom/test/cde/blah

Breakpoint 1, 0x00010710 in main () at blah.c:14
14 *long_p = 0xffaa00dd;
(gdb) info register g1 o5
g1 0xffaa00dd -5635875
o5 0xffbffaba -4195654
(gdb) x/2wx 0xffbffaba - 4
0xffbffab6: 0x41414141 0x00000000
(gdb) stepi

Program received signal SIGSEGV, Segmentation fault.
0x00010710 in main () at blah.c:14
14 *long_p = 0xffaa00dd;
(gdb)
--- session ---

So, I understand that "st %g1, [ %o5 ]" will move the contents of %g1
into the address of %o5. So, to make sure i'm at the right location,
I examine the word at and before %o5 (0xffbffaba), and it looks like
i'm in the right location, immediatly after my memset 'A's. But the
instruction causes a SIGSEGV, which I really dont understand.

For your information, I'm running this on an UltraSparc I, using
Solaris 9, gcc 3.3.2, and latest patches.

Thank you in advanced for any assistance you can provide.
Bryan.
Nov 14 '05 #1
7 2134
bryan wrote:

I think I'm missing something fundamental here. I'm trying to set an
unsigned long value via a u_long pointer, however it coredumps
everytime I get to that instruction. Here is a sample program that
demonstrates the issue:

--- snip ---
#include <unistd.h>

int main() {
char buf[512];
u_char *char_p;
u_long *long_p;

memset(buf, 0x0, sizeof(buf));
memset(buf, 'A', 50);

char_p=buf;
long_p = (unsigned long *) (char_p+=strlen(buf));

*long_p = 0xffaa00dd;
}


The fundamental thing you've missed is the magic
word "alignment." Some machines will permit a `long'
to begin at any arbitrary address, but others require
that it begin at an address that's a multiple of four,
or eight, or something of the sort. (One can deduce
that the required alignment for an object is a divisor
of the object's size, but that's another topic.)

It appears that the machine you're using is of the
latter type: a `long' can't start "just anywhere," but only
at an address that satisfies a divisibility constraint.
It further appears that the value you generate for `long_p'
(fifty bytes past the start of `buf', whose own alignment
is not known) doesn't meet this constraint -- boom!

Legalistically speaking, anything at all can happen
once you've gone off the rails this way. In practice,
I've come across three different behaviors:

- The program crashes.

- The program works, but more slowly than if the
pointer had been properly aligned.

- The program runs, but the value is stored "near"
rather than "at" the place you intended.

Now to the big question: What are you trying to do?
Explain your goal, and perhaps someone can chart a path
to it that doesn't take you through the Circles of Hell.

--
Er*********@sun.com
Nov 14 '05 #2
br***@bueterfamily.org (bryan) writes:
I think I'm missing something fundamental here. I'm trying to set an
unsigned long value via a u_long pointer, however it coredumps
everytime I get to that instruction. Here is a sample program that
demonstrates the issue:

--- snip ---
#include <unistd.h>
Not a standard C header (and not needed by your code). Include
<string.h> instead to get declarations for `memset' and `strlen'.
int main() {
char buf[512];
u_char *char_p;
u_long *long_p;
`u_char' and `u_long' are not standard C type. I'll assume they
correspond to `unsigned char' and `unsigned long', respectively.
memset(buf, 0x0, sizeof(buf));
memset(buf, 'A', 50);

char_p=buf;
long_p = (unsigned long *) (char_p+=strlen(buf));

*long_p = 0xffaa00dd;
}


If you convert a pointer to an object type to a pointer to another
object type, the resulting pointer is not guaranteed to be correctly
aligned. Therefore, your cast causes undefined behavior, i.e. anything
could happen.

What are you really trying to achieve? If you want to serialize some
data, copy it bytewise (which is referred to as accessing the
"representation" of the data):

unsigned long data = 0xffaa00dd;
/* ... */
memcpy (char_p += strlen (buf), &data, sizeof data);

If the contents of the buffer are potentially read on another machine
later, use the /value/ (as opposed to the /representation/) of the data:

/* The following assumes 4 byte longs and 8 bit bytes. */
*char_p++ = (data >> 24) & 0xFF;
*char_p++ = (data >> 16) & 0xFF;
*char_p++ = (data >> 8) & 0xFF;
*char_p++ = data & 0xFF;

Martin
--
,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =.
/ ,- ) http://www.zero-based.org/ ((_/)o o(\_))
\ `-' `-'(. .)`-'
`-. Debian, a variant of the GNU operating system. \_/
Nov 14 '05 #3
Mac
On Thu, 06 May 2004 19:58:44 +0200, Martin Dickopp wrote:

If you convert a pointer to an object type to a pointer to another
object type, the resulting pointer is not guaranteed to be correctly
aligned. Therefore, your cast causes undefined behavior, i.e. anything
could happen.

You can, however, convert any pointer to a pointer to unsigned char and
then inspect the object byte by byte by way of the unsigned char pointer.
I point this out for the benefit of the OP, as I believe Martin already
knows this.
Martin


--Mac

Nov 14 '05 #4
>Eric Sosman <Er*********@sun.com> wrote in message >news:<40***************@sun.com>...

The fundamental thing you've missed is the magic
word "alignment." Some machines will permit a `long'
to begin at any arbitrary address, but others require
that it begin at an address that's a multiple of four,
or eight, or something of the sort. (One can deduce
that the required alignment for an object is a divisor
of the object's size, but that's another topic.)
Ok, this answers my question fully. So instead of writing a whole
long word I'll just write it one char at a time:

--- snip ---
#include <unistd.h>

int main() {
char buf[512];
u_char *char_p;
u_long *long_p;

memset(buf, 0x0, sizeof(buf));
memset(buf, 'A', 50);

char_p=buf;
long_p = (unsigned long *) (char_p+=strlen(buf));

/* *long_p = 0xffaa00dd; */
*char_p++ = 0xff ;
*char_p++ = 0xaa ;
*char_p++ = 0x00 ;
*char_p++ = 0xdd ;
}
--- snip ---

Its a bit more tedious, but it doesnt crash like it did previously,
and I dont have to worry about where I end up after filling buf[].
Now to the big question: What are you trying to do?
Explain your goal, and perhaps someone can chart a path
to it that doesn't take you through the Circles of Hell.


As for what I'm trying to do? Sticking an unsigned long value (memory
address) into an arbitrary location at the end of buf[]. So
eventually I'll want:

--- snip ---
....
void *from, *to;
u_char *char_p;
u_long *long_p,l_value;

char_p=buf;
long_p = (unsigned long *) (char_p+=strlen(buf));

/* *long_p = 0xffaa00dd; */
l_value = (long)(&string);

from = (void *)(&l_value);
to = (void *)(long_p);

memcpy(to, from, 4);
....
--- snip ---

And thats that. Thanks much.
Bryan.
Nov 14 '05 #5
bryan wrote:
Eric Sosman <Er*********@sun.com> wrote in message >news:<40***************@sun.com>...

Now to the big question: What are you trying to do?
Explain your goal, and perhaps someone can chart a path
to it that doesn't take you through the Circles of Hell.
As for what I'm trying to do? Sticking an unsigned long value (memory
address) into an arbitrary location at the end of buf[].


Guy walks into a bar and orders a beer, and instructs the
bartender to put a spoonful of salt in the bottom of the glass
before pouring. "Why do you want me to do that?" asks the
bartender. "To make sure it dissolves," says the guy.

In other words, when I asked "What are you trying to do?"
it was already obvious that you were trying to stuff a `long'
at an arbitrary location, just as it was obvious to the bartender
that the customer wanted salt in his beer. But just as it's weird
to want salt in beer, it's weird to want to stuff a `long' value
at a non-`long' place. The bartender didn't want to know why the
salt was to go into the glass first, but why it was to go in at all.
I'm similarly wondering why you want to do this weird thing
with `long' values.
So
eventually I'll want:

void *from, *to;
u_char *char_p;
u_long *long_p,l_value;

char_p=buf;
long_p = (unsigned long *) (char_p+=strlen(buf));

/* *long_p = 0xffaa00dd; */
l_value = (long)(&string);

from = (void *)(&l_value);
to = (void *)(long_p);

memcpy(to, from, 4);
...
--- snip ---

And thats that. Thanks much.


Boyoboyoboy are *you* living in a fool's paradise! It
appears that you haven't yet discovered "endianness," nor
have you discovered that `sizeof(long)' might not be four.
And from your remark that this `long' is actually "a memory
address," it appears you haven't quite understood that a
pointer might not be the same size as a `long'. You are
setting yourself up for lots of trouble here (and working
much too hard at it, too), so again I ask: Why?

--
Er*********@sun.com
Nov 14 '05 #6
>Eric Sosman <Er*********@sun.com> wrote in message >news:<40***************@sun.com>...

Guy walks into a bar and orders a beer, and instructs the
bartender to put a spoonful of salt in the bottom of the glass
before pouring. "Why do you want me to do that?" asks the
bartender. "To make sure it dissolves," says the guy.

In other words, when I asked "What are you trying to do?"
it was already obvious that you were trying to stuff a `long'
at an arbitrary location, just as it was obvious to the bartender
that the customer wanted salt in his beer. But just as it's weird
to want salt in beer, it's weird to want to stuff a `long' value
at a non-`long' place. The bartender didn't want to know why the
salt was to go into the glass first, but why it was to go in at all.
I'm similarly wondering why you want to do this weird thing
with `long' values.
ha, good analogy!

So, what am I trying to do? Well, first off, I was just tryig to side
step a straight forward question. I didnt want to get flamed by
saying that I was trying to exploit a bug in libDtHelp:
http://www.kb.cert.org/vuls/id/575804

Let me back that up by saying, I'm not trying to be malicious, I was
just bored at work and reading a few articles on buffer overflows, so
I thought I would play with it a little and learn somthing along the
way:
http://www.securityfocus.com/archive/1/12734

Furthermore, I havnt touched C in a while and this has been a good
practice exersice for getting acustomed to it again. Also, i've
taught myself how to use debuggers (both gdb and mdb), learned a
little assembly, some CPU architecture, and via these posts, learned a
few things about "alignment".

Boyoboyoboy are *you* living in a fool's paradise! It
appears that you haven't yet discovered "endianness," nor
have you discovered that `sizeof(long)' might not be four.
And from your remark that this `long' is actually "a memory
address," it appears you haven't quite understood that a
pointer might not be the same size as a `long'. You are
setting yourself up for lots of trouble here (and working
much too hard at it, too), so again I ask: Why?

--
Er*********@sun.com


Now... Yes, I do know about "endianness". Sparc is big endian, so I
neednt worry about byte order. I've viewed several examples from
memory dumps on how it is stored, so I also know its four bytes.
Maybe different areas are different lenghts, but I havnt run into that
yet, so no biggie.

I also understand that most of what I'm doing is not portable. I
havnt been down that road yet, so i'm not too concerned. This is for
one specific instance, and that is enough of a challenge for me. I am
a beginner C programmer, and I'm probably prone to do stupid things.
I'm ok with that for now.

So, at any rate. Thanks for your help, I've made some progress on the
overflow. If your interested I'll share what i've done. I probably
wont get it fully working, most likely because of the many unknown
technical details that I'm just not aware of, but i'm ok with that
too. Its fun anyway.
Bryan.

ps. Sorry for the delay in posting, but i'm stuck using google for
now.
Nov 14 '05 #7
bryan wrote:
Eric Sosman <Er*********@sun.com> wrote in message >news:<40***************@sun.com>...
[...] It
appears that you haven't yet discovered "endianness," nor
have you discovered that `sizeof(long)' might not be four. [...]


Now... Yes, I do know about "endianness". Sparc is big endian, so I
neednt worry about byte order. I've viewed several examples from
memory dumps on how it is stored, so I also know its four bytes.
Maybe different areas are different lenghts, but I havnt run into that
yet, so no biggie.


As it happens, sizeof(long) on SPARC is either four *or* eight,
depending on the compiler options. Be wary of what you "know!"

--
Er*********@sun.com

Nov 14 '05 #8

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

Similar topics

7
3578
by: William Payne | last post by:
Hello, I have a variable of type unsigned long. It has a number of bits set (with set I mean they equal one). I need to determine those bits and their position and create new numbers from them. For...
2
32263
by: Goran | last post by:
Hi! I need to convert from a unsigned char array to a float. I don't think i get the right results in the program below. unsigned char array1 = { 0xde, 0xc2, 0x44, 0x23}; //I'm not sure in...
34
16604
by: Andy | last post by:
Hi, Are 1 through 4 defined behaviors in C? unsigned short i; unsigned long li; /* 32-bit wide */ 1. i = 65535 + 3; 2. i = 1 - 3; 3. li = (unsigned long)0xFFFFFFFF + 3; 4. li = 1...
3
7148
by: nightolo | last post by:
Hi all, after all I have to say that I'm not a native english speaker so I pray you to excuse for my poor english. I got a trouble writing an application in a powerpc enviroment, that's the...
16
5097
by: TTroy | last post by:
Hello, I'm relatively new to C and have gone through more than 4 books on it. None mentioned anything about integral promotion, arithmetic conversion, value preserving and unsigned preserving. ...
36
5257
by: Digital Puer | last post by:
Hi, suppose I have an unsigned long long. I would like to extract the front 'n' bits of this value and convert them into an integer. For example, if I extract the first 3 bits, I would get an int...
10
17531
by: jeff | last post by:
unsigned long a = ...; long b = (long)a; while a overflows, what is the result of b? Thank you.
13
2024
by: Martin Wells | last post by:
I commonly use the likes of -1 for max unsigned values, or something like -7 to get 6 away from the max value; sort of like: unsigned x = ... if (-7 == x) puts("x is 6 away from its maximum");...
105
6075
by: Keith Thompson | last post by:
pereges <Broli00@gmail.comwrites: These types already have perfectly good names already. Why give them new ones? If you must rename them for some reason, use typedefs, not macros. --
0
7120
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
6991
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7196
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
5456
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
4897
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 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 a new...
0
4583
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3088
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3078
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
649
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.