mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-21 15:45:02 +00:00
MFP4:
Implement prctl(). Submitted by: rdivacky Tested with: LTP
This commit is contained in:
parent
efc7cb843b
commit
955d762aca
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=163734
@ -53,7 +53,6 @@ DUMMY(bdflush);
|
||||
DUMMY(sysfs);
|
||||
DUMMY(query_module);
|
||||
DUMMY(nfsservctl);
|
||||
DUMMY(prctl);
|
||||
DUMMY(rt_sigtimedwait);
|
||||
DUMMY(rt_sigqueueinfo);
|
||||
DUMMY(capget);
|
||||
|
@ -298,7 +298,8 @@
|
||||
l_gid16_t egid, l_gid16_t sgid); }
|
||||
171 AUE_GETRESGID STD { int linux_getresgid16(l_gid16_t *rgid, \
|
||||
l_gid16_t *egid, l_gid16_t *sgid); }
|
||||
172 AUE_PRCTL STD { int linux_prctl(void); }
|
||||
172 AUE_PRCTL STD { int linux_prctl(l_int option, l_int arg2, l_int arg3, \
|
||||
l_int arg4, l_int arg5); }
|
||||
173 AUE_NULL STD { int linux_rt_sigreturn( \
|
||||
struct l_ucontext *ucp); }
|
||||
174 AUE_NULL STD { int linux_rt_sigaction(l_int sig, \
|
||||
|
@ -84,6 +84,7 @@ linux_proc_init(struct thread *td, pid_t child, int flags)
|
||||
/* non-exec call */
|
||||
em = malloc(sizeof *em, M_LINUX, M_WAITOK | M_ZERO);
|
||||
em->pid = child;
|
||||
em->pdeath_signal = 0;
|
||||
if (flags & CLONE_VM) {
|
||||
/* handled later in the code */
|
||||
} else {
|
||||
@ -151,6 +152,7 @@ linux_proc_exit(void *arg __unused, struct proc *p)
|
||||
int error;
|
||||
struct thread *td = FIRST_THREAD_IN_PROC(p);
|
||||
int *child_clear_tid;
|
||||
struct proc *q, *nq;
|
||||
|
||||
if (__predict_true(p->p_sysent != &elf_linux_sysvec))
|
||||
return;
|
||||
@ -204,6 +206,26 @@ linux_proc_exit(void *arg __unused, struct proc *p)
|
||||
|
||||
/* clean the stuff up */
|
||||
free(em, M_LINUX);
|
||||
|
||||
/* this is a little weird but rewritten from exit1() */
|
||||
sx_xlock(&proctree_lock);
|
||||
q = LIST_FIRST(&p->p_children);
|
||||
for (; q != NULL; q = nq) {
|
||||
nq = LIST_NEXT(q, p_sibling);
|
||||
if (q->p_flag & P_WEXIT)
|
||||
continue;
|
||||
if (__predict_false(q->p_sysent != &elf_linux_sysvec))
|
||||
continue;
|
||||
em = em_find(q, EMUL_UNLOCKED);
|
||||
KASSERT(em != NULL, ("linux_reparent: emuldata not found: %i\n", q->p_pid));
|
||||
if (em->pdeath_signal != 0) {
|
||||
PROC_LOCK(q);
|
||||
psignal(q, em->pdeath_signal);
|
||||
PROC_UNLOCK(q);
|
||||
}
|
||||
EMUL_UNLOCK(&emul_lock);
|
||||
}
|
||||
sx_xunlock(&proctree_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -251,7 +273,7 @@ linux_schedtail(void *arg __unused, struct proc *p)
|
||||
int error = 0;
|
||||
int *child_set_tid;
|
||||
|
||||
if (p->p_sysent != &elf_linux_sysvec)
|
||||
if (__predict_true(p->p_sysent != &elf_linux_sysvec))
|
||||
return;
|
||||
|
||||
retry:
|
||||
|
@ -50,6 +50,8 @@ struct linux_emuldata {
|
||||
|
||||
struct linux_emuldata_shared *shared;
|
||||
|
||||
int pdeath_signal; /* parent death signal */
|
||||
|
||||
LIST_ENTRY(linux_emuldata) threads; /* list of linux threads */
|
||||
};
|
||||
|
||||
|
@ -76,6 +76,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <compat/linux/linux_sysproto.h>
|
||||
#include <compat/linux/linux_emul.h>
|
||||
#include <compat/linux/linux_misc.h>
|
||||
|
||||
#ifdef COMPAT_LINUX32
|
||||
#include <machine/../linux32/linux.h>
|
||||
@ -86,6 +87,7 @@ __FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#include <compat/linux/linux_mib.h>
|
||||
#include <compat/linux/linux_signal.h>
|
||||
#include <compat/linux/linux_util.h>
|
||||
|
||||
#ifdef __i386__
|
||||
@ -1546,3 +1548,52 @@ linux_exit_group(struct thread *td, struct linux_exit_group_args *args)
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
linux_prctl(struct thread *td, struct linux_prctl_args *args)
|
||||
{
|
||||
int error = 0;
|
||||
struct proc *p = td->td_proc;
|
||||
char comm[LINUX_MAX_COMM_LEN];
|
||||
struct linux_emuldata *em;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (ldebug(prctl))
|
||||
printf(ARGS(prctl, "%d, %d, %d, %d, %d"), args->option, args->arg2,
|
||||
args->arg3, args->arg4, args->arg5);
|
||||
#endif
|
||||
|
||||
switch (args->option) {
|
||||
case LINUX_PR_SET_PDEATHSIG:
|
||||
if (!LINUX_SIG_VALID(args->arg2))
|
||||
return (EINVAL);
|
||||
em = em_find(p, EMUL_UNLOCKED);
|
||||
KASSERT(em != NULL, ("prctl: emuldata not found.\n"));
|
||||
em->pdeath_signal = args->arg2;
|
||||
EMUL_UNLOCK(&emul_lock);
|
||||
break;
|
||||
case LINUX_PR_GET_PDEATHSIG:
|
||||
em = em_find(p, EMUL_UNLOCKED);
|
||||
KASSERT(em != NULL, ("prctl: emuldata not found.\n"));
|
||||
error = copyout(&em->pdeath_signal, (void *)(register_t) args->arg2, sizeof(em->pdeath_signal));
|
||||
EMUL_UNLOCK(&emul_lock);
|
||||
break;
|
||||
case LINUX_PR_SET_NAME:
|
||||
comm[LINUX_MAX_COMM_LEN-1] = 0;
|
||||
error = copyin(comm, (void *)(register_t) args->arg2, LINUX_MAX_COMM_LEN-1);
|
||||
if (error)
|
||||
return (error);
|
||||
PROC_LOCK(p);
|
||||
strcpy(p->p_comm, comm);
|
||||
PROC_UNLOCK(p);
|
||||
break;
|
||||
case LINUX_PR_GET_NAME:
|
||||
error = copyout(&p->p_comm, (void *)(register_t) args->arg2, MAXCOMLEN+1);
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
43
sys/compat/linux/linux_misc.h
Normal file
43
sys/compat/linux/linux_misc.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*-
|
||||
* Copyright (c) 2006 Roman Divacky
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer
|
||||
* in this position and unchanged.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_MISC_H_
|
||||
#define _LINUX_MISC_H_
|
||||
|
||||
/* defines for prctl */
|
||||
#define LINUX_PR_SET_PDEATHSIG 1 /* Second arg is a signal */
|
||||
#define LINUX_PR_GET_PDEATHSIG 2 /* Second arg is a ptr to return the signal */
|
||||
#define LINUX_PR_SET_NAME 15 /* Set process name */
|
||||
#define LINUX_PR_GET_NAME 16 /* Get process name */
|
||||
|
||||
#define LINUX_MAX_COMM_LEN 16 /* max length of the proc name */
|
||||
|
||||
#endif /* _LINUX_MISC_H_ */
|
||||
|
@ -56,7 +56,6 @@ DUMMY(sysfs);
|
||||
DUMMY(vm86);
|
||||
DUMMY(query_module);
|
||||
DUMMY(nfsservctl);
|
||||
DUMMY(prctl);
|
||||
DUMMY(rt_sigtimedwait);
|
||||
DUMMY(rt_sigqueueinfo);
|
||||
DUMMY(capget);
|
||||
|
@ -301,7 +301,8 @@
|
||||
l_gid16_t egid, l_gid16_t sgid); }
|
||||
171 AUE_GETRESGID STD { int linux_getresgid16(l_gid16_t *rgid, \
|
||||
l_gid16_t *egid, l_gid16_t *sgid); }
|
||||
172 AUE_PRCTL STD { int linux_prctl(void); }
|
||||
172 AUE_PRCTL STD { int linux_prctl(l_int option, l_int arg2, l_int arg3, \
|
||||
l_int arg4, l_int arg5); }
|
||||
173 AUE_NULL STD { int linux_rt_sigreturn( \
|
||||
struct l_ucontext *ucp); }
|
||||
174 AUE_NULL STD { int linux_rt_sigaction(l_int sig, \
|
||||
|
Loading…
Reference in New Issue
Block a user