proc: Add a sysctl to fetch virtual address space layout info
This provides information about fixed regions of the target process' user memory map. Reviewed by: kib MFC after: 1 month Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D33708
This commit is contained in:
parent
1811c1e957
commit
3ce04aca49
@ -432,6 +432,19 @@ struct kinfo_sigtramp32 {
|
||||
uint32_t ksigtramp_spare[4];
|
||||
};
|
||||
|
||||
struct kinfo_vm_layout32 {
|
||||
uint32_t kvm_min_user_addr;
|
||||
uint32_t kvm_max_user_addr;
|
||||
uint32_t kvm_text_addr;
|
||||
uint32_t kvm_text_size;
|
||||
uint32_t kvm_data_addr;
|
||||
uint32_t kvm_data_size;
|
||||
uint32_t kvm_stack_addr;
|
||||
uint32_t kvm_stack_size;
|
||||
int kvm_map_flags;
|
||||
uint32_t kvm_spare[14];
|
||||
};
|
||||
|
||||
struct kld_file_stat_1_32 {
|
||||
int version; /* set to sizeof(struct kld_file_stat_1) */
|
||||
char name[MAXPATHLEN];
|
||||
|
@ -3200,6 +3200,80 @@ sysctl_kern_proc_sigfastblk(SYSCTL_HANDLER_ARGS)
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
sysctl_kern_proc_vm_layout(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
struct kinfo_vm_layout kvm;
|
||||
struct proc *p;
|
||||
struct vmspace *vmspace;
|
||||
int error, *name;
|
||||
|
||||
name = (int *)arg1;
|
||||
if ((u_int)arg2 != 1)
|
||||
return (EINVAL);
|
||||
|
||||
error = pget((pid_t)name[0], PGET_CANDEBUG, &p);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
#ifdef COMPAT_FREEBSD32
|
||||
if (SV_CURPROC_FLAG(SV_ILP32)) {
|
||||
if (!SV_PROC_FLAG(p, SV_ILP32)) {
|
||||
PROC_UNLOCK(p);
|
||||
return (EINVAL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
vmspace = vmspace_acquire_ref(p);
|
||||
PROC_UNLOCK(p);
|
||||
|
||||
memset(&kvm, 0, sizeof(kvm));
|
||||
kvm.kvm_min_user_addr = vm_map_min(&vmspace->vm_map);
|
||||
kvm.kvm_max_user_addr = vm_map_max(&vmspace->vm_map);
|
||||
kvm.kvm_text_addr = (uintptr_t)vmspace->vm_taddr;
|
||||
kvm.kvm_text_size = vmspace->vm_tsize;
|
||||
kvm.kvm_data_addr = (uintptr_t)vmspace->vm_daddr;
|
||||
kvm.kvm_data_size = vmspace->vm_dsize;
|
||||
kvm.kvm_stack_addr = (uintptr_t)vmspace->vm_maxsaddr;
|
||||
kvm.kvm_stack_size = vmspace->vm_ssize;
|
||||
if ((vmspace->vm_map.flags & MAP_WIREFUTURE) != 0)
|
||||
kvm.kvm_map_flags |= KMAP_FLAG_WIREFUTURE;
|
||||
if ((vmspace->vm_map.flags & MAP_ASLR) != 0)
|
||||
kvm.kvm_map_flags |= KMAP_FLAG_ASLR;
|
||||
if ((vmspace->vm_map.flags & MAP_ASLR_IGNSTART) != 0)
|
||||
kvm.kvm_map_flags |= KMAP_FLAG_ASLR_IGNSTART;
|
||||
if ((vmspace->vm_map.flags & MAP_WXORX) != 0)
|
||||
kvm.kvm_map_flags |= KMAP_FLAG_WXORX;
|
||||
if ((vmspace->vm_map.flags & MAP_ASLR_STACK) != 0)
|
||||
kvm.kvm_map_flags |= KMAP_FLAG_ASLR_STACK;
|
||||
|
||||
#ifdef COMPAT_FREEBSD32
|
||||
if (SV_CURPROC_FLAG(SV_ILP32)) {
|
||||
struct kinfo_vm_layout32 kvm32;
|
||||
|
||||
memset(&kvm32, 0, sizeof(kvm32));
|
||||
kvm32.kvm_min_user_addr = (uint32_t)kvm.kvm_min_user_addr;
|
||||
kvm32.kvm_max_user_addr = (uint32_t)kvm.kvm_max_user_addr;
|
||||
kvm32.kvm_text_addr = (uint32_t)kvm.kvm_text_addr;
|
||||
kvm32.kvm_text_size = (uint32_t)kvm.kvm_text_size;
|
||||
kvm32.kvm_data_addr = (uint32_t)kvm.kvm_data_addr;
|
||||
kvm32.kvm_data_size = (uint32_t)kvm.kvm_data_size;
|
||||
kvm32.kvm_stack_addr = (uint32_t)kvm.kvm_stack_addr;
|
||||
kvm32.kvm_stack_size = (uint32_t)kvm.kvm_stack_size;
|
||||
kvm32.kvm_map_flags = kvm.kvm_map_flags;
|
||||
vmspace_free(vmspace);
|
||||
error = SYSCTL_OUT(req, &kvm32, sizeof(kvm32));
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
|
||||
error = SYSCTL_OUT(req, &kvm, sizeof(kvm));
|
||||
#ifdef COMPAT_FREEBSD32
|
||||
out:
|
||||
#endif
|
||||
vmspace_free(vmspace);
|
||||
return (error);
|
||||
}
|
||||
|
||||
SYSCTL_NODE(_kern, KERN_PROC, proc, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
|
||||
"Process table");
|
||||
|
||||
@ -3318,6 +3392,10 @@ static SYSCTL_NODE(_kern_proc, KERN_PROC_SIGFASTBLK, sigfastblk, CTLFLAG_RD |
|
||||
CTLFLAG_ANYBODY | CTLFLAG_MPSAFE, sysctl_kern_proc_sigfastblk,
|
||||
"Thread sigfastblock address");
|
||||
|
||||
static SYSCTL_NODE(_kern_proc, KERN_PROC_VM_LAYOUT, vm_layout, CTLFLAG_RD |
|
||||
CTLFLAG_ANYBODY | CTLFLAG_MPSAFE, sysctl_kern_proc_vm_layout,
|
||||
"Process virtual address space layout info");
|
||||
|
||||
int allproc_gen;
|
||||
|
||||
/*
|
||||
|
@ -1013,6 +1013,7 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
|
||||
#define KERN_PROC_CWD 42 /* process current working directory */
|
||||
#define KERN_PROC_NFDS 43 /* number of open file descriptors */
|
||||
#define KERN_PROC_SIGFASTBLK 44 /* address of fastsigblk magic word */
|
||||
#define KERN_PROC_VM_LAYOUT 45 /* virtual address space layout info */
|
||||
|
||||
/*
|
||||
* KERN_IPC identifiers
|
||||
|
@ -598,6 +598,25 @@ struct kinfo_sigtramp {
|
||||
void *ksigtramp_spare[4];
|
||||
};
|
||||
|
||||
#define KMAP_FLAG_WIREFUTURE 0x01 /* all future mappings wil be wired */
|
||||
#define KMAP_FLAG_ASLR 0x02 /* ASLR is applied to mappings */
|
||||
#define KMAP_FLAG_ASLR_IGNSTART 0x04 /* ASLR may map into sbrk grow region */
|
||||
#define KMAP_FLAG_WXORX 0x08 /* W^X mapping policy is enforced */
|
||||
#define KMAP_FLAG_ASLR_STACK 0x10 /* the stack location is randomized */
|
||||
|
||||
struct kinfo_vm_layout {
|
||||
uintptr_t kvm_min_user_addr;
|
||||
uintptr_t kvm_max_user_addr;
|
||||
uintptr_t kvm_text_addr;
|
||||
size_t kvm_text_size;
|
||||
uintptr_t kvm_data_addr;
|
||||
size_t kvm_data_size;
|
||||
uintptr_t kvm_stack_addr;
|
||||
size_t kvm_stack_size;
|
||||
int kvm_map_flags;
|
||||
uintptr_t kvm_spare[14];
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
/* Flags for kern_proc_out function. */
|
||||
#define KERN_PROC_NOTHREADS 0x1
|
||||
|
Loading…
Reference in New Issue
Block a user