Index: head/sys/compat/linux/linux_misc.c =================================================================== --- head/sys/compat/linux/linux_misc.c +++ head/sys/compat/linux/linux_misc.c @@ -232,22 +232,18 @@ linux_brk(struct thread *td, struct linux_brk_args *args) { struct vmspace *vm = td->td_proc->p_vmspace; - vm_offset_t new, old; - struct break_args /* { - char * nsize; - } */ tmp; + uintptr_t new, old; #ifdef DEBUG if (ldebug(brk)) printf(ARGS(brk, "%p"), (void *)(uintptr_t)args->dsend); #endif - old = (vm_offset_t)vm->vm_daddr + ctob(vm->vm_dsize); - new = (vm_offset_t)args->dsend; - tmp.nsize = (char *)new; - if (((caddr_t)new > vm->vm_daddr) && !sys_break(td, &tmp)) - td->td_retval[0] = (long)new; + old = (uintptr_t)vm->vm_daddr + ctob(vm->vm_dsize); + new = (uintptr_t)args->dsend; + if ((caddr_t)new > vm->vm_daddr && !kern_break(td, &new)) + td->td_retval[0] = (register_t)new; else - td->td_retval[0] = (long)old; + td->td_retval[0] = (register_t)old; return (0); } Index: head/sys/sys/syscallsubr.h =================================================================== --- head/sys/sys/syscallsubr.h +++ head/sys/sys/syscallsubr.h @@ -76,6 +76,7 @@ int kern_alternate_path(struct thread *td, const char *prefix, const char *path, enum uio_seg pathseg, char **pathbuf, int create, int dirfd); int kern_bindat(struct thread *td, int dirfd, int fd, struct sockaddr *sa); +int kern_break(struct thread *td, uintptr_t *addr); int kern_cap_ioctls_limit(struct thread *td, int fd, u_long *cmds, size_t ncmds); int kern_cap_rights_limit(struct thread *td, int fd, cap_rights_t *rights); Index: head/sys/vm/vm_unix.c =================================================================== --- head/sys/vm/vm_unix.c +++ head/sys/vm/vm_unix.c @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -69,6 +70,22 @@ sys_break(struct thread *td, struct break_args *uap) { #if !defined(__aarch64__) && !defined(__riscv__) + uintptr_t addr; + int error; + + addr = (uintptr_t)uap->nsize; + error = kern_break(td, &addr); + if (error == 0) + td->td_retval[0] = addr; + return (error); +#else /* defined(__aarch64__) || defined(__riscv__) */ + return (ENOSYS); +#endif /* defined(__aarch64__) || defined(__riscv__) */ +} + +int +kern_break(struct thread *td, uintptr_t *addr) +{ struct vmspace *vm = td->td_proc->p_vmspace; vm_map_t map = &vm->vm_map; vm_offset_t new, old, base; @@ -82,7 +99,7 @@ vmemlim = lim_cur(td, RLIMIT_VMEM); do_map_wirefuture = FALSE; - new = round_page((vm_offset_t)uap->nsize); + new = round_page(*addr); vm_map_lock(map); base = round_page((vm_offset_t) vm->vm_daddr); @@ -226,12 +243,9 @@ VM_MAP_WIRE_USER|VM_MAP_WIRE_NOHOLES); if (error == 0) - td->td_retval[0] = new; + *addr = new; return (error); -#else /* defined(__aarch64__) || defined(__riscv__) */ - return (ENOSYS); -#endif /* defined(__aarch64__) || defined(__riscv__) */ } #ifdef COMPAT_FREEBSD11