Page MenuHomeFreeBSD

D30257.id89252.diff
No OneTemporary

D30257.id89252.diff

diff --git a/sys/kern/kern_acct.c b/sys/kern/kern_acct.c
--- a/sys/kern/kern_acct.c
+++ b/sys/kern/kern_acct.c
@@ -141,7 +141,6 @@
static int acct_suspended;
static struct vnode *acct_vp;
static struct ucred *acct_cred;
-static struct plimit *acct_limit;
static int acct_flags;
static struct sx acct_sx;
@@ -206,7 +205,7 @@
sys_acct(struct thread *td, struct acct_args *uap)
{
struct nameidata nd;
- int error, flags, i, replacing;
+ int error, flags, replacing;
error = priv_check(td, PRIV_ACCT);
if (error)
@@ -276,15 +275,6 @@
return (error);
}
- /*
- * Create our own plimit object without limits. It will be assigned
- * to exiting processes.
- */
- acct_limit = lim_alloc();
- for (i = 0; i < RLIM_NLIMITS; i++)
- acct_limit->pl_rlimit[i].rlim_cur =
- acct_limit->pl_rlimit[i].rlim_max = RLIM_INFINITY;
-
/*
* Save the new accounting file vnode, and schedule the new
* free space watcher.
@@ -328,7 +318,6 @@
sx_assert(&acct_sx, SX_XLOCKED);
error = vn_close(acct_vp, acct_flags, acct_cred, td);
crfree(acct_cred);
- lim_free(acct_limit);
acct_configured = 0;
acct_vp = NULL;
acct_cred = NULL;
@@ -349,7 +338,6 @@
{
struct acctv3 acct;
struct timeval ut, st, tmp;
- struct plimit *oldlim;
struct proc *p;
struct rusage ru;
int t, ret;
@@ -374,6 +362,7 @@
}
p = td->td_proc;
+ td->td_pflags2 |= TDP2_ACCT;
/*
* Get process accounting information.
@@ -426,20 +415,14 @@
/* (8) The boolean flags that tell how the process terminated, etc. */
acct.ac_flagx = p->p_acflag;
+ PROC_UNLOCK(p);
+
/* Setup ancillary structure fields. */
acct.ac_flagx |= ANVER;
acct.ac_zero = 0;
acct.ac_version = 3;
acct.ac_len = acct.ac_len2 = sizeof(acct);
- /*
- * Eliminate rlimits (file size limit in particular).
- */
- oldlim = p->p_limit;
- p->p_limit = lim_hold(acct_limit);
- PROC_UNLOCK(p);
- lim_free(oldlim);
-
/*
* Write the accounting information to the file.
*/
@@ -447,6 +430,7 @@
(off_t)0, UIO_SYSSPACE, IO_APPEND|IO_UNIT, acct_cred, NOCRED,
NULL, td);
sx_sunlock(&acct_sx);
+ td->td_pflags2 &= ~TDP2_ACCT;
return (ret);
}
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -79,9 +79,7 @@
#include <sys/unistd.h>
#include <sys/user.h>
#include <sys/vnode.h>
-#ifdef KTRACE
#include <sys/ktrace.h>
-#endif
#include <net/vnet.h>
@@ -4363,9 +4361,7 @@
PROC_LOCK_ASSERT(p, MA_OWNED);
/* ktrace vnode */
- tracevp = p->p_tracevp;
- if (tracevp != NULL)
- vrefact(tracevp);
+ tracevp = ktr_get_tracevp(p, true);
/* text vnode */
textvp = p->p_textvp;
if (textvp != NULL)
@@ -4405,17 +4401,20 @@
/* working directory */
if (pwd->pwd_cdir != NULL) {
vrefact(pwd->pwd_cdir);
- export_vnode_to_sb(pwd->pwd_cdir, KF_FD_TYPE_CWD, FREAD, efbuf);
+ export_vnode_to_sb(pwd->pwd_cdir, KF_FD_TYPE_CWD,
+ FREAD, efbuf);
}
/* root directory */
if (pwd->pwd_rdir != NULL) {
vrefact(pwd->pwd_rdir);
- export_vnode_to_sb(pwd->pwd_rdir, KF_FD_TYPE_ROOT, FREAD, efbuf);
+ export_vnode_to_sb(pwd->pwd_rdir, KF_FD_TYPE_ROOT,
+ FREAD, efbuf);
}
/* jail directory */
if (pwd->pwd_jdir != NULL) {
vrefact(pwd->pwd_jdir);
- export_vnode_to_sb(pwd->pwd_jdir, KF_FD_TYPE_JAIL, FREAD, efbuf);
+ export_vnode_to_sb(pwd->pwd_jdir, KF_FD_TYPE_JAIL,
+ FREAD, efbuf);
}
}
PWDDESC_XUNLOCK(pdp);
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -373,8 +373,7 @@
struct pargs *oldargs = NULL, *newargs = NULL;
struct sigacts *oldsigacts = NULL, *newsigacts = NULL;
#ifdef KTRACE
- struct vnode *tracevp = NULL;
- struct ucred *tracecred = NULL;
+ struct ktr_io_params *kiop;
#endif
struct vnode *oldtextvp = NULL, *newtextvp;
int credential_changing;
@@ -390,6 +389,7 @@
static const char fexecv_proc_title[] = "(fexecv)";
imgp = &image_params;
+ kiop = NULL;
/*
* Lock the process and set the P_INEXEC flag to indicate that
@@ -779,11 +779,10 @@
* we do not regain any tracing during a possible block.
*/
setsugid(p);
+ kiop = NULL;
#ifdef KTRACE
- if (p->p_tracecred != NULL &&
- priv_check_cred(p->p_tracecred, PRIV_DEBUG_DIFFCRED))
- ktrprocexec(p, &tracecred, &tracevp);
+ kiop = ktrprocexec(p);
#endif
/*
* Close any file descriptors 0..2 that reference procfs,
@@ -938,12 +937,7 @@
*/
if (oldtextvp != NULL)
vrele(oldtextvp);
-#ifdef KTRACE
- if (tracevp != NULL)
- vrele(tracevp);
- if (tracecred != NULL)
- crfree(tracecred);
-#endif
+ ktr_io_params_free(kiop);
pargs_drop(oldargs);
pargs_drop(newargs);
if (oldsigacts != NULL)
diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c
--- a/sys/kern/kern_ktrace.c
+++ b/sys/kern/kern_ktrace.c
@@ -51,6 +51,7 @@
#include <sys/namei.h>
#include <sys/priv.h>
#include <sys/proc.h>
+#include <sys/resourcevar.h>
#include <sys/unistd.h>
#include <sys/vnode.h>
#include <sys/socket.h>
@@ -145,20 +146,28 @@
static struct mtx ktrace_mtx;
static struct sx ktrace_sx;
+struct ktr_io_params {
+ struct vnode *vp;
+ struct ucred *cr;
+ off_t lim;
+ u_int refs;
+};
+
static void ktrace_init(void *dummy);
static int sysctl_kern_ktrace_request_pool(SYSCTL_HANDLER_ARGS);
static u_int ktrace_resize_pool(u_int oldsize, u_int newsize);
static struct ktr_request *ktr_getrequest_entered(struct thread *td, int type);
static struct ktr_request *ktr_getrequest(int type);
static void ktr_submitrequest(struct thread *td, struct ktr_request *req);
-static void ktr_freeproc(struct proc *p, struct ucred **uc,
- struct vnode **vp);
+static struct ktr_io_params *ktr_freeproc(struct proc *p);
static void ktr_freerequest(struct ktr_request *req);
static void ktr_freerequest_locked(struct ktr_request *req);
static void ktr_writerequest(struct thread *td, struct ktr_request *req);
static int ktrcanset(struct thread *,struct proc *);
-static int ktrsetchildren(struct thread *,struct proc *,int,int,struct vnode *);
-static int ktrops(struct thread *,struct proc *,int,int,struct vnode *);
+static int ktrsetchildren(struct thread *, struct proc *, int, int,
+ struct ktr_io_params *);
+static int ktrops(struct thread *, struct proc *, int, int,
+ struct ktr_io_params *);
static void ktrprocctor_entered(struct thread *, struct proc *);
/*
@@ -421,28 +430,86 @@
STAILQ_INSERT_HEAD(&ktr_free, req, ktr_list);
}
+static void
+ktr_io_params_ref(struct ktr_io_params *kiop)
+{
+ mtx_assert(&ktrace_mtx, MA_OWNED);
+ kiop->refs++;
+}
+
+static struct ktr_io_params *
+ktr_io_params_unref(struct ktr_io_params *kiop)
+{
+ mtx_assert(&ktrace_mtx, MA_OWNED);
+ KASSERT(kiop->refs > 0, ("kiop ref == 0 %p", kiop));
+ return (--(kiop->refs) == 0 ? kiop : NULL);
+}
+
+void
+ktr_io_params_free(struct ktr_io_params *kiop)
+{
+ if (kiop == NULL)
+ return;
+
+ MPASS(kiop->refs == 0);
+ vrele(kiop->vp);
+ crfree(kiop->cr);
+ free(kiop, M_KTRACE);
+}
+
+static struct ktr_io_params *
+ktr_io_params_alloc(struct thread *td, struct vnode *vp)
+{
+ struct ktr_io_params *res;
+
+ res = malloc(sizeof(struct ktr_io_params), M_KTRACE, M_WAITOK);
+ res->vp = vp;
+ vref(vp);
+ res->cr = td->td_ucred;
+ crhold(res->cr);
+ res->lim = lim_cur(td, RLIMIT_FSIZE);
+ res->refs = 0;
+ return (res);
+}
+
/*
* Disable tracing for a process and release all associated resources.
* The caller is responsible for releasing a reference on the returned
* vnode and credentials.
*/
-static void
-ktr_freeproc(struct proc *p, struct ucred **uc, struct vnode **vp)
+static struct ktr_io_params *
+ktr_freeproc(struct proc *p)
{
+ struct ktr_io_params *kiop;
struct ktr_request *req;
PROC_LOCK_ASSERT(p, MA_OWNED);
mtx_assert(&ktrace_mtx, MA_OWNED);
- *uc = p->p_tracecred;
- p->p_tracecred = NULL;
- if (vp != NULL)
- *vp = p->p_tracevp;
- p->p_tracevp = NULL;
+ kiop = ktr_io_params_unref(p->p_ktrioparms);
+ p->p_ktrioparms = NULL;
p->p_traceflag = 0;
while ((req = STAILQ_FIRST(&p->p_ktr)) != NULL) {
STAILQ_REMOVE_HEAD(&p->p_ktr, ktr_list);
ktr_freerequest_locked(req);
}
+ return (kiop);
+}
+
+struct vnode *
+ktr_get_tracevp(struct proc *p, bool ref)
+{
+ struct vnode *vp;
+
+ PROC_LOCK_ASSERT(p, MA_OWNED);
+
+ if (p->p_ktrioparms != 0) {
+ vp = p->p_ktrioparms->vp;
+ if (ref)
+ vrefact(vp);
+ } else {
+ vp = NULL;
+ }
+ return (vp);
}
void
@@ -501,14 +568,21 @@
*
* XXX: We toss any pending asynchronous records.
*/
-void
-ktrprocexec(struct proc *p, struct ucred **uc, struct vnode **vp)
+struct ktr_io_params *
+ktrprocexec(struct proc *p)
{
+ struct ktr_io_params *kiop;
PROC_LOCK_ASSERT(p, MA_OWNED);
+
+ kiop = p->p_ktrioparms;
+ if (kiop == NULL || priv_check_cred(kiop->cr, PRIV_DEBUG_DIFFCRED))
+ return (NULL);
+
mtx_lock(&ktrace_mtx);
- ktr_freeproc(p, uc, vp);
+ kiop = ktr_freeproc(p);
mtx_unlock(&ktrace_mtx);
+ return (kiop);
}
/*
@@ -520,8 +594,7 @@
{
struct ktr_request *req;
struct proc *p;
- struct ucred *cred;
- struct vnode *vp;
+ struct ktr_io_params *kiop;
p = td->td_proc;
if (p->p_traceflag == 0)
@@ -536,13 +609,10 @@
sx_xunlock(&ktrace_sx);
PROC_LOCK(p);
mtx_lock(&ktrace_mtx);
- ktr_freeproc(p, &cred, &vp);
+ kiop = ktr_freeproc(p);
mtx_unlock(&ktrace_mtx);
PROC_UNLOCK(p);
- if (vp != NULL)
- vrele(vp);
- if (cred != NULL)
- crfree(cred);
+ ktr_io_params_free(kiop);
ktrace_exit(td);
}
@@ -583,7 +653,7 @@
ktrprocfork(struct proc *p1, struct proc *p2)
{
- MPASS(p2->p_tracevp == NULL);
+ MPASS(p2->p_ktrioparms == NULL);
MPASS(p2->p_traceflag == 0);
if (p1->p_traceflag == 0)
@@ -593,12 +663,8 @@
mtx_lock(&ktrace_mtx);
if (p1->p_traceflag & KTRFAC_INHERIT) {
p2->p_traceflag = p1->p_traceflag;
- if ((p2->p_tracevp = p1->p_tracevp) != NULL) {
- VREF(p2->p_tracevp);
- KASSERT(p1->p_tracecred != NULL,
- ("ktrace vnode with no cred"));
- p2->p_tracecred = crhold(p1->p_tracecred);
- }
+ if ((p2->p_ktrioparms = p1->p_ktrioparms) != NULL)
+ p1->p_ktrioparms->refs++;
}
mtx_unlock(&ktrace_mtx);
PROC_UNLOCK(p1);
@@ -932,7 +998,7 @@
int nfound, ret = 0;
int flags, error = 0;
struct nameidata nd;
- struct ucred *cred;
+ struct ktr_io_params *kiop, *old_kiop;
/*
* Need something to (un)trace.
@@ -940,6 +1006,7 @@
if (ops != KTROP_CLEARFILE && facs == 0)
return (EINVAL);
+ kiop = NULL;
ktrace_enter(td);
if (ops != KTROP_CLEAR) {
/*
@@ -960,34 +1027,34 @@
ktrace_exit(td);
return (EACCES);
}
+ kiop = ktr_io_params_alloc(td, vp);
+ kiop->refs++;
}
/*
* Clear all uses of the tracefile.
*/
if (ops == KTROP_CLEARFILE) {
- int vrele_count;
-
- vrele_count = 0;
+restart:
sx_slock(&allproc_lock);
FOREACH_PROC_IN_SYSTEM(p) {
+ old_kiop = NULL;
PROC_LOCK(p);
- if (p->p_tracevp == vp) {
+ if (p->p_ktrioparms->vp == vp) {
if (ktrcanset(td, p)) {
mtx_lock(&ktrace_mtx);
- ktr_freeproc(p, &cred, NULL);
+ old_kiop = ktr_freeproc(p);
mtx_unlock(&ktrace_mtx);
- vrele_count++;
- crfree(cred);
} else
error = EPERM;
}
PROC_UNLOCK(p);
+ if (old_kiop != NULL) {
+ sx_sunlock(&allproc_lock);
+ ktr_io_params_free(old_kiop);
+ goto restart;
+ }
}
sx_sunlock(&allproc_lock);
- if (vrele_count > 0) {
- while (vrele_count-- > 0)
- vrele(vp);
- }
goto done;
}
/*
@@ -1019,9 +1086,9 @@
}
nfound++;
if (descend)
- ret |= ktrsetchildren(td, p, ops, facs, vp);
+ ret |= ktrsetchildren(td, p, ops, facs, kiop);
else
- ret |= ktrops(td, p, ops, facs, vp);
+ ret |= ktrops(td, p, ops, facs, kiop);
}
if (nfound == 0) {
sx_sunlock(&proctree_lock);
@@ -1044,16 +1111,20 @@
goto done;
}
if (descend)
- ret |= ktrsetchildren(td, p, ops, facs, vp);
+ ret |= ktrsetchildren(td, p, ops, facs, kiop);
else
- ret |= ktrops(td, p, ops, facs, vp);
+ ret |= ktrops(td, p, ops, facs, kiop);
}
sx_sunlock(&proctree_lock);
if (!ret)
error = EPERM;
done:
- if (vp != NULL)
- (void) vn_close(vp, FWRITE, td->td_ucred, td);
+ if (kiop != NULL) {
+ mtx_lock(&ktrace_mtx);
+ kiop = ktr_io_params_unref(kiop);
+ ktr_io_params_free(kiop);
+ mtx_unlock(&ktrace_mtx);
+ }
ktrace_exit(td);
return (error);
#else /* !KTRACE */
@@ -1097,10 +1168,10 @@
#ifdef KTRACE
static int
-ktrops(struct thread *td, struct proc *p, int ops, int facs, struct vnode *vp)
+ktrops(struct thread *td, struct proc *p, int ops, int facs,
+ struct ktr_io_params *new_kiop)
{
- struct vnode *tracevp = NULL;
- struct ucred *tracecred = NULL;
+ struct ktr_io_params *old_kiop;
PROC_LOCK_ASSERT(p, MA_OWNED);
if (!ktrcanset(td, p)) {
@@ -1112,19 +1183,18 @@
PROC_UNLOCK(p);
return (1);
}
+ old_kiop = NULL;
mtx_lock(&ktrace_mtx);
if (ops == KTROP_SET) {
- if (p->p_tracevp != vp) {
- /*
- * if trace file already in use, relinquish below
- */
- tracevp = p->p_tracevp;
- VREF(vp);
- p->p_tracevp = vp;
+ if (p->p_ktrioparms != NULL &&
+ p->p_ktrioparms->vp != new_kiop->vp) {
+ /* if trace file already in use, relinquish below */
+ old_kiop = ktr_io_params_unref(p->p_ktrioparms);
+ p->p_ktrioparms = NULL;
}
- if (p->p_tracecred != td->td_ucred) {
- tracecred = p->p_tracecred;
- p->p_tracecred = crhold(td->td_ucred);
+ if (p->p_ktrioparms == NULL) {
+ p->p_ktrioparms = new_kiop;
+ ktr_io_params_ref(new_kiop);
}
p->p_traceflag |= facs;
if (priv_check(td, PRIV_KTRACE) == 0)
@@ -1133,23 +1203,20 @@
/* KTROP_CLEAR */
if (((p->p_traceflag &= ~facs) & KTRFAC_MASK) == 0)
/* no more tracing */
- ktr_freeproc(p, &tracecred, &tracevp);
+ old_kiop = ktr_freeproc(p);
}
mtx_unlock(&ktrace_mtx);
if ((p->p_traceflag & KTRFAC_MASK) != 0)
ktrprocctor_entered(td, p);
PROC_UNLOCK(p);
- if (tracevp != NULL)
- vrele(tracevp);
- if (tracecred != NULL)
- crfree(tracecred);
+ ktr_io_params_free(old_kiop);
return (1);
}
static int
ktrsetchildren(struct thread *td, struct proc *top, int ops, int facs,
- struct vnode *vp)
+ struct ktr_io_params *new_kiop)
{
struct proc *p;
int ret = 0;
@@ -1158,7 +1225,7 @@
PROC_LOCK_ASSERT(p, MA_OWNED);
sx_assert(&proctree_lock, SX_LOCKED);
for (;;) {
- ret |= ktrops(td, p, ops, facs, vp);
+ ret |= ktrops(td, p, ops, facs, new_kiop);
/*
* If this process has children, descend to them next,
* otherwise do any siblings, and if done with this level,
@@ -1183,6 +1250,7 @@
static void
ktr_writerequest(struct thread *td, struct ktr_request *req)
{
+ struct ktr_io_params *kiop;
struct ktr_header *kth;
struct vnode *vp;
struct proc *p;
@@ -1190,9 +1258,12 @@
struct uio auio;
struct iovec aiov[3];
struct mount *mp;
- int datalen, buflen, vrele_count;
+ off_t lim;
+ int datalen, buflen;
int error;
+ p = td->td_proc;
+
/*
* We hold the vnode and credential for use in I/O in case ktrace is
* disabled on the process as we write out the request.
@@ -1201,19 +1272,22 @@
* the vnode has been closed.
*/
mtx_lock(&ktrace_mtx);
- vp = td->td_proc->p_tracevp;
- cred = td->td_proc->p_tracecred;
+
+ kiop = p->p_ktrioparms;
/*
- * If vp is NULL, the vp has been cleared out from under this
- * request, so just drop it. Make sure the credential and vnode are
- * in sync: we should have both or neither.
+ * If kiop is NULL, it has been cleared out from under this
+ * request, so just drop it.
*/
- if (vp == NULL) {
- KASSERT(cred == NULL, ("ktr_writerequest: cred != NULL"));
+ if (kiop == NULL) {
mtx_unlock(&ktrace_mtx);
return;
}
+
+ vp = kiop->vp;
+ cred = kiop->cr;
+ lim = kiop->lim;
+
VREF(vp);
KASSERT(cred != NULL, ("ktr_writerequest: cred == NULL"));
crhold(cred);
@@ -1250,58 +1324,40 @@
vn_start_write(vp, &mp, V_WAIT);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+ MPASS((td->td_pflags2 & TDP2_KTRWRITE) == 0);
+ td->td_pflags2 |= TDP2_KTRWRITE;
+ td->td_ktr_io_lim = lim;
#ifdef MAC
error = mac_vnode_check_write(cred, NOCRED, vp);
if (error == 0)
#endif
error = VOP_WRITE(vp, &auio, IO_UNIT | IO_APPEND, cred);
+ td->td_pflags2 &= ~TDP2_KTRWRITE;
VOP_UNLOCK(vp);
vn_finished_write(mp);
crfree(cred);
- if (!error) {
+ if (error == 0) {
vrele(vp);
return;
}
/*
- * If error encountered, give up tracing on this vnode. We defer
- * all the vrele()'s on the vnode until after we are finished walking
- * the various lists to avoid needlessly holding locks.
- * NB: at this point we still hold the vnode reference that must
- * not go away as we need the valid vnode to compare with. Thus let
- * vrele_count start at 1 and the reference will be freed
- * by the loop at the end after our last use of vp.
- */
- log(LOG_NOTICE, "ktrace write failed, errno %d, tracing stopped\n",
- error);
- vrele_count = 1;
- /*
- * First, clear this vnode from being used by any processes in the
- * system.
- * XXX - If one process gets an EPERM writing to the vnode, should
- * we really do this? Other processes might have suitable
- * credentials for the operation.
+ * If error encountered, give up tracing on this vnode on this
+ * process. Other processes might still be suitable for
+ * writes to this vnode.
*/
- cred = NULL;
- sx_slock(&allproc_lock);
- FOREACH_PROC_IN_SYSTEM(p) {
- PROC_LOCK(p);
- if (p->p_tracevp == vp) {
- mtx_lock(&ktrace_mtx);
- ktr_freeproc(p, &cred, NULL);
- mtx_unlock(&ktrace_mtx);
- vrele_count++;
- }
- PROC_UNLOCK(p);
- if (cred != NULL) {
- crfree(cred);
- cred = NULL;
- }
- }
- sx_sunlock(&allproc_lock);
+ log(LOG_NOTICE,
+ "ktrace write failed, errno %d, tracing stopped for pid %d\n",
+ error, p->p_pid);
- while (vrele_count-- > 0)
- vrele(vp);
+ PROC_LOCK(p);
+ mtx_lock(&ktrace_mtx);
+ if (p->p_ktrioparms != NULL && p->p_ktrioparms->vp == vp)
+ kiop = ktr_freeproc(p);
+ mtx_unlock(&ktrace_mtx);
+ PROC_UNLOCK(p);
+ ktr_io_params_free(kiop);
+ vrele(vp);
}
/*
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -75,6 +75,9 @@
#include <sys/user.h>
#include <sys/vnode.h>
#include <sys/wait.h>
+#ifdef KTRACE
+#include <sys/ktrace.h>
+#endif
#ifdef DDB
#include <ddb/ddb.h>
@@ -1058,7 +1061,7 @@
kp->ki_args = p->p_args;
kp->ki_textvp = p->p_textvp;
#ifdef KTRACE
- kp->ki_tracep = p->p_tracevp;
+ kp->ki_tracep = ktr_get_tracevp(p, false);
kp->ki_traceflag = p->p_traceflag;
#endif
kp->ki_fd = p->p_fd;
diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c
--- a/sys/kern/kern_thread.c
+++ b/sys/kern/kern_thread.c
@@ -96,11 +96,11 @@
"struct proc KBI p_flag");
_Static_assert(offsetof(struct proc, p_pid) == 0xc4,
"struct proc KBI p_pid");
-_Static_assert(offsetof(struct proc, p_filemon) == 0x3c0,
+_Static_assert(offsetof(struct proc, p_filemon) == 0x3b8,
"struct proc KBI p_filemon");
-_Static_assert(offsetof(struct proc, p_comm) == 0x3d8,
+_Static_assert(offsetof(struct proc, p_comm) == 0x3d0,
"struct proc KBI p_comm");
-_Static_assert(offsetof(struct proc, p_emuldata) == 0x4b8,
+_Static_assert(offsetof(struct proc, p_emuldata) == 0x4b0,
"struct proc KBI p_emuldata");
#endif
#ifdef __i386__
@@ -116,11 +116,11 @@
"struct proc KBI p_flag");
_Static_assert(offsetof(struct proc, p_pid) == 0x78,
"struct proc KBI p_pid");
-_Static_assert(offsetof(struct proc, p_filemon) == 0x26c,
+_Static_assert(offsetof(struct proc, p_filemon) == 0x268,
"struct proc KBI p_filemon");
-_Static_assert(offsetof(struct proc, p_comm) == 0x280,
+_Static_assert(offsetof(struct proc, p_comm) == 0x27c,
"struct proc KBI p_comm");
-_Static_assert(offsetof(struct proc, p_emuldata) == 0x30c,
+_Static_assert(offsetof(struct proc, p_emuldata) == 0x308,
"struct proc KBI p_emuldata");
#endif
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -2359,17 +2359,17 @@
vn_rlimit_fsize(const struct vnode *vp, const struct uio *uio,
struct thread *td)
{
-
- if (vp->v_type != VREG || td == NULL)
+ if (vp->v_type != VREG || td == NULL ||
+ (td->td_pflags2 & TDP2_ACCT) != 0 ||
+ (uoff_t)uio->uio_offset + uio->uio_resid <=
+ ((td->td_pflags2 & TDP2_KTRWRITE) != 0 ? td->td_ktr_io_lim :
+ lim_cur(td, RLIMIT_FSIZE)))
return (0);
- if ((uoff_t)uio->uio_offset + uio->uio_resid >
- lim_cur(td, RLIMIT_FSIZE)) {
- PROC_LOCK(td->td_proc);
- kern_psignal(td->td_proc, SIGXFSZ);
- PROC_UNLOCK(td->td_proc);
- return (EFBIG);
- }
- return (0);
+
+ PROC_LOCK(td->td_proc);
+ kern_psignal(td->td_proc, SIGXFSZ);
+ PROC_UNLOCK(td->td_proc);
+ return (EFBIG);
}
int
diff --git a/sys/sys/ktrace.h b/sys/sys/ktrace.h
--- a/sys/sys/ktrace.h
+++ b/sys/sys/ktrace.h
@@ -265,6 +265,10 @@
#define KTRFAC_DROP 0x20000000 /* last event was dropped */
#ifdef _KERNEL
+struct ktr_io_params;
+
+struct vnode *ktr_get_tracevp(struct proc *, bool);
+void ktr_io_params_free(struct ktr_io_params *);
void ktrnamei(char *);
void ktrcsw(int, int, const char *);
void ktrpsig(int, sig_t, sigset_t *, int);
@@ -275,7 +279,7 @@
void ktrsysctl(int *name, u_int namelen);
void ktrsysret(int, int, register_t);
void ktrprocctor(struct proc *);
-void ktrprocexec(struct proc *, struct ucred **, struct vnode **);
+struct ktr_io_params *ktrprocexec(struct proc *);
void ktrprocexit(struct thread *);
void ktrprocfork(struct proc *, struct proc *);
void ktruserret(struct thread *);
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -378,6 +378,7 @@
void *td_lkpi_task; /* LinuxKPI task struct pointer */
int td_pmcpend;
void *td_coredump; /* (c) coredump request. */
+ off_t td_ktr_io_lim; /* (k) limit for ktrace file size */
#ifdef EPOCH_TRACE
SLIST_HEAD(, epoch_tracker) td_epochs;
#endif
@@ -528,6 +529,8 @@
#define TDP2_SBPAGES 0x00000001 /* Owns sbusy on some pages */
#define TDP2_COMPAT32RB 0x00000002 /* compat32 ABI for robust lists */
+#define TDP2_ACCT 0x00000004 /* Doing accounting */
+#define TDP2_KTRWRITE 0x00000008 /* Doing ktrace record write */
/*
* Reasons that the current thread can not be run yet.
@@ -661,8 +664,7 @@
int p_profthreads; /* (c) Num threads in addupc_task. */
volatile int p_exitthreads; /* (j) Number of threads exiting */
int p_traceflag; /* (o) Kernel trace points. */
- struct vnode *p_tracevp; /* (c + o) Trace to vnode. */
- struct ucred *p_tracecred; /* (o) Credentials to trace with. */
+ struct ktr_io_params *p_ktrioparms; /* (c + o) Params for ktrace. */
struct vnode *p_textvp; /* (b) Vnode of executable. */
u_int p_lock; /* (c) Proclock (prevent swap) count. */
struct sigiolst p_sigiolst; /* (c) List of sigio sources. */

File Metadata

Mime Type
text/plain
Expires
Wed, Mar 18, 1:22 AM (4 h, 45 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29866248
Default Alt Text
D30257.id89252.diff (22 KB)

Event Timeline