Do not allocate struct kinfo_vmobject on stack.

Its size is 1184 bytes.

Noted by:	eugen
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
This commit is contained in:
kib 2017-07-22 13:33:06 +00:00
parent 112fb3abf7
commit e38ce8ac29

View File

@ -2275,7 +2275,7 @@ vm_object_vnode(vm_object_t object)
static int static int
sysctl_vm_object_list(SYSCTL_HANDLER_ARGS) sysctl_vm_object_list(SYSCTL_HANDLER_ARGS)
{ {
struct kinfo_vmobject kvo; struct kinfo_vmobject *kvo;
char *fullpath, *freepath; char *fullpath, *freepath;
struct vnode *vp; struct vnode *vp;
struct vattr va; struct vattr va;
@ -2300,6 +2300,7 @@ sysctl_vm_object_list(SYSCTL_HANDLER_ARGS)
count * 11 / 10)); count * 11 / 10));
} }
kvo = malloc(sizeof(*kvo), M_TEMP, M_WAITOK);
error = 0; error = 0;
/* /*
@ -2317,13 +2318,13 @@ sysctl_vm_object_list(SYSCTL_HANDLER_ARGS)
continue; continue;
} }
mtx_unlock(&vm_object_list_mtx); mtx_unlock(&vm_object_list_mtx);
kvo.kvo_size = ptoa(obj->size); kvo->kvo_size = ptoa(obj->size);
kvo.kvo_resident = obj->resident_page_count; kvo->kvo_resident = obj->resident_page_count;
kvo.kvo_ref_count = obj->ref_count; kvo->kvo_ref_count = obj->ref_count;
kvo.kvo_shadow_count = obj->shadow_count; kvo->kvo_shadow_count = obj->shadow_count;
kvo.kvo_memattr = obj->memattr; kvo->kvo_memattr = obj->memattr;
kvo.kvo_active = 0; kvo->kvo_active = 0;
kvo.kvo_inactive = 0; kvo->kvo_inactive = 0;
TAILQ_FOREACH(m, &obj->memq, listq) { TAILQ_FOREACH(m, &obj->memq, listq) {
/* /*
* A page may belong to the object but be * A page may belong to the object but be
@ -2335,46 +2336,46 @@ sysctl_vm_object_list(SYSCTL_HANDLER_ARGS)
* approximation of the system anyway. * approximation of the system anyway.
*/ */
if (vm_page_active(m)) if (vm_page_active(m))
kvo.kvo_active++; kvo->kvo_active++;
else if (vm_page_inactive(m)) else if (vm_page_inactive(m))
kvo.kvo_inactive++; kvo->kvo_inactive++;
} }
kvo.kvo_vn_fileid = 0; kvo->kvo_vn_fileid = 0;
kvo.kvo_vn_fsid = 0; kvo->kvo_vn_fsid = 0;
kvo.kvo_vn_fsid_freebsd11 = 0; kvo->kvo_vn_fsid_freebsd11 = 0;
freepath = NULL; freepath = NULL;
fullpath = ""; fullpath = "";
vp = NULL; vp = NULL;
switch (obj->type) { switch (obj->type) {
case OBJT_DEFAULT: case OBJT_DEFAULT:
kvo.kvo_type = KVME_TYPE_DEFAULT; kvo->kvo_type = KVME_TYPE_DEFAULT;
break; break;
case OBJT_VNODE: case OBJT_VNODE:
kvo.kvo_type = KVME_TYPE_VNODE; kvo->kvo_type = KVME_TYPE_VNODE;
vp = obj->handle; vp = obj->handle;
vref(vp); vref(vp);
break; break;
case OBJT_SWAP: case OBJT_SWAP:
kvo.kvo_type = KVME_TYPE_SWAP; kvo->kvo_type = KVME_TYPE_SWAP;
break; break;
case OBJT_DEVICE: case OBJT_DEVICE:
kvo.kvo_type = KVME_TYPE_DEVICE; kvo->kvo_type = KVME_TYPE_DEVICE;
break; break;
case OBJT_PHYS: case OBJT_PHYS:
kvo.kvo_type = KVME_TYPE_PHYS; kvo->kvo_type = KVME_TYPE_PHYS;
break; break;
case OBJT_DEAD: case OBJT_DEAD:
kvo.kvo_type = KVME_TYPE_DEAD; kvo->kvo_type = KVME_TYPE_DEAD;
break; break;
case OBJT_SG: case OBJT_SG:
kvo.kvo_type = KVME_TYPE_SG; kvo->kvo_type = KVME_TYPE_SG;
break; break;
case OBJT_MGTDEVICE: case OBJT_MGTDEVICE:
kvo.kvo_type = KVME_TYPE_MGTDEVICE; kvo->kvo_type = KVME_TYPE_MGTDEVICE;
break; break;
default: default:
kvo.kvo_type = KVME_TYPE_UNKNOWN; kvo->kvo_type = KVME_TYPE_UNKNOWN;
break; break;
} }
VM_OBJECT_RUNLOCK(obj); VM_OBJECT_RUNLOCK(obj);
@ -2382,29 +2383,30 @@ sysctl_vm_object_list(SYSCTL_HANDLER_ARGS)
vn_fullpath(curthread, vp, &fullpath, &freepath); vn_fullpath(curthread, vp, &fullpath, &freepath);
vn_lock(vp, LK_SHARED | LK_RETRY); vn_lock(vp, LK_SHARED | LK_RETRY);
if (VOP_GETATTR(vp, &va, curthread->td_ucred) == 0) { if (VOP_GETATTR(vp, &va, curthread->td_ucred) == 0) {
kvo.kvo_vn_fileid = va.va_fileid; kvo->kvo_vn_fileid = va.va_fileid;
kvo.kvo_vn_fsid = va.va_fsid; kvo->kvo_vn_fsid = va.va_fsid;
kvo.kvo_vn_fsid_freebsd11 = va.va_fsid; kvo->kvo_vn_fsid_freebsd11 = va.va_fsid;
/* truncate */ /* truncate */
} }
vput(vp); vput(vp);
} }
strlcpy(kvo.kvo_path, fullpath, sizeof(kvo.kvo_path)); strlcpy(kvo->kvo_path, fullpath, sizeof(kvo->kvo_path));
if (freepath != NULL) if (freepath != NULL)
free(freepath, M_TEMP); free(freepath, M_TEMP);
/* Pack record size down */ /* Pack record size down */
kvo.kvo_structsize = offsetof(struct kinfo_vmobject, kvo_path) + kvo->kvo_structsize = offsetof(struct kinfo_vmobject, kvo_path)
strlen(kvo.kvo_path) + 1; + strlen(kvo->kvo_path) + 1;
kvo.kvo_structsize = roundup(kvo.kvo_structsize, kvo->kvo_structsize = roundup(kvo->kvo_structsize,
sizeof(uint64_t)); sizeof(uint64_t));
error = SYSCTL_OUT(req, &kvo, kvo.kvo_structsize); error = SYSCTL_OUT(req, kvo, kvo->kvo_structsize);
mtx_lock(&vm_object_list_mtx); mtx_lock(&vm_object_list_mtx);
if (error) if (error)
break; break;
} }
mtx_unlock(&vm_object_list_mtx); mtx_unlock(&vm_object_list_mtx);
free(kvo, M_TEMP);
return (error); return (error);
} }
SYSCTL_PROC(_vm, OID_AUTO, objects, CTLTYPE_STRUCT | CTLFLAG_RW | CTLFLAG_SKIP | SYSCTL_PROC(_vm, OID_AUTO, objects, CTLTYPE_STRUCT | CTLFLAG_RW | CTLFLAG_SKIP |