summaryrefslogtreecommitdiff
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
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.
-rw-r--r--lib/libc/gen/getdomainname.312
-rw-r--r--lib/libc/gen/gethostname.319
-rw-r--r--sys/kern/kern_sysctl.c50
-rw-r--r--sys/sys/sysctl.h4
4 files changed, 69 insertions, 16 deletions
diff --git a/lib/libc/gen/getdomainname.3 b/lib/libc/gen/getdomainname.3
index 42c620c1ed1..fe4d944c3a7 100644
--- a/lib/libc/gen/getdomainname.3
+++ b/lib/libc/gen/getdomainname.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: getdomainname.3,v 1.5 1998/05/13 08:50:54 deraadt Exp $
+.\" $OpenBSD: getdomainname.3,v 1.6 1998/07/07 07:12:52 deraadt Exp $
.\"
.\" Copyright (c) 1983, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -53,8 +53,8 @@ The parameter
.Fa namelen
specifies the size of the
.Fa name
-array. The returned name is null-terminated unless insufficient
-space is provided.
+array. If insufficient space is provided, the returned name is truncated.
+The returned name is always null-terminated.
.Pp
.Fn Setdomainname
sets the domain name of the host machine to be
@@ -92,7 +92,11 @@ Domain names are limited to
.Dv MAXHOSTNAMELEN
(from
.Ao Pa sys/param.h Ac )
-characters, currently 256.
+characters, currently 256. This includes the terminating NUL character.
+.Pp
+If the buffer passed to
+.Fn getdomainname
+is too small, other operating systems may not gaurantee termination with NUL.
.Sh HISTORY
The
.Nm
diff --git a/lib/libc/gen/gethostname.3 b/lib/libc/gen/gethostname.3
index 881ba586e92..32b46fb9e1e 100644
--- a/lib/libc/gen/gethostname.3
+++ b/lib/libc/gen/gethostname.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: gethostname.3,v 1.5 1998/05/13 08:50:56 deraadt Exp $
+.\" $OpenBSD: gethostname.3,v 1.6 1998/07/07 07:12:53 deraadt Exp $
.\"
.\" Copyright (c) 1983, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -53,8 +53,8 @@ The parameter
.Fa namelen
specifies the size of the
.Fa name
-array. The returned name is null-terminated unless insufficient
-space is provided.
+array. If insufficient space is provided, the returned name is truncated.
+The returned name is always null-terminated.
.Pp
.Fn Sethostname
sets the name of the host machine to be
@@ -90,9 +90,20 @@ Host names are limited to
.Dv MAXHOSTNAMELEN
(from
.Ao Pa sys/param.h Ac )
-characters, currently 256.
+characters, currently 256. This includes the terminating NUL character.
+.Pp
+If the buffer passed to
+.Fn getdomainname
+is smaller than
+.Dv MAXHOSTNAMELEN ,
+other operating systems may not gaurantee termination with NUL.
.Sh HISTORY
The
.Nm
function call appeared in
.Bx 4.2 .
+.Sh STANDARDS
+The
+.Nm
+function call conforms to
+.St -xpg4.2 .
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);
diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h
index 4b47e752a8c..59e51573884 100644
--- a/sys/sys/sysctl.h
+++ b/sys/sys/sysctl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sysctl.h,v 1.25 1998/06/02 06:10:30 deraadt Exp $ */
+/* $OpenBSD: sysctl.h,v 1.26 1998/07/07 07:12:51 deraadt Exp $ */
/* $NetBSD: sysctl.h,v 1.16 1996/04/09 20:55:36 cgd Exp $ */
/*
@@ -383,6 +383,8 @@ typedef int (sysctlfn)
int sysctl_int __P((void *, size_t *, void *, size_t, int *));
int sysctl_rdint __P((void *, size_t *, void *, int));
int sysctl_string __P((void *, size_t *, void *, size_t, char *, int));
+int sysctl_tstring __P((void *, size_t *, void *, size_t, char *, int));
+int sysctl__string __P((void *, size_t *, void *, size_t, char *, int, int));
int sysctl_rdstring __P((void *, size_t *, void *, char *));
int sysctl_rdstruct __P((void *, size_t *, void *, void *, int));
int sysctl_struct __P((void *, size_t *, void *, size_t, void *, int));