ruby-changes:35304
From: akr <ko1@a...>
Date: Thu, 4 Sep 2014 23:56:17 +0900 (JST)
Subject: [ruby-changes:35304] akr:r47386 (trunk): * process.c (has_privilege): New function.
akr 2014-09-04 23:56:03 +0900 (Thu, 04 Sep 2014) New Revision: 47386 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=47386 Log: * process.c (has_privilege): New function. (retry_fork_async_signal_safe): Don't use vfork() for privileged process. * configure.in (getresuid): Check function. (getresgid): Ditto. Modified files: trunk/ChangeLog trunk/configure.in trunk/process.c Index: configure.in =================================================================== --- configure.in (revision 47385) +++ configure.in (revision 47386) @@ -1996,6 +1996,8 @@ AC_CHECK_FUNCS(getpgid) https://github.com/ruby/ruby/blob/trunk/configure.in#L1996 AC_CHECK_FUNCS(getpgrp) AC_CHECK_FUNCS(getpriority) AC_CHECK_FUNCS(getpwnam_r) +AC_CHECK_FUNCS(getresgid) +AC_CHECK_FUNCS(getresuid) AC_CHECK_FUNCS(getrlimit) AC_CHECK_FUNCS(getsid) AC_CHECK_FUNCS(gettimeofday) # for making ac_cv_func_gettimeofday Index: ChangeLog =================================================================== --- ChangeLog (revision 47385) +++ ChangeLog (revision 47386) @@ -1,3 +1,12 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Thu Sep 4 23:39:52 2014 Tanaka Akira <akr@f...> + + * process.c (has_privilege): New function. + (retry_fork_async_signal_safe): Don't use vfork() for privileged + process. + + * configure.in (getresuid): Check function. + (getresgid): Ditto. + Thu Sep 4 20:22:14 2014 Laurent Arnoud <laurent@s...> * test/pathname/test_pathname.rb: added testcase for Pathname#mountpoint. Index: process.c =================================================================== --- process.c (revision 47385) +++ process.c (revision 47386) @@ -3277,6 +3277,72 @@ recv_child_error(int fd, int *errp, char https://github.com/ruby/ruby/blob/trunk/process.c#L3277 return size != 0; } +static int +has_privilege(void) +{ + /* + * has_privilege() is used to choose vfork() or fork(). + * + * If the process has privilege, the parent process or + * the child process can change UID/GID. + * If vfork() is used to create the child process and + * the parent or child process change effective UID/GID, + * different privileged processes shares memory. + * It is a bad situation. + * So, fork() should be used. + */ + + rb_uid_t ruid, euid; + rb_gid_t rgid, egid; + +#if defined HAVE_ISSETUGID + if (issetugid()) + return 1; +#endif + +#ifdef HAVE_GETRESUID + { + int ret; + rb_uid_t suid; + ret = getresuid(&ruid, &euid, &suid); + if (ret == -1) + rb_sys_fail("getresuid(2)"); + if (ruid != suid) + return 1; + } +#else + { + rb_uid_t ruid = getuid(); + rb_uid_t euid = geteuid(); + } +#endif + + if (ruid == 0 || ruid != euid) + return 1; + +#ifdef HAVE_GETRESGID + { + int ret; + rb_gid_t sgid; + ret = getresgid(&rgid, &egid, &sgid); + if (ret == -1) + rb_sys_fail("getresgid(2)"); + if (rgid != sgid) + return 0; + } +#else + { + rb_gid_t rgid = getgid(); + rb_gid_t egid = getegid(); + } +#endif + + if (rgid == 0 || rgid != egid) + return 1; + + return 0; +} + static rb_pid_t retry_fork_async_signal_safe(int *status, int *ep, int (*chfunc)(void*, char *, size_t), void *charg, @@ -3289,7 +3355,10 @@ retry_fork_async_signal_safe(int *status https://github.com/ruby/ruby/blob/trunk/process.c#L3355 while (1) { prefork(); #ifdef HAVE_WORKING_VFORK - pid = vfork(); + if (!has_privilege()) + pid = vfork(); + else + pid = fork(); #else pid = fork(); #endif -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/