Bug 54418

Summary: Bug in VM page protection handling.
Product: Base System Reporter: Pawel Jakub Dawidek <nick>
Component: kernAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Only Me CC: alc
Priority: Normal    
Version: Unspecified   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
file.diff none

Description Pawel Jakub Dawidek 2003-07-12 21:10:13 UTC
	There is a problem in setting page protection in function
	vm_map_protect().
	When we set for example max_protection to VM_PROT_READ and
	after that we will try do change max_protection to VM_PROT_ALL
	there is no chance to do that, because of bogus check. This 'if'
	doesn't check if we set max_protection or just protection and
	denieds all increasing max_protection tries.
	Problem doesn't affect FreeBSD directly, because such situation
	never occurs, but for 3rd-party kernel modules this could be importent.
	For example, for my module - cerb - where I need to do operations
	on VM pages, it is very important and this bug provoke 'Bus error's
	in some situations.

Fix: This patch fix this.
How-To-Repeat: 	This sample kernel module shows the problem. It is for FreeBSD 4.x,
	but simlar could be prepared for 5.x.

#include <sys/param.h>

#include <sys/proc.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/systm.h>

#include <sys/lock.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <vm/vm_map.h>

static int
mod(struct module *module, int cmd, void *arg)
{
	vm_map_t map = &curproc->p_vmspace->vm_map;
	vm_offset_t start, end;
	int error = 0;

	switch (cmd) {
	case MOD_LOAD:
		end = start = (vm_offset_t)curproc->p_vmspace->vm_daddr +
		    ctob(curproc->p_vmspace->vm_dsize);
		start--;
		error = vm_map_protect(map, start, end, VM_PROT_READ, TRUE);
		printf("ERROR1: %d\n", error);
		error = vm_map_protect(map, start, end, VM_PROT_ALL, TRUE);
		/* Here should be 2 which means KERN_PROTECTION_FAILURE. */
		printf("ERROR2: %d\n", error);
		error = 0;
		printf("testmod loaded.\n");
		break;
	case MOD_UNLOAD:
		printf("testmod unloaded.\n");
		break;
	default:
		error = EINVAL;
		break;
	}

	return (error);
}

static moduledata_t testmod_mod =
{
	"testmod",
	mod,
	NULL
};

DECLARE_MODULE(testmod, testmod_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
Comment 1 Maxim Konovalov freebsd_committer freebsd_triage 2003-07-13 11:11:26 UTC
State Changed
From-To: open->closed

As alc@ said it is not a bug.
Comment 2 Ceri Davies freebsd_committer freebsd_triage 2003-07-13 13:03:47 UTC
Adding to audit trail, from misfiled PR kern/54420:

Date: Sat, 12 Jul 2003 15:36:27 -0500
From: "Alan L. Cox" <alc@imimic.com>
Message-Id: <3F10714B.44FAD294@imimic.com>
References: <20030712201112.87A7E3ABB53@milla.ask33.net>

 Never mind the comment about the breakage.  That is not correct.
 
 Regards,
 Alan