[comp.unix.wizards] Setting process groups

southard@unc.cs.unc.edu (Scott Southard) (10/27/87)

I am writing a program that creates several child processes, and at some
point I would like to kill all the children, but not the parent, with a
killpg() call.  How do I set the process group id of all the children to
the same id, but not to the id used by the parent?  Can I just pick a
process group id to assign to the children that is different than the
one used by the parent?  How can I determine what process group id's are
not in use?  Any help on this would be appreciated.

Scott Southard
decvax!mcnc!unc!southard

mouse@mcgill-vision.UUCP (der Mouse) (11/18/87)

In article <1765@unc.cs.unc.edu>, southard@unc.cs.unc.edu (Scott Southard) writes:
> I am writing a program that creates several child processes, and at
> some point I would like to kill all the children, but not the parent,
> with a killpg() call.  How do I set the process group id of all the
> children to the same id, but not to the id used by the parent?

setpgrp(2).  (Please mention what sort of system you are on.  In this
case, I assume, since you are talking about process groups, that you
are on a Berkeley derivative UNIX.)

> Can I just pick a process group id to assign to the children that is
> different than the one used by the parent?  How can I determine what
> process group id's are not in use?  Any help on this would be
> appreciated.

The only way, as far as I know, to determine what process groups are in
use is a ps-like program which scans the process table.

However, the convention is that the process group of all processes in a
job is the process ID of the job leader.  Thus, for your application, I
would say you could pick one of the children and use its process ID as
the process group number to give all of them.

					der Mouse

				(mouse@mcgill-vision.uucp)

haynes@ucscc.UCSC.EDU.UUCP (11/25/87)

Incidentally, there's a security hole connected with setpgrp()
in that the system doesn't check whether the pgrp number you
proffer is already in use by somebody else.  So with a little
cleverness you can attach to the pgrp of someone else's process
and proceed to kill it.

haynes@ucscc.ucsc.edu
haynes@ucscc.bitnet
..ucbvax!ucscc!haynes

flee@gondor.psu.edu (Felix Lee) (11/27/87)

In article <1261@saturn.ucsc.edu> haynes@ucscc.UCSC.EDU (Jim Haynes) writes:
> Incidentally, there's a security hole connected with setpgrp()
> in that the system doesn't check whether the pgrp number you
> proffer is already in use by somebody else.

SVID setpgrp() doesn't take an argument.  It's equivalent to Berkeleyish
setpgrp(getpid()).  And anyway you still can't kill a process you don't
own even in Berkeley.  kill -KILL -1 as root will kill everything, but
as joe user will only kill joe's processes.
--
Felix Lee	flee@gondor.psu.edu	*!psuvax1!gondor!flee

allbery@ncoast.UUCP (12/01/87)

As quoted from <1261@saturn.ucsc.edu> by haynes@ucscc.UCSC.EDU.ucsc.edu (99700000):
+---------------
| Incidentally, there's a security hole connected with setpgrp()
| in that the system doesn't check whether the pgrp number you
| proffer is already in use by somebody else.  So with a little
| cleverness you can attach to the pgrp of someone else's process
| and proceed to kill it.
+---------------

...which is why System V won't let you set the pgrp to anything other than
your pid.

Wonderful idea, by the way -- don't you get a warm glow from having posted
an easily-exploited security hole to the Net?  Please be more circumspect
next time.
-- 
Brandon S. Allbery		      necntc!ncoast!allbery@harvard.harvard.edu
 {hoptoad,harvard!necntc,cbosgd,sun!mandrill!hal,uunet!hnsurg3}!ncoast!allbery
			Moderator of comp.sources.misc

chris@mimsy.UUCP (Chris Torek) (12/02/87)

>As quoted from <1261@saturn.ucsc.edu> by haynes@ucscc.UCSC.EDU.ucsc.edu (99700000):
>| Incidentally, there's a security hole connected with setpgrp()
>| in that the system doesn't check whether the pgrp number you
>| proffer is already in use by somebody else.

In article <6305@ncoast.UUCP> allbery@ncoast.UUCP (Brandon Allbery) writes:
>...which is why System V won't let you set the pgrp to anything other than
>your pid.

That is the wrong test, but sufficent.

>Wonderful idea, by the way -- don't you get a warm glow from having posted
>an easily-exploited security hole to the Net?  Please be more circumspect
>next time.

A closed hole:

	p = pfind(uap->pid);
	if (p == 0) {
		u.u_error = ESRCH;
		return;
	}
/* need better control mechanisms for process groups */
	if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) {
		u.u_error = EPERM;
		return;
	}
	p->p_pgrp = uap->pgrp;

