iconv_open fails when suid bit is on
In RHEL 5 system, libc-6, I'm seeing the following strange phenomena $ cat iconv_test.c #include stdio.h #include errno.h #include fcntl.h #include iconv.h void iconv_test() { static int nr = 0; iconv_t iconv = iconv_open(MSCP949,UTF-8); //iconv_t iconv = iconv_open(UTF-16,UTF-8); if (iconv == (iconv_t)-1) { puts( can't initialize iconv); } else { puts( iconv open success! ); } nr++; } int main(int argc,char **argv) { iconv_test(); return 0; } $ gcc iconv_test.c $ ./a.out iconv open success! $ sudo su - # chown root:foo a.out # chmod 4555 a.out # su foo - $ ./a.out can't initialize iconv $ strace ./a.out 2/dev/null iconv open success! iconv_open on UTF-16 to UTF-8 succeeds! This phenomena doesn't happen in recent Ubuntu. I'm not familiar with the inner workings of iconv, but stracing a good iconv run reveals it dlopen so files according to the chosen encodings, maybe it's related. 1) I'll be glad for any thoughts or ideas how to debug this issue, other than downloading the libc source rpm, compiling it, LD_PRELOAD, and hope the problem will be recreated. 2) If someone can test this on a RHEL-5 machine, and report if it happens to him too, it could be helpful. Thanks, ___ Linux-il mailing list Linux-il@cs.huji.ac.il http://mailman.cs.huji.ac.il/mailman/listinfo/linux-il
Re: iconv_open fails when suid bit is on
running strace on an suid binary - ignores the 'suid' bit. so the test with strace is not relevant. --guy On 02/13/2012 10:56 AM, Elazar Leibovich wrote: In RHEL 5 system, libc-6, I'm seeing the following strange phenomena $ cat iconv_test.c #include stdio.h #include errno.h #include fcntl.h #include iconv.h void iconv_test() { static int nr = 0; iconv_t iconv = iconv_open(MSCP949,UTF-8); //iconv_t iconv = iconv_open(UTF-16,UTF-8); if (iconv == (iconv_t)-1) { puts( can't initialize iconv); } else { puts( iconv open success! ); } nr++; } int main(int argc,char **argv) { iconv_test(); return 0; } $ gcc iconv_test.c $ ./a.out iconv open success! $ sudo su - # chown root:foo a.out # chmod 4555 a.out # su foo - $ ./a.out can't initialize iconv $ strace ./a.out 2/dev/null iconv open success! iconv_open on UTF-16 to UTF-8 succeeds! This phenomena doesn't happen in recent Ubuntu. I'm not familiar with the inner workings of iconv, but stracing a good iconv run reveals it dlopen so files according to the chosen encodings, maybe it's related. 1) I'll be glad for any thoughts or ideas how to debug this issue, other than downloading the libc source rpm, compiling it, LD_PRELOAD, and hope the problem will be recreated. 2) If someone can test this on a RHEL-5 machine, and report if it happens to him too, it could be helpful. Thanks, ___ Linux-il mailing list Linux-il@cs.huji.ac.il http://mailman.cs.huji.ac.il/mailman/listinfo/linux-il ___ Linux-il mailing list Linux-il@cs.huji.ac.il http://mailman.cs.huji.ac.il/mailman/listinfo/linux-il
Re: iconv_open fails when suid bit is on
On Mon, Feb 13, 2012 at 11:45:26AM +0200, guy keren wrote: running strace on an suid binary - ignores the 'suid' bit. so the test with strace is not relevant. Indeed, and to strace programs that do this, I do something like that: Open a root shell: # echo $$ let's say it printed 1234, so its pid is 1234 Open another root shell: # strace -f -o /tmp/trace1 -p 1234 Now, inside 1234 run what you need to debug. 'strace -f -p pid' does follow correctly the uid changes caused by suid binaries and setuid etc. Some years ago I played a bit with the more obvious # strace -f su - user -c program which then did not work well. Not sure if this was changed. '-f -p pid' always worked for me. Sorry I can't comment about the actual OP quesion, but just a guess - perhaps it's on nfs? -- Didi On 02/13/2012 10:56 AM, Elazar Leibovich wrote: In RHEL 5 system, libc-6, I'm seeing the following strange phenomena $ cat iconv_test.c #include stdio.h #include errno.h #include fcntl.h #include iconv.h void iconv_test() { static int nr = 0; iconv_t iconv = iconv_open(MSCP949,UTF-8); //iconv_t iconv = iconv_open(UTF-16,UTF-8); if (iconv == (iconv_t)-1) { puts( can't initialize iconv); } else { puts( iconv open success! ); } nr++; } int main(int argc,char **argv) { iconv_test(); return 0; } $ gcc iconv_test.c $ ./a.out iconv open success! $ sudo su - # chown root:foo a.out # chmod 4555 a.out # su foo - $ ./a.out can't initialize iconv $ strace ./a.out 2/dev/null iconv open success! iconv_open on UTF-16 to UTF-8 succeeds! This phenomena doesn't happen in recent Ubuntu. I'm not familiar with the inner workings of iconv, but stracing a good iconv run reveals it dlopen so files according to the chosen encodings, maybe it's related. 1) I'll be glad for any thoughts or ideas how to debug this issue, other than downloading the libc source rpm, compiling it, LD_PRELOAD, and hope the problem will be recreated. 2) If someone can test this on a RHEL-5 machine, and report if it happens to him too, it could be helpful. Thanks, ___ Linux-il mailing list Linux-il@cs.huji.ac.il http://mailman.cs.huji.ac.il/mailman/listinfo/linux-il ___ Linux-il mailing list Linux-il@cs.huji.ac.il http://mailman.cs.huji.ac.il/mailman/listinfo/linux-il ___ Linux-il mailing list Linux-il@cs.huji.ac.il http://mailman.cs.huji.ac.il/mailman/listinfo/linux-il
Re: iconv_open fails when suid bit is on
2) If someone can test this on a RHEL-5 machine, and report if it happens to him too, it could be helpful. FWIW, I see no problems on either RHEL 5.4 or Fedora 15. -- Oleg Goldshmidt | p...@goldshmidt.org o...@goldshmidt.org ___ Linux-il mailing list Linux-il@cs.huji.ac.il http://mailman.cs.huji.ac.il/mailman/listinfo/linux-il
Re: iconv_open fails when suid bit is on [SOLVED]
On Mon, Feb 13, 2012 at 12:22 PM, Yedidyah Bar-David linux...@didi.bardavid.org wrote: Indeed, and to strace programs that do this, I do something like that: Thanks! Worked like a charm. Here's the trouble: [pid 31526] open($ORIGIN/tls/i686/sse2/libKSC.so, O_RDONLY) = -1 ENOENT (No such file or directory) [pid 31526] open($ORIGIN/tls/i686/libKSC.so, O_RDONLY) = -1 ENOENT (No such file or directory) [pid 31526] open($ORIGIN/tls/sse2/libKSC.so, O_RDONLY) = -1 ENOENT (No such file or directory) [pid 31526] open($ORIGIN/tls/libKSC.so, O_RDONLY) = -1 ENOENT (No such file or directory) [pid 31526] open($ORIGIN/i686/sse2/libKSC.so, O_RDONLY) = -1 ENOENT (No such file or directory) [pid 31526] open($ORIGIN/i686/libKSC.so, O_RDONLY) = -1 ENOENT (No such file or directory) [pid 31526] open($ORIGIN/sse2/libKSC.so, O_RDONLY) = -1 ENOENT (No such file or directory) [pid 31526] open($ORIGIN/libKSC.so, O_RDONLY) = -1 ENOENT (No such file or directory) ... (fallback to other library locations) vs a good run of open(/usr/lib/gconv/gconv-modules.cache, O_RDONLY) = 3 open(/usr/lib/gconv/UHC.so, O_RDONLY) = 3 open(/usr/lib/gconv/tls/i686/sse2/libKSC.so, O_RDONLY) = -1 ENOENT (No such file or directory) open(/usr/lib/gconv/tls/i686/libKSC.so, O_RDONLY) = -1 ENOENT (No such file or directory) open(/usr/lib/gconv/tls/sse2/libKSC.so, O_RDONLY) = -1 ENOENT (No such file or directory) open(/usr/lib/gconv/tls/libKSC.so, O_RDONLY) = -1 ENOENT (No such file or directory) open(/usr/lib/gconv/i686/sse2/libKSC.so, O_RDONLY) = -1 ENOENT (No such file or directory) open(/usr/lib/gconv/i686/libKSC.so, O_RDONLY) = -1 ENOENT (No such file or directory) open(/usr/lib/gconv/sse2/libKSC.so, O_RDONLY) = -1 ENOENT (No such file or directory) open(/usr/lib/gconv/libKSC.so, O_RDONLY) = 3 Some googling lead me to another software having this problem: 54 #ifdef SECURE_MAN_UID 55/* iconv_open may not work correctly in setuid processes; in GNU 56 * libc, gconv modules may be linked against other gconv modules and 57 * rely on RPATH $ORIGIN to load those modules from the correct 58 * path, but $ORIGIN is disabled in setuid processes. It is 59 * impossible to reset libc's idea of setuidness without creating a 60* whole new process image. Therefore, if the calling process is 61* setuid, we must drop privileges and execute manconv. 62 * 63 * If dropping privileges fails, fall through to the in-process 64* code, as in some situations it may actually manage to work. 65 */ Alas, complexityhttp://neugierig.org/software/blog/2011/04/complexity.htmlis indeed a problem. To make a long story short: 1) The linux linker let you add to rpath (so search path for a specific binary) the symbol $ORIGIN, which is resolved in runtime to the binaries' path. 2) iconv_open uses this feature to locate additional library at run time (at least in my version). 3) This feature doesn't work when running suid binaries (at least in my CentOS specific version) for security reasonshttp://seclists.org/fulldisclosure/2010/Oct/257 . 4) Thus iconv_open don't find it's library path, assumes that no such encoding exist on the system, and fails with illegal argument errno. A possible workaround is to create symbolic links to all files in /usr/lib/gconv in the ldd path, enabling iconv to find them even without using the $ORIGIN ldd feature. For the record, my glibc version is glibc-2.5-49.el5_5.7. Thanks! ___ Linux-il mailing list Linux-il@cs.huji.ac.il http://mailman.cs.huji.ac.il/mailman/listinfo/linux-il