MFi386 rev 1.56:
Bring the linux mmap code more into line with how linux (2.4.x) behaves. Tested by: Scot Hetzel <swhetzel@gmail.com> on amd64 without PROT_EXEC Additionally to the i386 version always use PROT_EXEC in the mapping like the previous version of the amd64 code did. We need to examinate this further to decide what the right thing to do is. For now this fixes several problems in the LTP test runs and should behave regarding PROT_EXEC like before.
This commit is contained in:
parent
8b5b885047
commit
4f383e20a9
@ -34,6 +34,8 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/clock.h>
|
||||
#include <sys/imgact.h>
|
||||
#include <sys/limits.h>
|
||||
@ -728,9 +730,20 @@ linux_mmap_common(struct thread *td, struct l_mmap_argv *linux_args)
|
||||
off_t pos;
|
||||
} */ bsd_args;
|
||||
int error;
|
||||
struct file *fp;
|
||||
|
||||
error = 0;
|
||||
bsd_args.flags = 0;
|
||||
fp = NULL;
|
||||
|
||||
/*
|
||||
* Linux mmap(2):
|
||||
* You must specify exactly one of MAP_SHARED and MAP_PRIVATE
|
||||
*/
|
||||
if (! ((linux_args->flags & LINUX_MAP_SHARED) ^
|
||||
(linux_args->flags & LINUX_MAP_PRIVATE)))
|
||||
return (EINVAL);
|
||||
|
||||
if (linux_args->flags & LINUX_MAP_SHARED)
|
||||
bsd_args.flags |= MAP_SHARED;
|
||||
if (linux_args->flags & LINUX_MAP_PRIVATE)
|
||||
@ -813,17 +826,44 @@ linux_mmap_common(struct thread *td, struct l_mmap_argv *linux_args)
|
||||
bsd_args.addr = (caddr_t)PTRIN(linux_args->addr);
|
||||
bsd_args.len = linux_args->len;
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX i386 Linux always emulator forces PROT_READ on (why?)
|
||||
* so we do the same. We add PROT_EXEC to work around buggy
|
||||
* applications (e.g. Java) that take advantage of the fact
|
||||
* that execute permissions are not enforced by x86 CPUs.
|
||||
* We add PROT_EXEC to work around buggy applications (e.g. Java)
|
||||
* that take advantage of the fact that execute permissions are not
|
||||
* enforced by x86 CPUs.
|
||||
*/
|
||||
bsd_args.prot = linux_args->prot | PROT_EXEC | PROT_READ;
|
||||
bsd_args.prot = linux_args->prot | PROT_EXEC;
|
||||
if (linux_args->flags & LINUX_MAP_ANON)
|
||||
bsd_args.fd = -1;
|
||||
else
|
||||
else {
|
||||
/*
|
||||
* Linux follows Solaris mmap(2) description:
|
||||
* The file descriptor fildes is opened with
|
||||
* read permission, regardless of the
|
||||
* protection options specified.
|
||||
* If PROT_WRITE is specified, the application
|
||||
* must have opened the file descriptor
|
||||
* fildes with write permission unless
|
||||
* MAP_PRIVATE is specified in the flag
|
||||
* argument as described below.
|
||||
*/
|
||||
|
||||
if ((error = fget(td, linux_args->fd, &fp)) != 0)
|
||||
return (error);
|
||||
if (fp->f_type != DTYPE_VNODE) {
|
||||
fdrop(fp, td);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
/* Linux mmap() just fails for O_WRONLY files */
|
||||
if (! (fp->f_flag & FREAD)) {
|
||||
fdrop(fp, td);
|
||||
return (EACCES);
|
||||
}
|
||||
|
||||
bsd_args.fd = linux_args->fd;
|
||||
fdrop(fp, td);
|
||||
}
|
||||
bsd_args.pos = (off_t)linux_args->pgoff * PAGE_SIZE;
|
||||
bsd_args.pad = 0;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user