Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

*NIX ACE_Process::child is unable to call setrlimit after set*id #1901

Open
likema opened this issue Aug 13, 2022 · 0 comments
Open

*NIX ACE_Process::child is unable to call setrlimit after set*id #1901

likema opened this issue Aug 13, 2022 · 0 comments

Comments

@likema
Copy link
Contributor

likema commented Aug 13, 2022

ACE_Process::child is called after for fork and various set*id on UNIX

If calling setrlimit inside ACE_Process::child, setrlimit might return -1 with errno EPERM because various set*id might limit permissions.

See also:

ACE_TAO/ACE/ace/Process.cpp

Lines 383 to 444 in 44c80da

this->child_id_ = ACE::fork (options.process_name (),
options.avoid_zombies ());
if (this->child_id_ == 0)
{
# if !defined (ACE_LACKS_SETPGID)
// If we're the child and the options specified a non-default
// process group, try to set our pgid to it. This allows the
// <ACE_Process_Manager> to wait for processes by their
// process-group.
if (options.getgroup () != ACE_INVALID_PID
&& ACE_OS::setpgid (0,
options.getgroup ()) < 0)
{
#if !defined (ACE_HAS_THREADS)
// We can't emit this log message because ACELIB_ERROR(), etc.
// will invoke async signal unsafe functions, which results
// in undefined behavior in threaded programs.
ACELIB_ERROR ((LM_ERROR,
ACE_TEXT ("%p.\n"),
ACE_TEXT ("ACE_Process::spawn: setpgid failed.")));
#endif
}
# endif /* ACE_LACKS_SETPGID */
# if !defined (ACE_LACKS_SETREGID)
if (options.getrgid () != (uid_t) -1
|| options.getegid () != (uid_t) -1)
if (ACE_OS::setregid (options.getrgid (),
options.getegid ()) == -1)
{
#if !defined (ACE_HAS_THREADS)
// We can't emit this log message because ACELIB_ERROR(), etc.
// will invoke async signal unsafe functions, which results
// in undefined behavior in threaded programs.
ACELIB_ERROR ((LM_ERROR,
ACE_TEXT ("%p.\n"),
ACE_TEXT ("ACE_Process::spawn: setregid failed.")));
#endif
}
# endif /* ACE_LACKS_SETREGID */
# if !defined (ACE_LACKS_SETREUID)
// Set user and group id's.
if (options.getruid () != (uid_t) -1
|| options.geteuid () != (uid_t) -1)
if (ACE_OS::setreuid (options.getruid (),
options.geteuid ()) == -1)
{
#if !defined (ACE_HAS_THREADS)
// We can't emit this log message because ACELIB_ERROR(), etc.
// will invoke async signal unsafe functions, which results
// in undefined behavior in threaded programs.
ACELIB_ERROR ((LM_ERROR,
ACE_TEXT ("%p.\n"),
ACE_TEXT ("ACE_Process::spawn: setreuid failed.")));
#endif
}
# endif /* ACE_LACKS_SETREUID */
this->child (ACE_OS::getppid ());
}

I suggest that separate the above set*id into a virtual member function named int set_child_uid_gid(ACE_Process_Options&) so that the user can overload it such as

int ...::set_child_uid_gid(ACE_Process_Optioins& opts)
{
    setrlimit ...
    return ACE_Process_Options::set_child_uid_gid(opts);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

1 participant