diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1998-07-07 07:12:54 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1998-07-07 07:12:54 +0000 |
commit | 92eb952610a47e72b227f82fa5b443acef185daa (patch) | |
tree | cb87ad6c6e14eb1fade24bd87b9eba352868bc5e | |
parent | 8a836816791cedf4b8b9c0387db0bbbffa977a86 (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.3 | 12 | ||||
-rw-r--r-- | lib/libc/gen/gethostname.3 | 19 | ||||
-rw-r--r-- | sys/kern/kern_sysctl.c | 50 | ||||
-rw-r--r-- | sys/sys/sysctl.h | 4 |
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)); |