diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -1886,7 +1886,8 @@ { char *tmparg; size_t outlen; - int error = 0, ro_string = 0; + int error = 0; + bool ro_string = false; /* * If the sysctl isn't writable and isn't a preallocated tunable that @@ -1898,21 +1899,22 @@ */ if ((oidp->oid_kind & (CTLFLAG_WR | CTLFLAG_TUN)) == 0 || arg2 == 0 || kdb_active) { - arg2 = strlen((char *)arg1) + 1; - ro_string = 1; + ro_string = true; } if (req->oldptr != NULL) { - if (ro_string) { + if (ro_string) tmparg = arg1; - outlen = strlen(tmparg) + 1; - } else { + else { tmparg = malloc(arg2, M_SYSCTLTMP, M_WAITOK); sx_slock(&sysctlstringlock); memcpy(tmparg, arg1, arg2); sx_sunlock(&sysctlstringlock); - outlen = strlen(tmparg) + 1; } + if (arg2 == 0) + outlen = arg2 = strlen(tmparg) + 1; + else + outlen = strnlen(tmparg, arg2 - 1) + 1; error = SYSCTL_OUT(req, tmparg, outlen); @@ -1921,7 +1923,12 @@ } else { if (!ro_string) sx_slock(&sysctlstringlock); - outlen = strlen((char *)arg1) + 1; + + if (arg2 == 0) + outlen = arg2 = strlen((char *)arg1) + 1; + else + outlen = strnlen((char *)arg1, arg2 - 1) + 1; + if (!ro_string) sx_sunlock(&sysctlstringlock); error = SYSCTL_OUT(req, NULL, outlen);