summaryrefslogtreecommitdiff
path: root/sys/kern/kern_sysctl.c
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1998-07-07 07:12:54 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1998-07-07 07:12:54 +0000
commit92eb952610a47e72b227f82fa5b443acef185daa (patch)
treecb87ad6c6e14eb1fade24bd87b9eba352868bc5e /sys/kern/kern_sysctl.c
parent8a836816791cedf4b8b9c0387db0bbbffa977a86 (diff)
per XPG, gethostname() with a short buffer returns truncated data - not ENOMEM.
As permitted, make the truncated buffer be NUL terminated. make getdomainname() match.
Diffstat (limited to 'sys/kern/kern_sysctl.c')
-rw-r--r--sys/kern/kern_sysctl.c50
1 files changed, 43 insertions, 7 deletions
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index c0d0316cfa7..bf8ec43273d 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_sysctl.c,v 1.25 1998/06/02 06:10:28 deraadt Exp $ */
+/* $OpenBSD: kern_sysctl.c,v 1.26 1998/07/07 07:12:40 deraadt Exp $ */
/* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */
/*-
@@ -246,13 +246,13 @@ kern_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
securelevel = level;
return (0);
case KERN_HOSTNAME:
- error = sysctl_string(oldp, oldlenp, newp, newlen,
+ error = sysctl_tstring(oldp, oldlenp, newp, newlen,
hostname, sizeof(hostname));
if (newp && !error)
hostnamelen = newlen;
return (error);
case KERN_DOMAINNAME:
- error = sysctl_string(oldp, oldlenp, newp, newlen,
+ error = sysctl_tstring(oldp, oldlenp, newp, newlen,
domainname, sizeof(domainname));
if (newp && !error)
domainnamelen = newlen;
@@ -479,16 +479,52 @@ sysctl_string(oldp, oldlenp, newp, newlen, str, maxlen)
char *str;
int maxlen;
{
+ return sysctl__string(oldp, oldlenp, newp, newlen, str, maxlen, 0);
+}
+
+int
+sysctl_tstring(oldp, oldlenp, newp, newlen, str, maxlen)
+ void *oldp;
+ size_t *oldlenp;
+ void *newp;
+ size_t newlen;
+ char *str;
+ int maxlen;
+{
+ return sysctl__string(oldp, oldlenp, newp, newlen, str, maxlen, 1);
+}
+
+int
+sysctl__string(oldp, oldlenp, newp, newlen, str, maxlen, trunc)
+ void *oldp;
+ size_t *oldlenp;
+ void *newp;
+ size_t newlen;
+ char *str;
+ int maxlen;
+ int trunc;
+{
int len, error = 0;
+ char c;
len = strlen(str) + 1;
- if (oldp && *oldlenp < len)
- return (ENOMEM);
+ if (oldp && *oldlenp < len) {
+ if (trunc == 0 || *oldlenp == 0)
+ return (ENOMEM);
+ }
if (newp && newlen >= maxlen)
return (EINVAL);
if (oldp) {
- *oldlenp = len;
- error = copyout(str, oldp, len);
+ if (trunc && *oldlenp < len) {
+ /* XXX save & zap NUL terminator while copying */
+ c = str[*oldlenp-1];
+ str[*oldlenp-1] = '\0';
+ error = copyout(str, oldp, *oldlenp);
+ str[*oldlenp-1] = c;
+ } else {
+ *oldlenp = len;
+ error = copyout(str, oldp, len);
+ }
}
if (error == 0 && newp) {
error = copyin(newp, str, newlen);