From: Vladimir Vassilevsky on

There is a project of many files. Some functions from some modules are
called from other modules, so those functions must have a global scope.
However, those functions are part of a system and they have many side
effects. So those functions should be called only from the right places
and at the right times.

What would be the elegant way to ensure that idiots won't call the
system functions just because the functions are visible?

In C++, I can hide those functions into classes or namespaces, so the
functions will be accessible only where it is needed. Is there a way to
do something like that in C ?


Vladimir Vassilevsky
DSP and Mixed Signal Design Consultant
http://www.abvolt.com

From: David Brown on
On 12/08/2010 07:02, Vladimir Vassilevsky wrote:
>
> There is a project of many files. Some functions from some modules are
> called from other modules, so those functions must have a global scope.
> However, those functions are part of a system and they have many side
> effects. So those functions should be called only from the right places
> and at the right times.
>
> What would be the elegant way to ensure that idiots won't call the
> system functions just because the functions are visible?
>
> In C++, I can hide those functions into classes or namespaces, so the
> functions will be accessible only where it is needed. Is there a way to
> do something like that in C ?
>

No - AFAIK in C, it's all or nothing. The only way to avoid the
functions being easily callable is to omit their declarations from the
header files, or to "hide" them in extra header files. Nothing can stop
users declaring them with explicit "extern" statements and calling them,
however.

One possible way to neaten things would be to have your module header
like this:

#ifndef __module_h__
#define __module_h__

#ifdef AllowSystemCalls
#define SYSCALL
#else
// gcc has a nice __attribute__ syntax to use here
// warning attribute is another option
#define SYSCALL __attribute__((error("I can't let you do that, Dave")))
#endif


extern void NormalFunction(void);
extern void SYSCALL SystemFunction(void);









From: Jon Kirwan on
On Thu, 12 Aug 2010 00:02:43 -0500, Vladimir Vassilevsky
<nospam(a)nowhere.com> wrote:

><snip>
>What would be the elegant way to ensure that idiots won't call the
>system functions just because the functions are visible?
>
>In C++, I can hide those functions into classes or namespaces, so the
>functions will be accessible only where it is needed. Is there a way to
>do something like that in C ?

Yes -- until I saw "elegant," above. Is a cfront style
solution off the table?

Jon

P.S. Here's my 'dump out' which is probably NOT elegant.

You linker may support features the c compiler doesn't
directly provide, but where you can write a program to modify
the object file to gain access. c tends to only require
basic linker features, though, and the linker may not have
any support for something useful.

