On Jan 22 11:05, Corinna Vinschen via Cygwin wrote:
> On Jan 21 20:37, Lavrentiev, Anton (NIH/NLM/NCBI) [C] via Cygwin wrote:
> > By default Cygwin creates the user environment with unlimited
> > processes (and I suppose that any user can just run "bash"
> > unrestricted, thus obtaining the unlimited process resource).  Which
> > then brings up a question about security of the system, as a whole.
> > And so the second part is, is there any way to securely control /
> > restrict the behavior?
> 
> This is not something controlled by Cygwin, rather by the OS.  Cygwin
> provides the POSIX calls getrlimit/setrlimit, but obviously those have
> to be implemented in terms of OS functions or faked.
> 
> The only implemented limits are RLIMIT_AS, RLIMIT_CORE, RLIMIT_NOFILE
> and RLIMIT_STACK, and only RLIMIT_AS is actually calling into the OS to
> install a restriction.
> 
> I just checked the MSDN man pages and it's possible to install a per-job
> process limit.  But that only affects processes inside the job.
> Assuming the process limit is established by a shell, only the child
> processes inside this shell would be affected, so it's basically
> equivalent to a soft limit in the terms of setrlimit.

You got me thinking there...

Unfortunately there's a tricky difference between POSIX soft limits and
the way Windows job limits work.

- Soft rlimits can be changed by any process, up or down, as long as the
  new limit doesn't exceed the hard limit.  A child process inherits the
  limits, but it can change (raise!) them right away, only limited by
  the hard limit.

- Job limits on Windows can be changed by the process, but the limits
  are accumulated if jobs are nested.  The lowest limit wins.

  If a child process inherited a job limit, it can't raise the limit,
  unless it knows the name of the job object *and* has the right to set
  limits on this object.  The problem here is, the current job the
  process is running in, does not necessarily contain the information
  about the real limit.  This information may be in a job object higher
  up in the job hirarchy.  Unfortunately QueryInformationJobObject only
  returns limits defined in this very job, not limits defined higher up.
  And there's no way to fetch info about parent job objects, unless you
  know their names or still have open handles on them.

All in all, that means, the current implementation of
setrlimit(RLIMIT_AS) is not quite correct.  The job object is inherited
by children, but then, if the child defines a new limit, it just creates
a nested job with this limit inside the already existing job.  So the new
limit is ignored if the parent (or grandparent, or ...) job defines a
lower limit.

Unfortunately the child can't just breakaway from a job.  Only the parent
can do this for a child at CreateProcess() time.  So we can't just
breakaway at setrlimit time and create a new, independent job object.

The bottom line is, if we want to do this right, we have to redesign
the entire setrlimit thingy:

- always allow BREAKAWAY_FROM_JOB
- always start the child with BREAKAWAY_FROM_JOB
- always create a new job object in the child after fork/exec implementing
  the soft limits inherited from the parent
- in setrlimit: always just change the current job object


Corinna

-- 
Problem reports:      https://cygwin.com/problems.html
FAQ:                  https://cygwin.com/faq/
Documentation:        https://cygwin.com/docs.html
Unsubscribe info:     https://cygwin.com/ml/#unsubscribe-simple

Reply via email to