Introduce kern_mmap_req().
This presents an extensible interface to the generic mmap(2) implementation via a struct pointer intended to use a designated initializer or compount literal. We take advantage of the mandatory zeroing of fields not listed in the initializer. Remove kern_mmap_fpcheck() and use kern_mmap_req(). The motivation for this change is a desire to keep the core implementation from growing an ever-increasing number of arguments that must be specified in the correct order for the lowest-level implementations. In CheriBSD we have already added two more arguments. Reviewed by: kib Discussed with: kevans Obtained from: CheriBSD Sponsored by: DARPA, AFRL Differential Revision: https://reviews.freebsd.org/D23164
This commit is contained in:
parent
a2037dba7e
commit
d718de812f
@ -77,6 +77,7 @@ int
|
||||
linux_mmap_common(struct thread *td, uintptr_t addr, size_t len, int prot,
|
||||
int flags, int fd, off_t pos)
|
||||
{
|
||||
struct mmap_req mr, mr_fixed;
|
||||
struct proc *p = td->td_proc;
|
||||
struct vmspace *vms = td->td_proc->p_vmspace;
|
||||
int bsd_flags, error;
|
||||
@ -201,17 +202,25 @@ linux_mmap_common(struct thread *td, uintptr_t addr, size_t len, int prot,
|
||||
* address is not zero, try with MAP_FIXED and MAP_EXCL first,
|
||||
* and fall back to the normal behaviour if that fails.
|
||||
*/
|
||||
mr = (struct mmap_req) {
|
||||
.mr_hint = addr,
|
||||
.mr_len = len,
|
||||
.mr_prot = prot,
|
||||
.mr_flags = bsd_flags,
|
||||
.mr_fd = fd,
|
||||
.mr_pos = pos,
|
||||
.mr_check_fp_fn = linux_mmap_check_fp,
|
||||
};
|
||||
if (addr != 0 && (bsd_flags & MAP_FIXED) == 0 &&
|
||||
(bsd_flags & MAP_EXCL) == 0) {
|
||||
error = kern_mmap_fpcheck(td, addr, len, prot,
|
||||
bsd_flags | MAP_FIXED | MAP_EXCL, fd, pos,
|
||||
linux_mmap_check_fp);
|
||||
mr_fixed = mr;
|
||||
mr_fixed.mr_flags |= MAP_FIXED | MAP_EXCL;
|
||||
error = kern_mmap_req(td, &mr_fixed);
|
||||
if (error == 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
error = kern_mmap_fpcheck(td, addr, len, prot, bsd_flags, fd, pos,
|
||||
linux_mmap_check_fp);
|
||||
error = kern_mmap_req(td, &mr);
|
||||
out:
|
||||
LINUX_CTR2(mmap2, "return: %d (%p)", error, td->td_retval[0]);
|
||||
|
||||
|
@ -65,6 +65,18 @@ struct uio;
|
||||
|
||||
typedef int (*mmap_check_fp_fn)(struct file *, int, int, int);
|
||||
|
||||
struct mmap_req {
|
||||
vm_offset_t mr_hint;
|
||||
vm_size_t mr_len;
|
||||
int mr_prot;
|
||||
int mr_flags;
|
||||
int mr_fd;
|
||||
off_t mr_pos;
|
||||
mmap_check_fp_fn mr_check_fp_fn;
|
||||
};
|
||||
|
||||
int kern___getcwd(struct thread *td, char *buf, enum uio_seg bufseg,
|
||||
size_t buflen, size_t path_max);
|
||||
int kern_accept(struct thread *td, int s, struct sockaddr **name,
|
||||
socklen_t *namelen, struct file **fp);
|
||||
int kern_accept4(struct thread *td, int s, struct sockaddr **name,
|
||||
@ -182,9 +194,7 @@ int kern_mlock(struct proc *proc, struct ucred *cred, uintptr_t addr,
|
||||
size_t len);
|
||||
int kern_mmap(struct thread *td, uintptr_t addr, size_t len, int prot,
|
||||
int flags, int fd, off_t pos);
|
||||
int kern_mmap_fpcheck(struct thread *td, uintptr_t addr, size_t len,
|
||||
int prot, int flags, int fd, off_t pos,
|
||||
mmap_check_fp_fn check_fp_fn);
|
||||
int kern_mmap_req(struct thread *td, const struct mmap_req *mrp);
|
||||
int kern_mmap_maxprot(struct proc *p, int prot);
|
||||
int kern_mprotect(struct thread *td, uintptr_t addr, size_t size, int prot);
|
||||
int kern_msgctl(struct thread *, int, int, struct msqid_ds *);
|
||||
|
@ -199,26 +199,39 @@ int
|
||||
kern_mmap(struct thread *td, uintptr_t addr0, size_t len, int prot, int flags,
|
||||
int fd, off_t pos)
|
||||
{
|
||||
struct mmap_req mr = {
|
||||
.mr_hint = addr0,
|
||||
.mr_len = len,
|
||||
.mr_prot = prot,
|
||||
.mr_flags = flags,
|
||||
.mr_fd = fd,
|
||||
.mr_pos = pos
|
||||
};
|
||||
|
||||
return (kern_mmap_fpcheck(td, addr0, len, prot, flags, fd, pos, NULL));
|
||||
return (kern_mmap_req(td, &mr));
|
||||
}
|
||||
|
||||
/*
|
||||
* When mmap'ing a file, check_fp_fn may be used for the caller to do any
|
||||
* last-minute validation based on the referenced file in a non-racy way.
|
||||
*/
|
||||
int
|
||||
kern_mmap_fpcheck(struct thread *td, uintptr_t addr0, size_t len, int prot,
|
||||
int flags, int fd, off_t pos, mmap_check_fp_fn check_fp_fn)
|
||||
kern_mmap_req(struct thread *td, const struct mmap_req *mrp)
|
||||
{
|
||||
struct vmspace *vms;
|
||||
struct file *fp;
|
||||
struct proc *p;
|
||||
off_t pos;
|
||||
vm_offset_t addr;
|
||||
vm_size_t pageoff, size;
|
||||
vm_size_t len, pageoff, size;
|
||||
vm_prot_t cap_maxprot;
|
||||
int align, error, max_prot;
|
||||
int align, error, fd, flags, max_prot, prot;
|
||||
cap_rights_t rights;
|
||||
mmap_check_fp_fn check_fp_fn;
|
||||
|
||||
addr = mrp->mr_hint;
|
||||
len = mrp->mr_len;
|
||||
prot = mrp->mr_prot;
|
||||
flags = mrp->mr_flags;
|
||||
fd = mrp->mr_fd;
|
||||
pos = mrp->mr_pos;
|
||||
check_fp_fn = mrp->mr_check_fp_fn;
|
||||
|
||||
if ((prot & ~(_PROT_ALL | PROT_MAX(_PROT_ALL))) != 0)
|
||||
return (EINVAL);
|
||||
@ -239,7 +252,6 @@ kern_mmap_fpcheck(struct thread *td, uintptr_t addr0, size_t len, int prot,
|
||||
vms = p->p_vmspace;
|
||||
fp = NULL;
|
||||
AUDIT_ARG_FD(fd);
|
||||
addr = addr0;
|
||||
|
||||
/*
|
||||
* Ignore old flags that used to be defined but did not do anything.
|
||||
|
Loading…
Reference in New Issue
Block a user