In 4.3BSD, you can setpgrp() only to an existing process that is
yours (unless you are root).  The `inferior()' test lets setuid
programs cross uid boundaries as long as they stick within their
process tree.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

duncan@comp.vuw.ac.nz (Duncan McEwan) (12/02/87)

In article <910@mcgill-vision.UUCP> mouse@mcgill-vision.UUCP (der Mouse) writes:
>In article <1765@unc.cs.unc.edu>, southard@unc.cs.unc.edu writes:
>> How can I determine what process group id's are not in use?
>
>The only way, as far as I know, to determine what process groups are in
>use is a ps-like program which scans the process table.
>

Although the man page doesn't say so, killpg(2) behaves like kill(2)
when given signal 0 as its second argument.  That is, it checks if you
would be able to send a signal to the given process group.  So if you
get the error ESRCH back from a "killgp(pgrp, 0)" you know that there
are no processes in that process group.  Not that this info is
particularly useful here - Der Mouse's suggestion of adhering to the
convention of using the process group leader's pid is more sensible
than something like

	for (i = 1; i <= 32767; i++)
		if (killpg (i, 0) < 0 && errno == ESRCH)
			break
	...

BTW, while I was playing around with this, I noticed that the man page
for setpgrp(2) does not say it is an error to put yourself in an existing
process group.  A quick look at the 4.3bsd code shows it isn't (it makes
no checks regarding the process group).  Not that this causes any harm
anyway - if you try to killpg a process group containing processes that
don't belong to you, only your own get killed (unless you happen to
be superuser - something to be said for being careful with programs that
run with uid 0 and use killpg).

One other thing I noticed was that on our pyramid running OSx 4.0,
killpg returns no error if it could kill any of the processes in the
process group.  On a VAX running 4.3bsd it returns EPERM if there are
any that it couldn't kill.  Is OSx's behaviour a hangover from it's
4.2 origins, or is it a Pyramid `enhancement' to the way 4.3 works.
The Pyramid behaviour seems more useful to me.

Duncan

Domain: duncan@comp.vuw.ac.nz		Path: ...!uunet!vuwcomp!duncan

larry@hcr.UUCP (12/02/87)

In article <3134@psuvax1.psu.edu> flee@gondor.psu.edu (Felix Lee) writes:
>SVID setpgrp() doesn't take an argument.  It's equivalent to Berkeleyish
>setpgrp(getpid()).
>--
>Felix Lee	flee@gondor.psu.edu	*!psuvax1!gondor!flee

Actually SVID setpgrp() has an "extra feature" that Berkeley setpgrp(getpid())
does not have - it detaches the process from its controlling terminal.  This
does tend to make it "difficult" to create a pipeline attached to your terminal
but with its own process group.

Larry Philps
HCR Corporation
130 Bloor St. West, 10th floor
Toronto, Ontario
M5S 1N5
(416) 922-1937
{utzoo,utcsri,decvax,ihnp4}!hcr!larry

marki@hpiacla.UUCP (12/04/87)

One method I've used for a parent killing children but not the parent
itself is to set up the parent as the process group leader.  Then the
parent spawns off some children.  The parent is then set to ignore a
signal, say signal 15.

Then have the parent issue a   kill (0, 15);  .  This will kill 
all processes in the process group including the parent.  However,
since the parent set itself up to ignore the signal, it will survive
the signal.  And live on to spawn another day (or child).


Mark

**************************************************************************
* Mark Ikemoto 	            | {ucbvax,hplabs}!hpda!hpiacla!marki  [UUCP] *
* Indus. Appl. Center (IAC) | mark@hpiacla                        [SMTP] *
* Hewlett-Packard Co.       | (408) 746-5453                      [AT&T] *
* 1266 Kifer Road           | 1-746-5453                     [HP-TELNET] *
* Sunnyvale, CA  94086      | "What If..."                [HP-TELEPATHY] *
**************************************************************************

decot@hpisod2.UUCP (12/05/87)

> **************************************************************************
> * Mark Ikemoto	      | {ucbvax,hplabs}!hpda!hpiacla!marki  [UUCP] *
> * Indus. Appl. Center (IAC) | mark@hpiacla			    [SMTP] *
> * Hewlett-Packard Co.	      | (408) 746-5453			    [AT&T] *
> * 1266 Kifer Road	      | 1-746-5453		       [HP-TELNET] *
> * Sunnyvale, CA  94086      | "What If..."		    [HP-TELEPATHY] *
> **************************************************************************

Where's your teleportation address?   We didn't spend all that research
money for nothing, you know!!

Dave Decot
HP Teleportation Lab
hpda!decot

simon@its63b.ed.ac.uk (ECSC68 S Brown CS) (12/07/87)

In article <2990@hcr.UUCP>  writes:
>Actually SVID setpgrp() has an "extra feature" that Berkeley setpgrp(getpid())
>does not have - it detaches the process from its controlling terminal.  This
>does tend to make it "difficult" to create a pipeline attached to your terminal
>but with its own process group.

Well, you can do that by making each such pipeline belong to it's own SXT
device, and have all these SXT's multiplexed onto your *real* terminal.
Instant job-control!

BTW, SVR2 (and 3?) setpgrp() doesn't fully detach a process from its 
controlling tty if this process has already done a setpgrp() previously
(as is the case for a login-shell -- this comes from init and getty).
What it does in this case is to "partially" detach -- so that if you try 
to set up a new controlling terminal, it's not actually a controlling terminal 
at all -- things like terminal-generated signals don't get sent to the process.
Presumably this is just a cretinous bug, and not something more sophisticated.


