http://www.perlmonks.org?node_id=639568


in reply to System and CGI - File Created but not the Content

You could try to use strace to find out what ameme is doing that could possibly fail under a different user.

Does your system have selinux (or any other fancy security system) enabled?

BTW this doesn't seem to be related to perl at all, so you're rather off topic here.

  • Comment on Re: System and CGI - File Created but not the Content

Replies are listed 'Best First'.
Re^2: System and CGI - File Created but not the Content
by monkfan (Curate) on Sep 18, 2007 at 08:24 UTC
    Hi moritz,
    Yes it seems that it uses SELINUX, since I'm with:
    Enterprise Red Hat 4.1.1-52
    I tried strace with the following snippet in my script.pl:
    system("strace -o $my_repo /home/monkfan/bin/ameme /home/monkfan/publi +c_html/FOO/input_files/input_file.txt param1");
    It doesn't seem to give any error message and it gives the following:
    execve("/home/ewijaya/bin/ameme", ["/home/monkfan/bin/ameme", "numMoti +fs=10", "rcToo=off", "good=/home/monkfan/public_html/FOO"...], [/* 28 + vars */]) = 0 brk(0) = 0x85a6000 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, + 0) = 0x110000 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or d +irectory) open("/etc/ld.so.cache", O_RDONLY) = 0 fstat64(0, {st_mode=S_IFREG|0644, st_size=58761, ...}) = 0 mmap2(NULL, 58761, PROT_READ, MAP_PRIVATE, 0, 0) = 0x111000 close(0) = 0 open("/lib/i686/nosegneg/libm.so.6", O_RDONLY) = 0 read(0, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\20t\223"..., +512) = 512 fstat64(0, {st_mode=S_IFREG|0755, st_size=208364, ...}) = 0 mmap2(0x934000, 155776, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE +, 0, 0) = 0x934000 mmap2(0x959000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ +DENYWRITE, 0, 0x24) = 0x959000 close(0) = 0 open("/lib/i686/nosegneg/libc.so.6", O_RDONLY) = 0 read(0, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0000\177"..., 5 +12) = 512 fstat64(0, {st_mode=S_IFREG|0755, st_size=1589232, ...}) = 0 mmap2(0x7f2000, 1308068, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRIT +E, 0, 0) = 0x7f2000 mmap2(0x92c000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP +_DENYWRITE, 0, 0x13a) = 0x92c000 mmap2(0x92f000, 9636, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ +ANONYMOUS, -1, 0) = 0x92f000 close(0) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, + 0) = 0x120000 set_thread_area({entry_number:-1 -> 6, base_addr:0x1208d0, limit:10485 +75, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_ +not_present:0, useable:1}) = 0 mprotect(0x92c000, 8192, PROT_READ) = 0 mprotect(0x959000, 4096, PROT_READ) = 0 mprotect(0x7ee000, 4096, PROT_READ) = 0 munmap(0x111000, 58761) = 0 brk(0) = 0x85a6000 brk(0x85c7000) = 0x85c7000 fstat64(0, 0xbf9640b0) = -1 EBADF (Bad file descripto +r) mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, + 0) = 0x3d1000 read(0, 0x3d1000, 8192) = -1 EBADF (Bad file descripto +r) write(2, "Short POST input.", 17) = -1 EBADF (Bad file descripto +r) write(2, "\n", 1) = -1 EBADF (Bad file descripto +r) exit_group(-1) = ?

    Regards,
    Edward
      Yes it seems that it uses SELINUX

      That explains a lot.

      Selinux provides "security contexts", and everything that a webserver may run is in the server's security context.

      This means that it is not allowed to do a whole lot of things, even if the file permissions allow it.

      Which in turn means that virtually everything can go wrong.

      I'd recommend to write a daemon that runs a normal user, validates it input and executes the program. The CGI script and the daemon can communicate via TCP or named pipes.

        ... write a daemon that runs a normal user, validates it input and executes the program. The CGI script and the daemon can communicate via TCP or named pipes.
        How do you do that? Using Perl script? Do you have any example of it?
        Sorry I'm quite new to this, so obvious thing may not be obvious to me.

        Regards,
        Edward

      I've written some CGI scripts under Fedora Core 4 (similar to Red hat) running SELinux, and there are some things you have to watch out for.

      The easiest way to verify if this is the problem: log in as root, then use this command:

      setenforce 0

      This will turn off the enforcement of SELinux security checks - but not the checking. Errors will continue to be logged. On my system the default location was /var/log/messages (this may vary from one flavor of linux to another).

      If the error with the CGI script goes away, you know it's SELinux. The log file should help give you a clue as to where the problem is. Turn enforcing back on with:

      setenforce 1

      If you want a CGI script to be able to write a file, the directory it's writing to much have read and execute permission:

      chmod 755 output_dir

      It must also have the proper SELinux security context:

      chcon -t httpd_sys_content_t output_dir

      Also, you have to remember that the CGI script runs with the user id of the web server. For apache, this is usually 'nobody' or 'www'. Make sure this user has permission to run the external executable (ameme?). Then make sure the executable has the the proper security context:

      chmod 755 ameme
      chcon -t httpd_sys_script_exec_t ameme

      You can use "ls -lZ" to check the current security context settings.

      Note also that the log file will contain errors that say what the expected context is, in the case SELinux blocks something from running. It will also give the path to the offending directory or executable.

        I have a similar situation which I am about to post under "System and CGI - File Created but not the Content (Similar Situation)". It is different becasue here perl is the program trying to write and SELinux was set off all the way back in rc.local. If you guys would have a look it would be greatly appreciated!