diff --git a/sys/vfs/procfs/procfs_rlimit.c b/sys/vfs/procfs/procfs_rlimit.c --- a/sys/vfs/procfs/procfs_rlimit.c +++ b/sys/vfs/procfs/procfs_rlimit.c @@ -58,15 +58,18 @@ { struct proc *p = lp->lwp_proc; size_t xlen; + size_t remain; char *ps; int error; int i; + int n; char psbuf[512]; /* XXX - conservative */ if (uio->uio_rw != UIO_READ) return (EOPNOTSUPP); ps = psbuf; + remain = sizeof(psbuf); for (i = 0; i < RLIM_NLIMITS; i++) { @@ -74,7 +77,13 @@ * Add the rlimit ident */ - ps += ksprintf(ps, "%s ", rlimit_ident[i]); + n = ksnprintf(ps, remain, "%s ", rlimit_ident[i]); + if (n < 0 || (size_t)n >= remain) { + error = ENOMEM; + goto bailout; + } + ps += n; + remain -= n; /* * Replace RLIM_INFINITY with -1 in the string @@ -85,27 +94,38 @@ */ if (p->p_rlimit[i].rlim_cur == RLIM_INFINITY) { - ps += ksprintf(ps, "-1 "); + n = ksnprintf(ps, remain, "-1 "); } else { - ps += ksprintf(ps, "%llu ", - (unsigned long long)p->p_rlimit[i].rlim_cur); + n = ksnprintf(ps, remain, "%llu ", + (unsigned long long)p->p_rlimit[i].rlim_cur); + } + if (n < 0 || (size_t)n >= remain) { + error = ENOMEM; + goto bailout; } + ps += n; + remain -= n; /* * maximum limit */ if (p->p_rlimit[i].rlim_max == RLIM_INFINITY) { - ps += ksprintf(ps, "-1\n"); + n = ksnprintf(ps, remain, "-1\n"); } else { - ps += ksprintf(ps, "%llu\n", - (unsigned long long)p->p_rlimit[i].rlim_max); + n = ksnprintf(ps, remain, "%llu\n", + (unsigned long long)p->p_rlimit[i].rlim_max); + } + if (n < 0 || (size_t)n >= remain) { + error = ENOMEM; + goto bailout; } + ps += n; + remain -= n; } xlen = ps - psbuf; error = uiomove_frombuf(psbuf, xlen, uio); - +bailout: return (error); } -