RE: Globals visible in shared object libraries

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



It's been fixed.  First, the main module cannot be compiled with -fPIC,
or
the symbols will be exported, and merged with common ones in the SO's

Also, I added a 'version-script' file that declares most everything
'local'.
This protects symbols in the SO from matching ones in other SO's

If you want to see the problem, here are the files I used:
The symbols that gets stomped on is 'value', which has different
declarations in each module.

==========MAKEFILE=====================
all: testmain lib 
CC = gcc
######   REMOVE -fPIC, AND IT WORKS AS I EXPECT
FLAGS = -Wall -c -g3 -O3 -fPIC
MAINFLAGS = -lpthread -ldl -lc -o testmain
SOFLAGS = -Wall  -c -g3 -O3 -fPIC
LFLAGS1 = -shared -Wl,-soname,lib.so.1 -o lib.so.1 
clean :
	rm *.o
	rm *.1
	rm testmain
testmain : main.o
	${CC} ${MAINFLAGS} main.o
main.o: main.c
	${CC} ${FLAGS} main.c
lib: lib.o
	${CC} ${LFLAGS1} lib.o
lib.o: lib.c
	${CC} ${SOFLAGS} lib.c
============main.c===========================
#include <stdio.h>
#include <dlfcn.h>

#include <unistd.h>
#include <pthread.h>

typedef void *(*THREAD_FUNC)(void*);
long  value;

int _beginthread(void (*function)(void *), int stack, void * arg) {
	pthread_attr_t thread_attr;
	pthread_t a_thread;

	pthread_attr_init(&thread_attr);
	
pthread_attr_setdetachstate(&thread_attr,PTHREAD_CREATE_DETACHED);

	
pthread_create(&a_thread,&thread_attr,(THREAD_FUNC)function,arg);
	return 0;
}

void thread1(void *s) {

	do {
		value++;
		sleep(1);
	} while (1);

	return ;
}

void (*init_lib)(unsigned char *);
void (*get_value)(unsigned long *);

void thread2 (void *s) {
	int x = 0;
	puts("reading thread has been launched");
	do {
		unsigned long value;
		get_value(&value);
		printf("TEST_FUNCTION - The value is: %ld\n",value);
		sleep(1);
	} while (x++ < 40);
	puts("Thread 2 is exiting...");
	return ;
}

int main() {

	void * handle;

	value = 0;

	handle = dlopen("./lib.so.1",RTLD_NOW);
	if (handle == 0) {
		puts("The libarary could not be found");
		return -1;
	}
	init_lib = dlsym(handle,"init_lib");
	if (init_lib == 0) {
		puts("The function could not be found...");
		return -1;
	}

	get_value = dlsym(handle,"get_value");
	if (get_value == 0) {
		puts("The get_value function could not be found...");
		return -1;
	}
	printf("1- The location is %p, contents %ld\n",&value,value);
	init_lib((unsigned char *) &value);
	printf("2- The location is %p, contents %ld\n",&value,value);
	_beginthread(thread1,0,0);
	sleep(3);
	_beginthread(thread2,0,0);

	sleep(100);

	return 0;
}
================lib.c=========================
#include <stdio.h>