-- 
--------------------------------------------------
| Simon Brown                                    |
| Laboratory for Foundations of Computer Science |
| Department of Computer Science                 |
| University of Edinburgh, Scotland, UK.         |
--------------------------------------------------
 UUCP:  uunet!mcvax!ukc!lfcs!simon
 ARPA:  simon%lfcs.ed@nss.cs.ucl.ac.uk      "Life's like that, you know"
 JANET: simon@uk.ac.ed.lfcs

klt@arinc0.ARPA (Kermit Tensmeyer) (12/07/87)

In article <2990@hcr.UUCP> larry@hcr.UUCP (Larry Philps) writes:
>
>Actually SVID setpgrp() has an "extra feature" that Berkeley setpgrp(getpid())
>does not have - it detaches the process from its controlling terminal.  This
>does tend to make it "difficult" to create a pipeline attached to your terminal
>but with its own process group.
>
>Larry Philps

That feature bit me in the rear. I have a process server that works to
my satisfaction under BSD but attempting to convert it to SVID is 
danged near impossible. The server uses sockets to communicate with 
clients on the same hosts. These client are background processes that
require terminal/console interaction with the operator (ie full screen
interactions "mount tape for processing and tell which drive", or
"Directory full - redirect message processing where?" etc.) The method
under BSD is to set the process group that is allowed to access the
current console to the master pid of the process which the system 
"thinks" currently own's the terminal. When processes do not have
the terminal the server and associated code set the process group
to zero.

The upshot is that BSD allows any process with the "right" process id
to interact on that terminal. (This is true esp. with c-shell)
On the other hand SVID will let setpgrp be set to only zero and not
the pid of any other process (regardless of the owner bit's).

Is there a real workaround for a "pure" SVID environment? I can't
test it in our "mongrel" mixed BSD/SVID (read Gould UTX) system.

	Kermit Tensmeyer klt@arinc-gw (26.2.0.88)
	(301) 266 2025

james@cantuar.UUCP (J. Collier) (12/09/87)

Sender:

Followup-To:

Distribution:


Chris Torek (chris@mimsy.uucp) writes (from the unix-wizards digest):
>
>In article <13102@comp.vuw.ac.nz> duncan@comp.vuw.ac.nz (Duncan McEwan) writes:
>>BTW, while I was playing around with this, I noticed that the man page
>>for setpgrp(2) does not say it is an error to put yourself in an existing
>>process group.
>>
    (extract from setpgrp(2) manual entry)
>       [EPERM]
>       The effective user ID of the requested process is different
>       from that of the caller and the process is not a descendent
>       of the calling process.
>So it is implicit in the section listing for `EPERM'.

   I don't understand the relevance of this. Perhaps I'm mis-reading
Chris's article; if not..
   Surely the `EPERM' section refers only to the ownership of the
calling process and the target process [ie the process specified by the
first argument to setpgrp()]. As Duncan says, the 4.3 BSD code does not
check the requested process group.

Duncan continues:
>Not that this causes any harm anyway - if you try to killpg a process group
>containing processes that don't belong to you, only your own get killed [..]
   In BSD [at least] I believe the criminally gifted can still find modest
uses for setpgrp() in combination with one or two rather more serious
security flaws. I'm not sure if it can be considered a problem on its
own, though, and it would probably be expensive to tighten. Comments?

   [Aside: I once tried using setpgrp()/getpgrp() for IPC in a
program where process groups were not needed for the usual purposes -
instant parameterised signals, and cheap too!]
-------------------------
James Collier              Internet(ish):  james@cantuar.{uucp,nz}
Computer Science Dept.,    UUCP:           {watmath,munnari,mcvax}!cantuar!james
University of Canterbury,  Spearnet/Janet: j.collier@nz.ac.canty
Christchurch, New Zealand. Office: +64 3 482 009 x8356  Home: +64 3 554 025

chris@mimsy.UUCP (Chris Torek) (12/11/87)

In article <251@cantuar.UUCP> james@cantuar.UUCP (J. Collier) writes:
>... Perhaps I'm mis-reading Chris's article; if not..

No.  I was wrong, and the security hole exist.  Sorry about that.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

csg@pyramid.pyramid.com (Carl S. Gutekunst) (12/17/87)

In article <13102@comp.vuw.ac.nz> duncan@comp.vuw.ac.nz (Duncan McEwan) writes:
>... on our pyramid running OSx 4.0, killpg returns no error if it could kill
>any of the processes in the process group. On a VAX running 4.3bsd it returns
>EPERM if there are any that it couldn't kill.  Is OSx's behaviour a hangover
>from it's 4.2 origins, or is it a Pyramid `enhancement' to the way 4.3 works.

This is straight 4.2BSD. Actually, a lot of OSx is still 4.2BSD where we had
no compelling reason to change it. This is the "if it works, don't fix it"
method of software development. :-)

<csg>