Index: sys/sys/proc.h =================================================================== --- sys/sys/proc.h (wersja 243142) +++ sys/sys/proc.h (kopia robocza) @@ -528,6 +528,7 @@ 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. */ + rlim_t p_tracefsize; /* (c) File size limit of the tracer. */ 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. */ Index: sys/kern/vfs_vnops.c =================================================================== --- sys/kern/vfs_vnops.c (wersja 243142) +++ sys/kern/vfs_vnops.c (kopia robocza) @@ -1820,17 +1820,27 @@ vn_rlimit_fsize(const struct vnode *vp, const struct uio *uio, const struct thread *td) { + struct proc *p; + rlim_t fsize; if (vp->v_type != VREG || td == NULL) return (0); - PROC_LOCK(td->td_proc); - if ((uoff_t)uio->uio_offset + uio->uio_resid > - lim_cur(td->td_proc, RLIMIT_FSIZE)) { - kern_psignal(td->td_proc, SIGXFSZ); - PROC_UNLOCK(td->td_proc); + p = td->td_proc; + PROC_LOCK(p); + /* + * If this is ktrace file, use fsize limit of the tracer, otherwise + * use fsize limit of the process doing the write. + */ + if (vp == p->p_tracevp) + fsize = p->p_tracefsize; + else + fsize = lim_cur(p, RLIMIT_FSIZE); + if ((uoff_t)uio->uio_offset + uio->uio_resid > fsize) { + kern_psignal(p, SIGXFSZ); + PROC_UNLOCK(p); return (EFBIG); } - PROC_UNLOCK(td->td_proc); + PROC_UNLOCK(p); return (0); } Index: sys/kern/kern_ktrace.c =================================================================== --- sys/kern/kern_ktrace.c (wersja 243142) +++ sys/kern/kern_ktrace.c (kopia robocza) @@ -583,6 +583,7 @@ KASSERT(p1->p_tracecred != NULL, ("ktrace vnode with no cred")); p2->p_tracecred = crhold(p1->p_tracecred); + p2->p_tracefsize = p1->p_tracefsize; } } mtx_unlock(&ktrace_mtx); @@ -1059,6 +1060,9 @@ if (p->p_tracecred != td->td_ucred) { tracecred = p->p_tracecred; p->p_tracecred = crhold(td->td_ucred); + PROC_LOCK(td->td_proc); + p->p_tracefsize = lim_cur(td->td_proc, RLIMIT_FSIZE); + PROC_UNLOCK(td->td_proc); } p->p_traceflag |= facs; if (priv_check(td, PRIV_KTRACE) == 0)