long * value;
void init_lib(unsigned char * buffer) {
	value = (long *) buffer;
	printf("INSIDE The library has been initialized - the value
passed in was %p\n",buffer);
	printf("INSIDE The location is %p, contents
%lx\n",value,*value);
}
void get_value(unsigned long * ptr) {
	*ptr =  *value;
}

===================END CODE==========================
-----Original Message-----
From: Gaurav Jain [mailto:gaurav.anywhere@xxxxxxxxx] 
Sent: Wednesday, June 22, 2005 2:43 AM
To: Weber, Scott
Cc: Keith, Robert (London); gcc-help@xxxxxxxxxxx
Subject: Re: Globals visible in shared object libraries


Hi Scott,

I can't reproduce your problem in a small program.  Can you give your
source code that's failing?

Gaurav

On 6/13/05, Weber, Scott <Scott.Weber@xxxxxxxxxxxxx> wrote:
> Thanks for the tip.  I am not using RTLD_GLOBAL.  And it appears there

> is no real definition for RTLD_LOCAL  (i.e. 0x0000)
> 
> Forgot to mention, I can make B.so declaration 'static short value' 
> and solve the problem.  But that's not the fix I want. But I'm 
> concerned about the main execuable being corrupted by the shared libs,

> which are to be created by anybody.
> 
> I want to secure the main executable, not tell dozens of people they 
> have to code the sared module a specific way, and have to keep up with

> all the vendors everytime there is a problem.
> 
> Who gets the 'fvisibility' flag?  And does it apply if I'm not using 
> the RTLD_GLOBAL flag?
> 
> -----Original Message-----
> From: Keith, Robert (London) [mailto:robert_keith@xxxxxx]
> Sent: Monday, June 13, 2005 11:26 AM
> To: Weber, Scott; gcc-help@xxxxxxxxxxx
> Subject: RE: Globals visible in shared object libraries
> 
> 
> I have had a similar problem with functions. After much searching the 
> result is as follows
> 
> 1. Don't Load the module with RTLD_GLOBAL, which is what it sounds 
> like you are doing. If you absolutely have to do this then depending 
> on the version of the compiler that you are using I would recommend 
> compiling the code with the -fvisibility=hidden and making sure you 
> only call functions that you have extern'ed when calling across shared

> library boundaries. This switch makes all symbols part of the local 
> (dll/so) namespace when its loaded and only pushes symbols you have 
> explicitly declared as global in to the global namespace.
> 
> 2.Another alternative is to put the following in front of your 
> declaration for 'value'
> 
> __attribute__ ((visibility("hidden")))
> 
> This will only be honoured if your compiler has had this functionality

> included (or back ported). Basically this tells the compiler to look 
> in the local namespace then the global namespace when attempting to 
> resolve symbols using shared libraries. I honestly don't know what 
> version this was officially included in the compiler (I think it was 
> 3.4, since it has been back ported to many compilers even 3.2.3)
> 
> So that's the quick fix - more information can be found at:
> 
> http://gcc.gnu.org/wiki/Visibility
> 
> And
> 
> http://www.google.co.uk/url?sa=U&start=1&q=http://people.redhat.com/dr
> ep
> per/dsohowto.pdf&e=10431
> 
> 3. Namespace the variable in each so and make sure that the functions 
> that update it reference it via the correct name space.
> 
> E.g. namespace a {
>         value ;
> }
> void someFunc() {
>                 a::value = 10 ;
> }
> 
> namespace b {
>         value ;
> }
> 
> Void someOtherFunc() {
>         b::value = 21 ;
> }
> 
> Regards,
> 
> Robert Keith
> 
> 
> -----Original Message-----
> From: gcc-help-owner@xxxxxxxxxxx [mailto:gcc-help-owner@xxxxxxxxxxx] 
> On Behalf Of Weber, Scott
> Sent: 13 June 2005 17:13
> To: gcc-help@xxxxxxxxxxx
> Subject: Globals visible in shared object libraries
> 
> 
> 
> I have been digging at this for days, Now I'm turning to the experts.
> 
> Given:
> executable module A has a global variable (long)  called 'value' It 
> loads module B.so  using dlopen() and loads a function pointer (called
> 'test') .
> 
> Module B.so also has a global variable (some other type) called 
> 'value'
> 
> When I call test() in B.so and that function changes the contents of 
> 'value', it changes to one in the A executable.  Not the one in in 
> B.so.  (or I assume they have been 'linked' into the same memory 
> location)
> 
> How can I DISABLE the dynamic linker from doing what appears to be 
> binding the variable 'value'  in the two modules together?  It's this 
> a HUGH hole where any shared library can get access to (and corrupt) 
> variables in the main executable?
> 
> Everything think I've seen written seems to be regarding doing the 
> opposite.
> 
> Any help is appreciated.
> 
> -Scott Weber
> (sorry if this is not exclusively plain text - Outlook... :-(  )
> --------------------------------------------------------
> 
> If you are not an intended recipient of this e-mail, please notify the

> sender, delete it and do not read, act upon, print, disclose, copy, 
> retain or redistribute it. Click here for important additional terms
> relating to this e-mail.     http://www.ml.com/email_terms/
> --------------------------------------------------------
>


[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux