473,396 Members | 1,917 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,396 software developers and data experts.

Function pointer dereference security

I have following code:

union Pointer {
void *objp;
void (*funcp)();
};

Pointer p = ... ;

....

p();

---

Now, supposing that p were actually not a genuine function pointer but
arbitrary or malicious data, could such code be theoretically
exploited to hijack program execution, or does the C runtime check
that a function call is made to a legitimate address?

Nov 11 '07 #1
12 1868
Nyang A. Phra said:

<snip>
p();

---

Now, supposing that p were actually not a genuine function pointer
....then it would be the height of folly to treat it as if it were.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Nov 11 '07 #2
Now, supposing that p were actually not a genuine function pointer
>
...then it would be the height of folly to treat it as if it were.
Yeah kinda thought so, but what are the consequences? Does the runtime
catch such errors and just die or could in theory anomalous program
execution follow?

Nyang

Nov 11 '07 #3
>I have following code:
>
union Pointer {
void *objp;
void (*funcp)();
};

Pointer p = ... ;

...

p();

---

Now, supposing that p were actually not a genuine function pointer but
arbitrary or malicious data, could such code be theoretically
exploited to hijack program execution, or does the C runtime check
that a function call is made to a legitimate address?
Assuming that the pointer is to memory that is not mapped into the
process or simply doesn't exist, your program will probably just
crash. Some operating systems vary the load address of a program
randomly each time it is executed so it's harder to guess what
addresses will be available.

Assuming that the pointer is to a buffer that the attacker managed
to fill with code of his own choosing, possibly by buffer overflow,
you're in deep, deep trouble. (Think 'virus' and 'botnet'). The
attacker can do anything your program could. If your program was
running with administrative privileges, you're really screwed.
Buffer overflow is a technique used by a lot of viruses.

Some operating systems have provisions that you cannot execute
memory that is writable, making it harder to actually execute code
by writing over function return addresses when overflowing an auto
array. This isn't foolproof, but it does help. The program just
quickly crashes.

Assuming that the pointer is redirected from the expected routine to
an existing routine in the C library that deletes files, there's
probably not much that can be done, since it *is* legitimate code,
and the function arguments might be legitimate also.
Nov 11 '07 #4
On Nov 11, 7:37 am, gordonb.47...@burditt.org (Gordon Burditt) wrote:
I have following code:
union Pointer {
void *objp;
void (*funcp)();
};
Pointer p = ... ;
...
p();
---
Now, supposing that p were actually not a genuine function pointer but
arbitrary or malicious data, could such code be theoretically
exploited to hijack program execution, or does the C runtime check
that a function call is made to a legitimate address?

Assuming that the pointer is to memory that is not mapped into the
process or simply doesn't exist, your program will probably just
crash. Some operating systems vary the load address of a program
randomly each time it is executed so it's harder to guess what
addresses will be available.

Assuming that the pointer is to a buffer that the attacker managed
to fill with code of his own choosing, possibly by buffer overflow,
you're in deep, deep trouble. (Think 'virus' and 'botnet'). The
attacker can do anything your program could. If your program was
running with administrative privileges, you're really screwed.
Buffer overflow is a technique used by a lot of viruses.

Some operating systems have provisions that you cannot execute
memory that is writable, making it harder to actually execute code
by writing over function return addresses when overflowing an auto
array. This isn't foolproof, but it does help. The program just
quickly crashes.

Assuming that the pointer is redirected from the expected routine to
an existing routine in the C library that deletes files, there's
probably not much that can be done, since it *is* legitimate code,
and the function arguments might be legitimate also.
Yeah makes sense. Will avoid the construction. Thanks.

Nov 11 '07 #5
Nyang A. Phra said:
Now, supposing that p were actually not a genuine function pointer

...then it would be the height of folly to treat it as if it were.

Yeah kinda thought so, but what are the consequences?
If a function pointer does not point at a function, then the consequences
of dereferencing that pointer are undefined (which means anything may
happen, including Very Bad Things).
Does the runtime
catch such errors and just die or could in theory anomalous program
execution follow?
Both are possibilities.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Nov 11 '07 #6
"Nyang A. Phra" <na****@gmail.comwrites:
Now, supposing that p were actually not a genuine function pointer

...then it would be the height of folly to treat it as if it were.

