ommap: fix signed len and pos arguments
4.3 BSD's mmap took an int len and long pos. Reject negative lengths and in freebsd32 sign-extend pos correctly rather than mis-handling negative positions as large positive ones. Reviewed by: kib
This commit is contained in:
parent
3f8ced5bce
commit
01ce7fca44
|
@ -535,6 +535,15 @@ freebsd6_freebsd32_mmap(struct thread *td,
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef COMPAT_43
|
||||
int
|
||||
ofreebsd32_mmap(struct thread *td, struct ofreebsd32_mmap_args *uap)
|
||||
{
|
||||
return (kern_ommap(td, (uintptr_t)uap->addr, uap->len, uap->prot,
|
||||
uap->flags, uap->fd, uap->pos));
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
freebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap)
|
||||
{
|
||||
|
|
|
@ -176,8 +176,8 @@
|
|||
68 AUE_NULL OBSOL vwrite
|
||||
69 AUE_SBRK NOPROTO { int sbrk(int incr); }
|
||||
70 AUE_SSTK NOPROTO { int sstk(int incr); }
|
||||
71 AUE_MMAP COMPAT|NOPROTO { void *mmap(void *addr, int len, \
|
||||
int prot, int flags, int fd, int pos); }
|
||||
71 AUE_MMAP COMPAT { void *freebsd32_mmap(void *addr, int len, \
|
||||
int prot, int flags, int fd, int32_t pos); }
|
||||
72 AUE_O_VADVISE COMPAT11|NOPROTO { int vadvise(int anom); }
|
||||
73 AUE_MUNMAP NOPROTO { int munmap(void *addr, size_t len); }
|
||||
74 AUE_MPROTECT STD { int freebsd32_mprotect(void *addr, \
|
||||
|
|
|
@ -218,6 +218,8 @@ int kern_nanosleep(struct thread *td, struct timespec *rqt,
|
|||
int kern_ntp_adjtime(struct thread *td, struct timex *ntv, int *retvalp);
|
||||
int kern_ogetdirentries(struct thread *td, struct ogetdirentries_args *uap,
|
||||
long *ploff);
|
||||
int kern_ommap(struct thread *td, uintptr_t hint, int len, int oprot,
|
||||
int oflags, int fd, long pos);
|
||||
int kern_openat(struct thread *td, int fd, const char *path,
|
||||
enum uio_seg pathseg, int flags, int mode);
|
||||
int kern_pathconf(struct thread *td, const char *path,
|
||||
|
|
|
@ -456,6 +456,14 @@ struct ommap_args {
|
|||
#endif
|
||||
int
|
||||
ommap(struct thread *td, struct ommap_args *uap)
|
||||
{
|
||||
return (kern_ommap(td, (uintptr_t)uap->addr, uap->len, uap->prot,
|
||||
uap->flags, uap->fd, uap->pos));
|
||||
}
|
||||
|
||||
int
|
||||
kern_ommap(struct thread *td, uintptr_t hint, int len, int oprot,
|
||||
int oflags, int fd, long pos)
|
||||
{
|
||||
static const char cvtbsdprot[8] = {
|
||||
0,
|
||||
|
@ -469,35 +477,38 @@ ommap(struct thread *td, struct ommap_args *uap)
|
|||
};
|
||||
int flags, prot;
|
||||
|
||||
if (len < 0)
|
||||
return (EINVAL);
|
||||
|
||||
#define OMAP_ANON 0x0002
|
||||
#define OMAP_COPY 0x0020
|
||||
#define OMAP_SHARED 0x0010
|
||||
#define OMAP_FIXED 0x0100
|
||||
|
||||
prot = cvtbsdprot[uap->prot & 0x7];
|
||||
prot = cvtbsdprot[oprot & 0x7];
|
||||
#if (defined(COMPAT_FREEBSD32) && defined(__amd64__)) || defined(__i386__)
|
||||
if (i386_read_exec && SV_PROC_FLAG(td->td_proc, SV_ILP32) &&
|
||||
prot != 0)
|
||||
prot |= PROT_EXEC;
|
||||
#endif
|
||||
flags = 0;
|
||||
if (uap->flags & OMAP_ANON)
|
||||
if (oflags & OMAP_ANON)
|
||||
flags |= MAP_ANON;
|
||||
if (uap->flags & OMAP_COPY)
|
||||
if (oflags & OMAP_COPY)
|
||||
flags |= MAP_COPY;
|
||||
if (uap->flags & OMAP_SHARED)
|
||||
if (oflags & OMAP_SHARED)
|
||||
flags |= MAP_SHARED;
|
||||
else
|
||||
flags |= MAP_PRIVATE;
|
||||
if (uap->flags & OMAP_FIXED)
|
||||
if (oflags & OMAP_FIXED)
|
||||
flags |= MAP_FIXED;
|
||||
return (kern_mmap(td, &(struct mmap_req){
|
||||
.mr_hint = (uintptr_t)uap->addr,
|
||||
.mr_len = uap->len,
|
||||
.mr_hint = hint,
|
||||
.mr_len = len,
|
||||
.mr_prot = prot,
|
||||
.mr_flags = flags,
|
||||
.mr_fd = uap->fd,
|
||||
.mr_pos = uap->pos,
|
||||
.mr_fd = fd,
|
||||
.mr_pos = pos,
|
||||
}));
|
||||
}
|
||||
#endif /* COMPAT_43 */
|
||||
|
|
Loading…
Reference in New Issue