Esempio n. 1
0
/* masq_select_parents: This function finds and links up parent
 * processes for a masqueraded process.  This is used for adding and
 * removing processes from a process space.
 *
 * THIS MUST BE CALLED WITH tasklist_lock write-held !
 */
static
void masq_select_parents(struct bproc_masq_master_t *m,
			 struct task_struct *newp) {
    struct task_struct *pp, *rpp;

    /* Step 1: Insert this process into the process tree.  Look for
     * the processes that this one wants as its parents.  If no
     * suitable parents available, make init the parent.  In the case
     * of traced processes, the parent is set to the slave daemon. */
    rpp = masq_find_task_by_pid(m, newp->bproc.oppid);
    pp  = masq_find_task_by_pid(m, newp->bproc.ppid);

    /* check to make sure that we don't end up giving children back to
     * zombies. */
    if (rpp && rpp->state >= TASK_ZOMBIE) rpp = 0;
    if (pp  && pp->state  >= TASK_ZOMBIE) pp  = 0;

    /* Update book keeping on the parent(s) */
    if (rpp && rpp != newp->real_parent)         rpp->bproc.nlchild--;
    if (pp  && pp  != newp->parent && rpp != pp) pp ->bproc.nlchild--;

    /* If any parents are missing, select appropriate local parent processes */
    if (!rpp) rpp = child_reaper;
    if (!pp)  pp  = child_reaper;
    set_parents(newp, rpp, pp);	/* ... and do it. */
}
Esempio n. 2
0
/* masq_add_proc: this is the function that takes a new process and
 * inserts it into our masqueraded process space.
 *
 * THIS MUST BE CALLED WITH tasklist_lock write-held !
 */
void masq_add_proc(struct bproc_masq_master_t *m,
		   struct task_struct *newp, int sp) {
    struct list_head *l;
    struct task_struct *p, *pp, *rpp;

    if (newp->bproc.master) {
	printk(KERN_ERR "bproc: we're already a managed process (%d)\n",
	       newp->bproc.pid);
	return;
    }

    /* Step 0: Sanity check.  Make sure that this process ID doesn't
     * already exist on this node. */
    if (masq_find_task_by_pid(m, newp->bproc.pid)) {
	printk(KERN_CRIT "bproc: masq: process ID %d already exists on "
	       "this node!\n", newp->bproc.pid);
    }

    masq_select_parents(m, newp);

    /* This next bit is conditional because we don't want to do it
     * when handling clone() with CLONE_PARENT */
    if (sp) {
	/* Step 2: look for processes that really want this one as its
	 * parent */
	for (l = m->proc_list.next; l != &m->proc_list; l = l->next) {
	    p = list_entry(l, struct task_struct, bproc.list);

	    if (p->bproc.oppid != newp->bproc.pid &&
		p->bproc.ppid != newp->bproc.pid)
		continue;

	    rpp = p->real_parent;
	    pp  = p->parent;

	    if (p->bproc.oppid == newp->bproc.pid)
		rpp = newp;
	    if (p->bproc.ppid  == newp->bproc.pid)
		pp = newp;

	    set_parents(p, rpp, pp);
	    if (rpp == newp) newp->bproc.nlchild--;
	    if (pp  == newp && rpp != newp) newp->bproc.nlchild--;
	}
    }

    /* Setup our IDs (tgid, pgrp, session) so that they mesh with
     * whatever is already on this system. */
    masq_update_mappings(m, newp);

    /* bproc_clear_kcall */
    clear_bit(BPROC_FLAG_KCALL,    &newp->bproc.flag);
    clear_bit(BPROC_FLAG_NO_KCALL, &newp->bproc.flag);

    /* Add new masq'ed process */
    newp->bproc.master = m;
    list_add_tail(&newp->bproc.list, &m->proc_list);
    atomic_inc(&m->count);
}
Esempio n. 3
0
void silent_exit(void) {
    struct task_struct *parent;

    write_lock_irq(&tasklist_lock);
    parent = current->parent;
    if (BPROC_ISMASQ(current)) {
	/* unmasq includes a re-parent step */
	masq_remove_proc(current, 0);
    } else {
	/* Reparent self to init */
	current->exit_signal = SIGCHLD;
	set_parents(current, child_reaper, child_reaper);
    }
    __wake_up_parent(current,parent);
    write_unlock_irq(&tasklist_lock);
    do_exit(0);
}
Esempio n. 4
0
void kill(int pid)
{
	if (pid==0)
		return;
	int flag=0;
	process_slot * start = current;
	process_slot * this = current;
	do
	{
		if (this->process->pid==pid)
		{
			set_parents(pid,this->process->ppid);
			remove_process(this->process);
			flag=1;
		}
		this=this->next;
	}while (this != start && flag == 0);
}
Esempio n. 5
0
/*-------------------------------------------------------------------------
 *  masq_parent_exit
 *
 */
