Text file busy
Peter Edwards
peter.edwards at openet-telecom.com
Mon Sep 15 07:05:30 PDT 2003
Terry Lambert wrote:
>Wesley Morgan wrote:
>
>
>>It's also unfortunate that this protection does not seem to extend to
>>libaries. I've had some in-use X libraries get overwritten with some very
>>colorful results.
>>
>>
>
>So send patches.
>
>
I did a year ago :-) See PR 37554. (Not the original patch, the
self-follow-up).
That was for 4.5-STABLE: It's been running on a box that does nightly
builds of -current and -stable (and infrequent installworlds of -stable)
since then without any ill effects. A -current equivalent (with a sysctl
knob, "vm.mmap_exec_immutable", to turn the behaviour on/off) is
attached, in case anyone's interested.
As noted in the original PR, the choice of PROT_EXEC to decide to add
VV_TEXT to the vnode might be better done with a new mmap flag, say,
PROT_IMMUTABLE or something, but PROT_EXEC works fine for me.
-------------- next part --------------
Index: sys/vm/vm_mmap.c
===================================================================
RCS file: /pub/FreeBSD/development/FreeBSD-CVS/src/sys/vm/vm_mmap.c,v
retrieving revision 1.165
diff -u -r1.165 vm_mmap.c
--- sys/vm/vm_mmap.c 7 Sep 2003 18:47:54 -0000 1.165
+++ sys/vm/vm_mmap.c 15 Sep 2003 13:36:46 -0000
@@ -91,6 +91,11 @@
static int max_proc_mmap;
SYSCTL_INT(_vm, OID_AUTO, max_proc_mmap, CTLFLAG_RW, &max_proc_mmap, 0, "");
+static int mmap_exec_immutable = 1;
+SYSCTL_INT(_vm, OID_AUTO, mmap_exec_immutable, CTLFLAG_RW,
+ &mmap_exec_immutable, 1, "mmap(2) of a regular file for execute access "
+ "marks the file as immutable");
+
/*
* Set the maximum number of vm_map_entry structures per process. Roughly
* speaking vm_map_entry structures are tiny, so allowing them to eat 1/100
@@ -443,8 +448,18 @@
error = vm_mmap(&vms->vm_map, &addr, size, prot, maxprot,
flags, handle, pos);
mtx_lock(&Giant);
- if (error == 0)
+ if (error == 0) {
+ /*
+ * If mapping a regular file as PROT_EXEC, and configured to,
+ * mark the file as immutable
+ */
+ if (mmap_exec_immutable &&
+ handle != NULL && vp != NULL &&
+ (prot & PROT_EXEC) && vp->v_type == VREG)
+ vp->v_vflag |= VV_TEXT;
td->td_retval[0] = (register_t) (addr + pageoff);
+ }
+
done:
if (vp)
vput(vp);
More information about the freebsd-current
mailing list