From 3c792b83f8f961544eb668b3d15c0a0c91f8c602 Mon Sep 17 00:00:00 2001 From: Alex Hornung Date: Wed, 24 Mar 2010 20:26:55 +0000 Subject: [PATCH] linprocfs - further fix /proc/{pid}/maps * Change to use sbufs instead of ksprintf and don't copy out to userland until done parsing maps. * Avoid using EFBIG, since linux programs don't understand it. * Make use of the new vn_fullpath guessing so that it is likely that we get the right path. * Fix a bug when fullpath was NULL. Reported-by: Samuel J. Greear --- .../linux/i386/linprocfs/linprocfs_misc.c | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/sys/emulation/linux/i386/linprocfs/linprocfs_misc.c b/sys/emulation/linux/i386/linprocfs/linprocfs_misc.c index 75ee1a6271..359174cdb3 100644 --- a/sys/emulation/linux/i386/linprocfs/linprocfs_misc.c +++ b/sys/emulation/linux/i386/linprocfs/linprocfs_misc.c @@ -704,12 +704,11 @@ int linprocfs_domaps(struct proc *curp, struct proc *p, struct pfsnode *pfs, struct uio *uio) { - int len; int error; vm_map_t map = &p->p_vmspace->vm_map; vm_map_entry_t entry; vm_ooffset_t off = 0; - char mebuffer[256]; + struct sbuf *sb; char *name = "", *freename = NULL; struct vnode *vp; struct vattr vat; @@ -721,7 +720,9 @@ linprocfs_domaps(struct proc *curp, struct proc *p, struct pfsnode *pfs, if (uio->uio_offset != 0) return (0); - + + sb = sbuf_new_auto(); + error = 0; vm_map_lock_read(map); for (entry = map->header.next; @@ -757,7 +758,7 @@ linprocfs_domaps(struct proc *curp, struct proc *p, struct pfsnode *pfs, } if (vp) { - vn_fullpath(curproc, vp, &name, &freename); + vn_fullpath(curproc, vp, &name, &freename, 1); vn_lock(vp, LK_SHARED | LK_RETRY); VOP_GETATTR(vp, &vat); ino = vat.va_fileid; @@ -771,11 +772,17 @@ linprocfs_domaps(struct proc *curp, struct proc *p, struct pfsnode *pfs, name = "[stack]"; } + /* + * We cannot safely hold the map locked while accessing + * userspace as a VM fault might recurse the locked map. + */ + vm_map_unlock_read(map); + /* * format: * start-end access offset major:minor inode [.text file] */ - ksnprintf(mebuffer, sizeof(mebuffer), + error = sbuf_printf(sb, "%08lx-%08lx %s%s%s%s %08llx %02x:%02x %llu%s%s\n", (u_long)entry->start, (u_long)entry->end, (entry->protection & VM_PROT_READ)?"r":"-", @@ -786,24 +793,13 @@ linprocfs_domaps(struct proc *curp, struct proc *p, struct pfsnode *pfs, 0, /* major */ 0, /* minor */ ino, /* inode */ - *name ? " " : "", - name); - + (name && *name) ? " " : "", + name ? name : ""); + if (error == -1) + error = ENOMEM; if (freename) kfree(freename, M_TEMP); - len = strlen(mebuffer); - if (len > uio->uio_resid) { - error = EFBIG; - break; - } - - /* - * We cannot safely hold the map locked while accessing - * userspace as a VM fault might recurse the locked map. - */ - vm_map_unlock_read(map); - error = uiomove(mebuffer, len, uio); vm_map_lock_read(map); if (error) break; @@ -824,5 +820,9 @@ linprocfs_domaps(struct proc *curp, struct proc *p, struct pfsnode *pfs, } vm_map_unlock_read(map); + sbuf_finish(sb); + if (error == 0) + error = uiomove_frombuf(sbuf_data(sb), sbuf_len(sb), uio); + sbuf_delete(sb); return error; } -- 2.41.0