Circa 1980, c++ used to be called "c with classes" and
targeted c, just fine. If cfront were available (I don't
know that it is, or isn't, now), it might be able to act as a
kind of pre-processor of sorts for c code that used just the
class-syntax as an extension to get close. You'd just write
"mostly c" and use the class method and let cfront mangle
stuff for you and produce usable c -- except for the mangling
which you may or may not feel strongly about.

If you are fine with name mangling but no cfront is handy,
you could consider writing something short and sweet to get
the job done as a preprocessing step.

Otherwise, if you feel strongly about only using a simple
editor and c and nothing else and not interested in finding
out about or using any special linker features, bypassing
what the c compiler does by modifying object files before the
linker step, then you are stuck with the module-local scope
or the global-at-link-time scope for which c provides syntax
and can do what generations have done before you -- write
unique names and otherwise don't include extern statements
for them in modules that shouldn't be using them. That won't
control anyone else who links, though.

I suppose you could consider something, not unlike a
librarian of some kind, that allows you to prelink some
object modules together and then strip out certain global
names afterwards that you don't want publicized and supply
that as a linkage unit to others. It would block them even
if they tried to declare the names, then. Again, might be
custom work. But there it is.
From: Peter Keller on
David Brown <david(a)westcontrol.removethisbit.com> wrote:
> On 12/08/2010 07:02, Vladimir Vassilevsky wrote:
>>
>> There is a project of many files. Some functions from some modules are
>> called from other modules, so those functions must have a global scope.
>> However, those functions are part of a system and they have many side
>> effects. So those functions should be called only from the right places
>> and at the right times.
>>
>> What would be the elegant way to ensure that idiots won't call the
>> system functions just because the functions are visible?
>>
>> In C++, I can hide those functions into classes or namespaces, so the
>> functions will be accessible only where it is needed. Is there a way to
>> do something like that in C ?
>>
>
> No - AFAIK in C, it's all or nothing. The only way to avoid the
> functions being easily callable is to omit their declarations from the
> header files, or to "hide" them in extra header files. Nothing can stop
> users declaring them with explicit "extern" statements and calling them,
> however.

What about the "static" keyword? Sure, it'll only let you call the
function in the file in which you defined the static function, but
it'll be marked as private in the object file and you shouldn't be
able to link against it extern tricks or no. If you want to share
the static function across several files, you're generally out of luck.

Besides, just document the library's real api, and say if you deviate
from it there is no guarantee of correct behavior and you won't
support them.

C++ with namespaces or private member functions don't fix anything
for a determined hacker. I could, outside of any legal C++ means,
call private methods in a class I don't have a header file to if I
wanted to and only a pointer to it.

Here is an example:

#include <stdio.h>
#include <stdlib.h>

class Foo
{
public:
Foo() {};
~Foo() {};
void callit(int c) { hello(c); }

private:
void hello(int x)
{
printf("Hello: %d\n", x);
}
};

/* gcc 4.1.2 C++ ABI C linkage call */
extern "C" { void _ZN3Foo5helloEi(void*, int); }

int main(int argc, char *argv[])
{
Foo f;

/* normal way */
f.callit(10);

/* naive method to break the 'private' protection. */
_ZN3Foo5helloEi(&f, 20);

return 0;
}

If I cared more, I could probably deduce what the function table looks like
from the object and do some void (**func)(void*, int) hackery to figure out
a callable function form the class pointer.

So, in reality, you should be asking: What is my threat model?

If it is simply "To prevent idle stupidity", then document the API only,
and don't support it if they do anything else. If it is "ensure noone can
ever call into code I don't want them to" you're screwed--it is always
possible.

Later,
-pete



From: David Brown on
On 12/08/2010 10:30, Peter Keller wrote:
> David Brown<david(a)westcontrol.removethisbit.com> wrote:
>> On 12/08/2010 07:02, Vladimir Vassilevsky wrote:
>>>
>>> There is a project of many files. Some functions from some modules are
>>> called from other modules, so those functions must have a global scope.
>>> However, those functions are part of a system and they have many side
>>> effects. So those functions should be called only from the right places
>>> and at the right times.
>>>
>>> What would be the elegant way to ensure that idiots won't call the
>>> system functions just because the functions are visible?
>>>
>>> In C++, I can hide those functions into classes or namespaces, so the
>>> functions will be accessible only where it is needed. Is there a way to
>>> do something like that in C ?
>>>
>>
>> No - AFAIK in C, it's all or nothing. The only way to avoid the
>> functions being easily callable is to omit their declarations from the
>> header files, or to "hide" them in extra header files. Nothing can stop
>> users declaring them with explicit "extern" statements and calling them,
>> however.
>
> What about the "static" keyword? Sure, it'll only let you call the
> function in the file in which you defined the static function, but
> it'll be marked as private in the object file and you shouldn't be
> able to link against it extern tricks or no. If you want to share
> the static function across several files, you're generally out of luck.
>

I got the impression from the O/P that the functions had to have
external linkage because they could be called from other modules, but
that he wanted to make it hard to call them. If "static" was the
answer, then I think Vladimir would have figured that out himself.

> Besides, just document the library's real api, and say if you deviate
> from it there is no guarantee of correct behavior and you won't
> support them.
>

<snip>

>
> So, in reality, you should be asking: What is my threat model?
>
> If it is simply "To prevent idle stupidity", then document the API only,
> and don't support it if they do anything else. If it is "ensure noone can
> ever call into code I don't want them to" you're screwed--it is always
> possible.
>

It's always possible to work around any technical restrictions that are
put in. And clear documentation is also always important. But I think
the aim here is to make it hard to break the API rules - it limits the
risk of accidents by people who don't read the documentation properly,
or who think they know better than the document writer.



> Later,
> -pete
>
>
>