iconv_open fails when suid bit is on

2012-02-13 Thread Elazar Leibovich
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

2012-02-13 Thread guy keren


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

2012-02-13 Thread Yedidyah Bar-David
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

2012-02-13 Thread Oleg Goldshmidt

 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]

2012-02-13 Thread Elazar Leibovich
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