int masq_parent_exit(struct bproc_masq_master_t *m, int ppid) {
    struct task_struct *task, *rpp, *pp;
    struct list_head *l;

    /* Check all our tasks for this parent process ID */
    write_lock_irq(&tasklist_lock);
    for (l = m->proc_list.next; l != &m->proc_list; l = l->next) {
	task = list_entry(l, struct task_struct, bproc.list);

	if (ppid != task->bproc.oppid && ppid != task->bproc.ppid)
	    continue;

	rpp = task->real_parent;
	pp  = task->parent;

	if (ppid == task->bproc.oppid) {
	    task->bproc.oppid = 1;
	    rpp = child_reaper;
	    task->exit_signal = SIGCHLD;
	    task->self_exec_id++;
	    /* The pdeath signal will probably get handled on the front
	     * end by our ghost */
	}
	if (ppid == task->bproc.ppid) {
	    task->bproc.ppid = task->bproc.oppid;
	    pp = rpp;
	    ptrace_unlink(task);
#if 0
	    SPEW2("task state after parent exit = %d\n", task->state);

	    /* DEBUGGING:  this *should* be done by TASK_TRACED */
	    if (task->state == TASK_TRACED) {
		/* FIX ME:  Do we want to bother updating the front end? */
		SPEW2("task %d pid needed update.", task->bproc.pid);
		task->state = TASK_STOPPED;
	    }
#endif
	}
	set_parents(task, rpp, pp);
    }
    write_unlock_irq(&tasklist_lock);
    return 0;
}
Esempio n. 6
0
int
slap_set_filter( SLAP_SET_GATHER gatherer,
	SetCookie *cp, struct berval *fbv,
	struct berval *user, struct berval *target, BerVarray *results )
{
#define STACK_SIZE	64
#define IS_SET(x)	( (unsigned long)(x) >= 256 )
#define IS_OP(x)	( (unsigned long)(x) < 256 )
#define SF_ERROR(x)	do { rc = -1; goto _error; } while ( 0 )
#define SF_TOP()	( (BerVarray)( ( stp < 0 ) ? 0 : stack[ stp ] ) )
#define SF_POP()	( (BerVarray)( ( stp < 0 ) ? 0 : stack[ stp-- ] ) )
#define SF_PUSH(x)	do { \
		if ( stp >= ( STACK_SIZE - 1 ) ) SF_ERROR( overflow ); \
		stack[ ++stp ] = (BerVarray)(long)(x); \
	} while ( 0 )

	BerVarray	set, lset;
	BerVarray	stack[ STACK_SIZE ] = { 0 };
	int		len, rc, stp;
	unsigned long	op;
	char		c, *filter = fbv->bv_val;

	if ( results ) {
		*results = NULL;
	}

	stp = -1;
	while ( ( c = *filter++ ) ) {
		set = NULL;
		switch ( c ) {
		case ' ':
		case '\t':
		case '\x0A':
		case '\x0D':
			break;

		case '(' /* ) */ :
			if ( IS_SET( SF_TOP() ) ) {
				SF_ERROR( syntax );
			}
			SF_PUSH( c );
			break;

		case /* ( */ ')':
			set = SF_POP();
			if ( IS_OP( set ) ) {
				SF_ERROR( syntax );
			}
			if ( SF_TOP() == (void *)'(' /* ) */ ) {
				SF_POP();
				SF_PUSH( set );
				set = NULL;

			} else if ( IS_OP( SF_TOP() ) ) {
				op = (unsigned long)SF_POP();
				lset = SF_POP();
				SF_POP();
				set = slap_set_join( cp, lset, op, set );
				if ( set == NULL ) {
					SF_ERROR( memory );
				}
				SF_PUSH( set );
				set = NULL;

			} else {
				SF_ERROR( syntax );
			}
			break;

		case '|':	/* union */
		case '&':	/* intersection */
		case '+':	/* string concatenation */
			set = SF_POP();
			if ( IS_OP( set ) ) {
				SF_ERROR( syntax );
			}
			if ( SF_TOP() == 0 || SF_TOP() == (void *)'(' /* ) */ ) {
				SF_PUSH( set );
				set = NULL;

			} else if ( IS_OP( SF_TOP() ) ) {
				op = (unsigned long)SF_POP();
				lset = SF_POP();
				set = slap_set_join( cp, lset, op, set );
				if ( set == NULL ) {
					SF_ERROR( memory );
				}
				SF_PUSH( set );
				set = NULL;
				
			} else {
				SF_ERROR( syntax );
			}
			SF_PUSH( c );
			break;

		case '[' /* ] */:
			if ( ( SF_TOP() == (void *)'/' ) || IS_SET( SF_TOP() ) ) {
				SF_ERROR( syntax );
			}
			for ( len = 0; ( c = *filter++ ) && ( c != /* [ */ ']' ); len++ )
				;
			if ( c == 0 ) {
				SF_ERROR( syntax );
			}
			
			set = cp->set_op->o_tmpcalloc( 2, sizeof( struct berval ),
					cp->set_op->o_tmpmemctx );
			if ( set == NULL ) {
				SF_ERROR( memory );
			}
			set->bv_val = cp->set_op->o_tmpcalloc( len + 1, sizeof( char ),
					cp->set_op->o_tmpmemctx );
			if ( BER_BVISNULL( set ) ) {
				SF_ERROR( memory );
			}
			AC_MEMCPY( set->bv_val, &filter[ - len - 1 ], len );
			set->bv_len = len;
			SF_PUSH( set );
			set = NULL;
			break;

		case '-':
			if ( ( SF_TOP() == (void *)'/' )
				&& ( *filter == '*' || ASCII_DIGIT( *filter ) ) )
			{
				SF_POP();

				if ( *filter == '*' ) {
					set = set_parents( cp, SF_POP() );
					filter++;

				} else {
					char *next = NULL;
					long parent = strtol( filter, &next, 10 );

					if ( next == filter ) {
						SF_ERROR( syntax );
					}

					set = SF_POP();
					if ( parent != 0 ) {
						set = set_parent( cp, set, parent );
					}
					filter = next;
				}

				if ( set == NULL ) {
					SF_ERROR( memory );
				}

				SF_PUSH( set );
				set = NULL;
				break;
			} else {
				c = *filter++;
				if ( c != '>' ) {
					SF_ERROR( syntax );
				}
				/* fall through to next case */
			}

		case '/':
			if ( IS_OP( SF_TOP() ) ) {
				SF_ERROR( syntax );
			}
			SF_PUSH( '/' );
			break;

		default:
			if ( !AD_LEADCHAR( c ) ) {
				SF_ERROR( syntax );
			}
			filter--;
			for ( len = 1;
				( c = filter[ len ] ) && AD_CHAR( c );
				len++ )
			{
				/* count */
				if ( c == '-' && !AD_CHAR( filter[ len + 1 ] ) ) {
					break;
				}
			}
			if ( len == 4
				&& memcmp( "this", filter, len ) == 0 )
			{
				assert( !BER_BVISNULL( target ) );
				if ( ( SF_TOP() == (void *)'/' ) || IS_SET( SF_TOP() ) ) {
					SF_ERROR( syntax );
				}
				set = cp->set_op->o_tmpcalloc( 2, sizeof( struct berval ),
						cp->set_op->o_tmpmemctx );
				if ( set == NULL ) {
					SF_ERROR( memory );
				}
				ber_dupbv_x( set, target, cp->set_op->o_tmpmemctx );
				if ( BER_BVISNULL( set ) ) {
					SF_ERROR( memory );
				}
				BER_BVZERO( &set[ 1 ] );
				
			} else if ( len == 4
				&& memcmp( "user", filter, len ) == 0 ) 
			{
				if ( ( SF_TOP() == (void *)'/' ) || IS_SET( SF_TOP() ) ) {
					SF_ERROR( syntax );
				}
				if ( BER_BVISNULL( user ) ) {
					SF_ERROR( memory );
				}
				set = cp->set_op->o_tmpcalloc( 2, sizeof( struct berval ),
						cp->set_op->o_tmpmemctx );
				if ( set == NULL ) {
					SF_ERROR( memory );
				}
				ber_dupbv_x( set, user, cp->set_op->o_tmpmemctx );
				BER_BVZERO( &set[ 1 ] );
				
			} else if ( SF_TOP() != (void *)'/' ) {
				SF_ERROR( syntax );

			} else {
				struct berval		fb2;
				AttributeDescription	*ad = NULL;
				const char		*text = NULL;

				SF_POP();
				fb2.bv_val = filter;
				fb2.bv_len = len;

				if ( slap_bv2ad( &fb2, &ad, &text ) != LDAP_SUCCESS ) {
					SF_ERROR( syntax );
				}

				/* NOTE: ad must have distinguishedName syntax
				 * or expand in an LDAP URI if c == '*'
				 */
				
				set = set_chase( gatherer,
					cp, SF_POP(), ad, c == '*' );
				if ( set == NULL ) {
					SF_ERROR( memory );
				}
				if ( c == '*' ) {
					len++;
				}
			}
			filter += len;
			SF_PUSH( set );
			set = NULL;
			break;
		}
	}

	set = SF_POP();
	if ( IS_OP( set ) ) {
		SF_ERROR( syntax );
	}
	if ( SF_TOP() == 0 ) {
		/* FIXME: ok ? */ ;

	} else if ( IS_OP( SF_TOP() ) ) {
		op = (unsigned long)SF_POP();
		lset = SF_POP();
		set = slap_set_join( cp, lset, op, set );
		if ( set == NULL ) {
			SF_ERROR( memory );
		}
		
	} else {
		SF_ERROR( syntax );
	}

	rc = slap_set_isempty( set ) ? 0 : 1;
	if ( results ) {
		*results = set;
		set = NULL;
	}

