Uploaded image for project: 'ZABBIX FEATURE REQUESTS'
  1. ZABBIX FEATURE REQUESTS
  2. ZBXNEXT-3388

Load libraries in runtime with RTLD_LOCAL flag

    Details

      Description

      Let's start with a small demonstration. Let's build a small application (test) linked against two libraries (liba.so and libe.so) depending on one and the same symbol (foo) from two different libraries (libb.so and libd.so).

      a.c:

      #include "a.h"
      #include "b.h"
      
      void	a_foo(void)
      {
      	foo();
      }
      

      a.h:

      void	a_foo(void);
      

      b.c:

      #include <stdio.h>
      
      void	foo(void)
      {
      	printf("bar\n");
      }
      

      b.h:

      void foo(void);
      

      d.c:

      #include <stdio.h>
      
      void	foo(void)
      {
      	printf("baz\n");
      }
      

      d.h:

      void	foo(void);
      

      e.c:

      #include "d.h"
      #include "e.h"
      
      void	e_foo(void)
      {
      	foo();
      }
      

      e.h:

      void	e_foo(void);
      

      Let's build libraries:

      $ gcc -o libb.so b.c -fPIC -shared
      $ gcc -o libd.so d.c -fPIC -shared
      $ gcc -o liba.so a.c -lb -L. -fPIC -shared
      $ gcc -o libe.so e.c -ld -L. -fPIC -shared
      

      Let's first test them separately.
      test_a:

      #include "a.h"
      
      int	main(void)
      {
      	a_foo();
      
      	return 0;
      }
      

      test_e.c:

      #include "e.h"
      
      int	main(void)
      {
      	e_foo();
      
      	return 0;
      }
      
      $ export LD_LIBRARY_PATH=.
      $ gcc -o test_a test_a.c -la -L.
      $ gcc -o test_e test_e.c -le -L.
      $ ./test_a
      bar
      $ ./test_e
      baz
      

      So far everything is as expected. Now let's link both libraries to the same program.
      test_both.c:

      #include "a.h"
      #include "e.h"
      
      int	main(void)
      {
      	a_foo();
      	e_foo();
      
      	return 0;
      }
      

      Both a_foo() and e_foo() print "bar" or "baz" depending on -l flag order:

      $ gcc -o test_both test_both.c -la -le -L.
      $ ./test_both
      bar
      bar
      $ gcc -o test_both test_both.c -le -la -L.
      $ ./test_both
      baz
      baz
      

      If program has it's own symbol foo it gets even better.
      test_own.c:

      #include "a.h"
      #include "e.h"
      #include <stdio.h>
      
      void	foo(void)
      {
      	printf("foo\n");
      }
      
      int	main(void)
      {
      	a_foo();
      	e_foo();
      
      	return 0;
      }
      

      Symbol foo from liba.so and libe.so gets resolved to the foo exported by the program itself:

      $ gcc -o test_own test_own.c -la -le -L.
      $ ./test_own
      foo
      foo
      

      But with a different approach it is possible to sort it out.
      test_rtld.c:

      #include <stdio.h>
      #include <dlfcn.h>
      
      void	foo(void)
      {
      	printf("foo\n");
      }
      
      int	main(void)
      {
      	void	*liba, *libe;
      	void	(*a_foo)(void);
      	void	(*e_foo)(void);
      
      	liba = dlopen("liba.so", RTLD_NOW | RTLD_LOCAL);
      	libe = dlopen("libe.so", RTLD_NOW | RTLD_LOCAL);
      
      	a_foo = dlsym(liba, "foo");
      	e_foo = dlsym(libe, "foo");
      
      	foo();
      	a_foo();
      	e_foo();
      
      	dlclose(liba);
      	dlclose(libe);
      
      	return 0;
      }
      
      $ gcc -o test_rtld test_rtld.c -ldl
      $ ./test_rtld 
      foo
      bar
      baz
      

      Most important question: How is it related to Zabbix?

      Zabbix depends on a number of libraries (cURL, Net-SNMP, OpenIPMI, DB client libraries, ...) which all require encryption libraries as a secondary dependency. Zabbix uses DB client libraries to access its database and links against UnixODBC which loads ODBC drivers which require DB client libraries too. Sometimes they all need different versions of the same library and inability to resolve symbols correctly (slight difference between "bar" and "baz" in the example above) often leads to crashes.

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                Unassigned
                Reporter:
                glebs.ivanovskis Glebs Ivanovskis (Inactive)
              • Votes:
                0 Vote for this issue
                Watchers:
                5 Start watching this issue

                Dates

                • Created:
                  Updated: