ldopen failing with relative path when linux capability is set
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
glibc (Ubuntu) |
Confirmed
|
Undecided
|
Unassigned |
Bug Description
Call to ldopen is failing when a POSIX capability is set on the file and a $ORIGIN relative path is given.
Relative path is used in some major tool such as the Java VM when required to grant bind on port less than 1024 without giving the su rights (for obvious security reasons). The impacted applications are : applications server, mail servers, etc ... all running Java.
See http://
For capability priviledge port bind, the only work-around are :
- patch the binary containing the $ORIGIN an replace it with code absolute path (ugly, isn't it?)
- use a iptable PAT redirection (prevent dynamic bind as you have to know beforehand the port value to create a rule) : make configuration complex and bring some limitations.
For other capabilities, there might be no workaround but to go with the setuid :(
Here is example of a program helping to reveal the potential bug :
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <unistd.h>
int main(int argc, char *argv[]){
void *handle;
double (*cosine)(double);
char *error;
printf("UID=%d EffUID=%d\n", getuid(), geteuid());
handle = dlopen (argv[1], RTLD_LAZY);
if (!handle) {
fprintf (stderr, "%s\n", dlerror());
exit(1);
}
dlerror(); /* Clear any existing error */
cosine = dlsym(handle, argv[2]);
if ((error = dlerror()) != NULL) {
fprintf (stderr, "%s\n", error);
exit(1);
}
printf ("res:%f\n", (*cosine)(2.0));
dlclose(
return 0;
}
Let's compile that :
gcc -o bug-cap-origin -ldl bug-cap-origin.c
cp bug-cap-origin ~
cd ~
Step 1 : Initial checkings
getcap bug-cap-origin
-> empty result (= no capabilities set at this time)
./bug-cap-origin '/usr/lib64/
-> OK: display the sin result
./bug-cap-origin '$ORIGIN/
-> OK: display the sin result
sudo ./bug-cap-origin '$ORIGIN/
-> OK: display the sin result
Step 2 : Assign a capability to the file and check again ... to get the problem
sudo setcap cap_net_
--> empty result (=capability was set)
./bug-cap-origin '/usr/lib64/
-> OK: display the sin result
./bug-cap-origin '$ORIGIN/
-> KO !!! : Message displayed = "$ORIGIN/
sudo ./bug-cap-origin '$ORIGIN/
-> OK: display the sin result
Step 3 : Removing the capability solve the problem
sudo setcap -r bug-cap-origin
-> empty result (= capability was removed)
./bug-cap-origin '/usr/lib64/
-> OK: display the sin result
./bug-cap-origin '$ORIGIN/
-> OK: display the sin result
sudo ./bug-cap-origin '$ORIGIN/
-> OK: display the sin result
Am I wrong somewhere or is the ldopen having issues with relative path when Linux capabilities are set ?
Test was done on :
ld-2.11.1
gcc 4.3.3
Linux 2.6.32-20-generic
Ubuntu 10.04 (latest dev)
I can confirm.
I need to give Firefox CAP_FOWNER to get it to stop failing to install extensions when utime() fails on ntfs-3g -- and then I get "libxul.so ... no such file or directory".
Also, do you mean dlopen, not ldopen?