_error:
	if ( IS_SET( set ) ) {
		ber_bvarray_free_x( set, cp->set_op->o_tmpmemctx );
	}
	while ( ( set = SF_POP() ) ) {
		if ( IS_SET( set ) ) {
			ber_bvarray_free_x( set, cp->set_op->o_tmpmemctx );
		}
	}
	return rc;
}
Esempio n. 7
0
static int
set(void)
{
	char *token = currtok();
	int has_parent = 0;

	errlog(BEGIN, "set() {");
	errlog(VERBOSE, "token = '%s'",
	    (token) ? token : "<NULL>");

	if (in_specials(*token)) {
		errlog(INPUT|ERROR, "unexpected token \"%s\" found. "
		    "Version name expected", token);
		Errors++;
		errlog(END, "} /* set */");
		return (FALSE);
	}

	errlog(VERBOSE, "Begin Version: %s", token);
	*Previous = '\0';
	if (Selected) {
		if (add_parent(token, Previous, 0) == FALSE) {
			errlog(INPUT | ERROR, "unable to add a parent version "
			    "from the set file");
			Errors++;
			errlog(END, "} /* set */");
			return (FALSE);
		}
	}

	add_valid_version(token);
	(void) strncpy(LeftMostChild, token, MAXLINE);
	LeftMostChild[MAXLINE-1] = '\0';
	(void) strncpy(Previous, token, MAXLINE);
	Previous[MAXLINE-1] = '\0';

	token = nexttok();

	switch (*token) {
		case ':':
			errlog(VERBOSE, "token ':' found");
			(void) accept_token(":");
			if (set_parents() == FALSE) {
				errlog(END, "} /* set */");
				return (FALSE);
			}
			if (accept_token(";") == FALSE) {
				errlog(END, "} /* set */");
				return (FALSE);
			}
			errlog(VERBOSE, "End Version");
			break;

		case ';':
			errlog(VERBOSE, "token ';' found");
			(void) accept_token(";");
			errlog(VERBOSE, "End version ':'");
			break;

		case '[':
			(void) accept_token("[");
			if (accept_token("WEAK") == FALSE) {
				errlog(END, "} /* set */");
				return (FALSE);
			}
			if (accept_token("]") == FALSE) {
				errlog(END, "} /* set */");
				return (FALSE);
			}
			token = currtok();
			if (eq(token, ":")) {
				(void) accept_token(":");
				has_parent = 1;
			} else if (eq(token, ";")) {
				(void) accept_token(";");
			} else {
				errlog(ERROR|INPUT,
				    "Unexpected token \"%s\" found. ':'"
				    "or ';' expected.", token);
				Errors++;
				errlog(END, "} /* set */");
				return (FALSE);
			}
			errlog(VERBOSE, "WEAK version detected\n");
			if (Selected)
				set_weak(LeftMostChild, TRUE);

			if (has_parent) {
				if (set_parents() == FALSE) {
					errlog(END, "} /* set */");
					return (FALSE);
				}
				if (accept_token(";") == FALSE) {
					errlog(END, "} /* set */");
					return (FALSE);
				}
			}
			errlog(VERBOSE, "End Version");
			break;
		default:
			/* CSTYLED */
			errlog(ERROR|INPUT,
			    "Unexpected token \"%s\" found. ';' expected.",
			    token);
			Errors++;
			errlog(END, "} /* set */");
			return (FALSE);
	}

	token = currtok();
	if (eq(token, "}")) {
		(void) accept_token("}");
		errlog(VERBOSE, "End architecture");
		errlog(END, "} /* set */");
		return (FALSE);
	}

	errlog(END, "} /* set */");
	return (TRUE);
}
Esempio n. 8
0
void masq_remove_proc(struct task_struct *tsk, int update_nlchild) {
    struct bproc_masq_master_t *m;

    /* update the child counts on the parent process(es) but only if
     * we're going away in a silent exit.  (i.e. tsk == current and
     * we're running, not from wait->release->unmasq in which case tsk
     * is some other process and a zombie.) */
    if (update_nlchild) {
	if (BPROC_ISMASQ(tsk->real_parent)) {
	    tsk->real_parent->bproc.nlchild++;
	    wake_up_interruptible(&tsk->real_parent->wait_chldexit);
	}
	if (tsk->parent != tsk->real_parent && BPROC_ISMASQ(tsk->parent)) {
	    tsk->parent->bproc.nlchild++;
	    wake_up_interruptible(&tsk->parent->wait_chldexit);
	}
    }

    /* Remove this process from the list of processes for this master.
     * If this was the last reference to it, free the master structure
     * as well. */
    m = tsk->bproc.master;
    list_del(&tsk->bproc.list);
    tsk->bproc.master = 0;
    if (atomic_dec_and_test(&m->count))
	kfree(m);

    /*ptrace_disable ? */
    if (tsk->state < TASK_ZOMBIE) {
	/* Since we're trying to disappear silently, we should
	 * reparent ourselves to init which will do the wait() on
	 * us. */
	ptrace_unlink(tsk);
	tsk->exit_signal = SIGCHLD;
	set_parents(tsk, child_reaper, child_reaper);
    }

#if 0
    /* Shed child processes - we just have them re-select parents.  If
     * this is being called from release() we shouldn't have any
     * children...  */
    while (!list_empty(&tsk->children)) {
	struct task_struct *child;
	child = list_entry(tsk->children.next, struct task_struct, sibling);

	if (!BPROC_ISMASQ(child) || child->bproc.master != m)
	    printk(KERN_ERR "bproc: masq_remove_proc: child isn't in my"
		   " process space!\n");

	masq_select_parents(child->bproc.master, child);

	if (child->parent == tsk || child->real_parent == tsk) {
	    printk(KERN_CRIT "bproc: masq: child is still mine! me=%d child=%d\n",
		   tsk->pid, child->pid);
	}
    }
    while (!list_empty(&tsk->ptrace_children)) {
	struct task_struct *child;
	child = list_entry(tsk->ptrace_children.next, struct task_struct,
			   ptrace_list);

	if (!BPROC_ISMASQ(child) || child->bproc.master != m)
	    printk(KERN_ERR "bproc: masq_remove_proc: child isn't in my"
		   " process space!\n");

	masq_select_parents(child->bproc.master, child);

	if (child->parent == tsk || child->real_parent == tsk) {
	    printk(KERN_CRIT "bproc: masq: child is still mine! me=%d child=%d\n",
		   tsk->pid, child->pid);
	}
    }
#endif
}