Yeah kinda thought so, but what are the consequences? Does the runtime
catch such errors and just die or could in theory anomalous program
execution follow?
The runtime is permitted, but not obligated, to catch such
errors. Most don't, so that anomalous program execution is
likely.
--
"Structure padding is the use of extraneous materials to
enhance the shape of a struct and make it more attractive to
members of the opposite struct. (See also "struct silicone.")"
--Eric Sosman
Nov 11 '07 #7
"Nyang A. Phra" <na****@gmail.comwrites:
I have following code:

union Pointer {
void *objp;
void (*funcp)();
};

Pointer p = ... ;

...

p();
[...]

A few things about your code, not addressing your actual question
(which has been answered by others).

Given a declaration of type "union Pointer", you can't refer to the
type as just "Pointer" (unless you've also declared a typedef).
<OT>C++ lets you do this; C doesn't.<OT>

If p is of type union Pointer, then p() is not the way to call the
function, since p is not of function or pointer-to-function type.
You'd need to use "p.funcp()".

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Looking for software development work in the San Diego area.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Nov 11 '07 #8
On Sunday 11 Nov 2007 5:16 am Nyang A. Phra <na****@gmail.comwrote in
article <11**********************@o38g2000hse.googlegroups .com>:
Now, supposing that p were actually not a genuine function pointer

...then it would be the height of folly to treat it as if it were.

Yeah kinda thought so, but what are the consequences? Does the runtime
catch such errors and just die or could in theory anomalous program
execution follow?
The runtime is not required to catch such conditions, and it typically
doesn't. In most memory protected architectures the operating system
will terminate the application for invalid/illegal instruction
sequences, as soon as your program tries to execute data. Before that
happens you may very likely trash your own data and program state. With
some techniques like execute disable functionality the system may
terminate your application even before it can actually execute any
data.

Note however that all this is highly system specific and the C Standard,
in the interests of wide applicability, has nothing to say upon this
other than that you have invoked Undefined Behaviour.

Nov 11 '07 #9
Nyang A. Phra wrote:
I have following code:

union Pointer {
void *objp;
void (*funcp)();
};

Pointer p = ... ;

...

p();
The compiler must issue a diagnostic. The () function-call
operator must follow an expression that yields a function pointer,
and the expression `p' yields a union pointer.
Now, supposing that p were actually not a genuine function pointer but
arbitrary or malicious data, could such code be theoretically
exploited to hijack program execution, or does the C runtime check
that a function call is made to a legitimate address?
Let's assume you wrote `p->funcp()' instead. Then it is your
responsibility to see to it that `p->funcp' holds a valid function
pointer value. If it does not, the behavior is undefined. (The
fact that the value is stored in a union isn't important; you need
to ensure its validity no matter where it resides.)

Some C implementations may perform some kinds of validity
check on function calls; if they do, the nature and thoroughness
of the checking are unspecified, as are the consequences of
failing the check. Others may just take you at your word and
try to call the "function" at J. Random Location; again, the
consequences are unspecified.

Even if run-time checking verifies that the call is to a
valid function, it's hard to imagine that it could ensure that
the call is to the "intended" function. If the Evil Genius gets
your program to call cos() when it thinks it's calling sqrt(),
a run-time checking scheme is quite likely to let the E.G. get
away with it. Mwaah-hah-hahaha!

--
Eric Sosman
es*****@ieee-dot-org.invalid
Nov 11 '07 #10
On Sat, 10 Nov 2007 20:56:19 -0800, "Nyang A. Phra" <na****@gmail.com>
wrote:
>I have following code:

union Pointer {
void *objp;
void (*funcp)();
};

Pointer p = ... ;

...

p();

---

Now, supposing that p were actually not a genuine function pointer but
arbitrary or malicious data, could such code be theoretically
exploited to hijack program execution, or does the C runtime check
that a function call is made to a legitimate address?
Are you talking about p or p.funcp. The executable statement above is
a syntax error that requires a diagnostic. Even though p and p.funcp
are guaranteed to occupy the same address (or at least start at the
same address), they do so as different types and are not
interchangeable. p is a union. You cannot apply the "function
operator", (), to it. p.funcp is a function pointer and p.funcp() is
syntactically correct.

If p.funcp has not been assigned the address of a function, then its
value is indeterminate. Any attempt to dereference it invokes
undefined behavior. There is no requirement in the standard for the
code generated by such a statement to check to insure the address is
valid. While the compilers I am experienced with do not generate code
to perform this check, there is no prohibition against it either. But
if a compiler were to generate such code, it would be above and beyond
the requirements of the standard. Depending on such behavior would
render your code extremely unportable.

Once you have invoked undefined behavior, anything your operating
system lets you get away with is possible. Hijacking your system is
one possibility; formatting your hard disk is another. With the
proper hardware add-ons, it could even route household voltage to your
chair. One of the worst manifestations of undefined behavior is to
appear to work correctly until you are demonstrating the program to
your boss or an important client.
Remove del for email
Nov 12 '07 #11
Eric Sosman <es*****@ieee-dot-org.invalidwrote:
Nyang A. Phra wrote:
I have following code:

union Pointer {
void *objp;
void (*funcp)();
};

Pointer p = ... ;

...

p();

The compiler must issue a diagnostic. The () function-call
operator must follow an expression that yields a function pointer,
and the expression `p' yields a union pointer.
Now, supposing that p were actually not a genuine function pointer but
arbitrary or malicious data, could such code be theoretically
exploited to hijack program execution, or does the C runtime check
that a function call is made to a legitimate address?

Let's assume you wrote `p->funcp()' instead. Then it is your
responsibility to see to it that `p->funcp' holds a valid function
pointer value. If it does not, the behavior is undefined. (The
fact that the value is stored in a union isn't important; you need
to ensure its validity no matter where it resides.)

Some C implementations may perform some kinds of validity
check on function calls; if they do, the nature and thoroughness
of the checking are unspecified, as are the consequences of
failing the check. Others may just take you at your word and
try to call the "function" at J. Random Location; again, the
consequences are unspecified.
Of course, the real question in all of this is: why _would_ you call
through a pointer which might contain random data? _You_ control your
pointers, nobody else. If you make sure that you only call a pointer
when you already know that it points at one valid function or another
(because, of course, you have assigned that function's address to this
pointer yourself), there is no need for the implementation to even try
to do so.

Richard
Nov 14 '07 #12
On Sat, 10 Nov 2007 20:56:19 -0800, "Nyang A. Phra" <na****@gmail.com>
wrote:

>I have following code:

union Pointer {
void *objp;
void (*funcp)();
};

Pointer p = ... ;

...

p();
p.funcp();

A perfectly good way to have self-modifying code, or execute loaded or
transferred snippets of machine code. Or, with the converse, to dump the
machine code of a function (for use later?).

A perfectly horrid way of writing safe and maintainable code, of course.
--
#include <standard.disclaimer>
_
Kevin D Quitt USA 91387-4454 96.37% of all statistics are made up
Dec 20 '07 #13

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

Similar topics

9
by: Pushker Pradhan | last post by:
I've a function which accepts void * as the arg because the actual datatype can be char or float or anything. The fuction: void convolve(void *x, float *convx, uint32 numrowsx, uint32 numcolsx,...
5
by: Cancerbero | last post by:
Hi (first, excuse me for my bad english) As I know, the semantics for typedef is: typedef A B; I think this makes B a synonym of A, where A is an existing data type. Is that right? Based...
51
by: Richard Hengeveld | last post by:
Hi all, I'm trying to understand how pointers for function parameters work. As I understand it, if you got a function like: void f(int *i) { *i = 0; }
8
by: nsharma78 | last post by:
Hi, I have a code as follows: class A { public: void print(){cout << "Magic" << endl;} };
1
by: Frederick Dean | last post by:
Hi, guys! Please look at the very simple code below: //---------------code begin------------------------ void f() { cout << "f function " << endl; } void (*pf)() = &f;
5
by: mancomb | last post by:
Hi, I'm curious to the syntax of calling member functions through pointers of classes returned through the -operator. For example (excuse the crude incomplete code); Here are the classes: ...
17
by: Jason Doucette | last post by:
I am converting a C-style unit into a C++ class. I have an implementation function that was defined in the .cpp file (so it was hidden from the interface that exists in the .h file). It uses a...
8
by: Tony Winslow | last post by:
Hi, I'm wondering why the following code works just fine: #include <stdio.h> int main() { (******printf)("Hello!\n");
10
by: Richard Heathfield | last post by:
Stephen Sprunk said: <snip> Almost. A function name *is* a pointer-to-function. You can do two things with it - copy it (assign its value to an object of function pointer type, with a...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
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
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
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
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,...

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.