proc: bugfix: array overrun from cgo in updateThreadList

This commit is contained in:
aarzilli
2016-01-08 09:43:37 +01:00
parent 4da4aea89c
commit 4266479531
3 changed files with 23 additions and 14 deletions

View File

@ -76,7 +76,7 @@ find_executable(int pid) {
} }
kern_return_t kern_return_t
get_threads(task_t task, void *slice) { get_threads(task_t task, void *slice, int limit) {
kern_return_t kret; kern_return_t kret;
thread_act_array_t list; thread_act_array_t list;
mach_msg_type_number_t count; mach_msg_type_number_t count;
@ -86,6 +86,11 @@ get_threads(task_t task, void *slice) {
return kret; return kret;
} }
if (count > limit) {
vm_deallocate(mach_task_self(), (vm_address_t) list, count * sizeof(list[0]));
return -2;
}
memcpy(slice, (void*)list, count*sizeof(list[0])); memcpy(slice, (void*)list, count*sizeof(list[0]));
kret = vm_deallocate(mach_task_self(), (vm_address_t) list, count * sizeof(list[0])); kret = vm_deallocate(mach_task_self(), (vm_address_t) list, count * sizeof(list[0]));

View File

@ -138,20 +138,25 @@ func (dbp *Process) updateThreadList() error {
var ( var (
err error err error
kret C.kern_return_t kret C.kern_return_t
count = C.thread_count(C.task_t(dbp.os.task)) count C.int
list []uint32
) )
for {
count = C.thread_count(C.task_t(dbp.os.task))
if count == -1 { if count == -1 {
return fmt.Errorf("could not get thread count") return fmt.Errorf("could not get thread count")
} }
list := make([]uint32, count) list = make([]uint32, count)
// TODO(dp) might be better to malloc mem in C and then free it here // TODO(dp) might be better to malloc mem in C and then free it here
// instead of getting count above and passing in a slice // instead of getting count above and passing in a slice
kret = C.get_threads(C.task_t(dbp.os.task), unsafe.Pointer(&list[0])) kret = C.get_threads(C.task_t(dbp.os.task), unsafe.Pointer(&list[0]), count)
if kret != C.KERN_SUCCESS { if kret != -2 {
return fmt.Errorf("could not get thread list") break
} }
if count < 0 { }
if kret != C.KERN_SUCCESS {
return fmt.Errorf("could not get thread list") return fmt.Errorf("could not get thread list")
} }

View File

@ -30,7 +30,7 @@ char *
find_executable(int pid); find_executable(int pid);
kern_return_t kern_return_t
get_threads(task_t task, void *); get_threads(task_t task, void *data,int limit);
int int
thread_count(task_t task); thread_count(task_t task);
@ -43,4 +43,3 @@ mach_send_reply(mach_msg_header_t);
kern_return_t kern_return_t
raise_exception(mach_port_t, mach_port_t, mach_port_t, exception_type_t); raise_exception(mach_port_t, mach_port_t, mach_port_t, exception_type_t);