/proc/self/fd looks like a cleaver way to be sure all fds are closed, i 
did not think about that.

Nice work!

/Jimmy


Ismael Luceno skrev:
> dragoran escribió:
>> Hello,
>> Since the fedora-extras review for initng started work has started to 
>> add selinux support for initng. I started by porting the sysvinit 
>> patches to initng. This made it possible that selinux loads its 
>> policy at all.
>> But then we run into an other problem:
>> The selinux policy does not allow initng to do what it should do (=> 
>> does not work in enforcing mode).
>> This is whats still missing until today.
>> There is a bugreport in redhats bugzilla about this issue:
>> https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=179761
>> One of the problems is that there are some fd leaks in initng.
>> When a daemon or a script gets started in its own selinux domain it 
>> picks up one of the still open fds but they are not in its domain 
>> which causes problems (not allowed to use them; does not work 
>> correctly).
>> I have no idea how to fix this thats why I am asking here...
>> Any ideas how to get rid of the fd leaks issue?
>> When this is solved we can see what avs are remaining and if they are 
>> fixable inside initng or not. If not we can modificy the policy to 
>> work with this.
>
> The attached patch _may_ fix the fd-leaking issue.
> But be careful, it's untested.
>
> ------------------------------------------------------------------------
>
> Index: plugins/bash_launcher/initng_bash_launcher.c
> ===================================================================
> --- plugins/bash_launcher/initng_bash_launcher.c      (revision 4826)
> +++ plugins/bash_launcher/initng_bash_launcher.c      (working copy)
> @@ -48,6 +48,7 @@
>  #include <initng_env_variable.h>
>  #include <initng_static_event_types.h>
>  #include <initng_event_hook.h>
> +#include <initng_fd.h>
>  
>  INITNG_PLUGIN_MACRO;
>  
> @@ -168,13 +169,10 @@
>  
>       if ((pid_fork = initng_fork(s, process_to_exec)) == 0)
>       {
> -             int i;
> -
>               /* run afterfork hooks from other plugins */
>               initng_fork_aforkhooks(s, process_to_exec);
>  
> -             for (i = 3; i < 1024; i++)
> -                     close(i);
> +             initng_fd_close_all_afork();
>  
>               /* execute code */
>               bash_this(script, s, args);
> Index: plugins/simple_launcher/initng_simple_launcher.c
> ===================================================================
> --- plugins/simple_launcher/initng_simple_launcher.c  (revision 4826)
> +++ plugins/simple_launcher/initng_simple_launcher.c  (working copy)
> @@ -45,6 +45,7 @@
>  #include <initng_env_variable.h>
>  #include <initng_static_event_types.h>
>  #include <initng_event_hook.h>
> +#include <initng_fd.h>
>  
>  INITNG_PLUGIN_MACRO;
>  
> @@ -183,11 +184,8 @@
>               /* run g.AFTER_FORK from other plugins */
>               initng_fork_aforkhooks(s, process_to_exec);
>  
> -             int i;
> +             initng_fd_close_all_afork();
>  
> -             for (i = 3; i < 1024; i++)
> -                     close(i);
> -
>  #ifdef DEBUG
>               D_("FROM_FORK simple_exec(%i,%s, ...);\n", argc, argv[0]);
>               /*D_argv("simple_exec: ", argv); */
> @@ -323,7 +321,7 @@
>       argv[0] = exec;
>  
>       ret=simple_exec_fork(process, service, argc, argv);
> -     
> +
>       // Do some cleanup
>       if(exec_args)
>           fix_free(exec_args, exec_args_unfixed);
> @@ -431,7 +429,7 @@
>                       fix_free(exec_fixed, exec);
>                       return (FALSE);
>               }
> -             
> +
>               free(argv[0]);
>               argv[0] = argv0; // Check this before freeing!
>       }
> @@ -441,21 +439,21 @@
>       result = simple_exec_fork(process, service, argc, argv);
>  
>       /* clean up */
> -     
> +
>       // First free the fixed argv0 if its not a plain link to argv[0]
>       if (argv0 && argv0 != argv[0])
>       {
>               free(argv0);
>       }
>       argv0 = NULL;
> -     
> +
>       // Later free the big argv array
> -     split_delim_free(argv); 
> +     split_delim_free(argv);
>       argv = NULL;
> -     
> +
>       // then free this one.
>       fix_free(exec_fixed, exec);
> - 
> +
>       /* return result */
>       if (result == FAIL)
>               return (FALSE);
> Index: src/initng_fd.c
> ===================================================================
> --- src/initng_fd.c   (revision 4826)
> +++ src/initng_fd.c   (working copy)
> @@ -25,6 +25,8 @@
>  #include <errno.h>
>  #include <string.h>
>  #include <fcntl.h>                                                   /* 
> fcntl() */
> +#include <sys/types.h>
> +#include <dirent.h>
>  
>  #include "initng.h"
>  #include "initng_global.h"
> @@ -271,7 +273,7 @@
>               pi->buffer_len = 9000;                          /* shortened by 
> 1000 chars */
>               pi->buffer[9000] = '\0';                        /* shortened by 
> 1000 chars */
>       }
> -     
> +
>       D_("function done...");
>  }
>  
> @@ -543,3 +545,27 @@
>  
>       return;
>  }
> +
> +void initng_fd_close_all_afork(void)
> +{
> +     DIR * dir;
> +     struct dirent * entry;
> +     int fd;
> +
> +     dir = opendir("/proc/self/fd");
> +     if (!dir)
> +     {
> +             W_("Can not open /proc/self/fd!\n");
> +
> +             for (fd = 3; fd < 1024; fd++)
> +                     close(fd);
> +             return;
> +     }
> +
> +     while ((entry = readdir(dir)))
> +     {
> +             fd = atoi(entry->d_name);
> +             if (fd > 2)
> +                     close(fd);
> +     }
> +}
> Index: src/initng_fd.h
> ===================================================================
> --- src/initng_fd.h   (revision 4826)
> +++ src/initng_fd.h   (working copy)
> @@ -19,12 +19,15 @@
>  
>  #ifndef INITNG_FD_H
>  #define INITNG_FD_H
> +#include "initng_active_db.h"
> +#include "initng_process_db.h"
>  
>  #define STILL_OPEN(fd) (fcntl(fd, F_GETFD)>=0)
>  
> -void initng_fd_process_read_input(active_db_h * service, process_h * p,
> -                                                               pipe_h * 
> pipe);
> +void initng_fd_process_read_input(active_db_h * service, process_h * p, 
> pipe_h * pipe);
>  void initng_fd_close_all(void);
>  void initng_fd_plugin_poll(int timeout);
>  
> +void initng_fd_close_all_afork(void);
> +
>  #endif
> Index: src/main.c
> ===================================================================
> --- src/main.c        (revision 4843)
> +++ src/main.c        (working copy)
> @@ -413,7 +413,10 @@
>       /* if this is real init */
>       if (g.i_am == I_AM_INIT)
>       {
> -             /*load selinux policy and rexec*/
> +             /* mount /proc */
> +             mount("proc", "/proc", "proc", 0, NULL);
> +
> +             /* load selinux policy and rexec */
>  #ifdef SELINUX
>               if ((fopen("/selinux/enforce", "r")) != NULL) goto BOOT;
>               int enforce = -1;
>   

-- 
_______________________________________________
Initng mailing list
[email protected]
http://jw.dyndns.org/mailman/listinfo/initng

Reply via email to