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/ > -------------------------------------------------------- >