summaryrefslogtreecommitdiffstats
path: root/lib/libc
diff options
context:
space:
mode:
authormatthew <matthew@openbsd.org>2012-08-29 21:46:29 +0000
committermatthew <matthew@openbsd.org>2012-08-29 21:46:29 +0000
commit2f26b2a1690acc52ccc299c4fb9fe4ddc175af03 (patch)
tree78ea1231805906d23eeccb4fe9f955c432b573c8 /lib/libc
parentThe low-level guts to support MTP (Multi-Threaded Processing) on the (diff)
downloadwireguard-openbsd-2f26b2a1690acc52ccc299c4fb9fe4ddc175af03.tar.xz
wireguard-openbsd-2f26b2a1690acc52ccc299c4fb9fe4ddc175af03.zip
Fix _SC_CHILD_MAX, _SC_OPEN_MAX, and _SC_STREAM_MAX to correctly
handle rlim_cur set to RLIM_INFINITY or values greater than LONG_MAX, as unlikely as those are to happen. Further limit _SC_STREAM_MAX to at most SHRT_MAX, because struct __sFILE uses a short int for storing the file descriptor. While here, also remove a dead label that Clang complains about. From FreeBSD via Brad.
Diffstat (limited to 'lib/libc')
-rw-r--r--lib/libc/gen/sysconf.c44
1 files changed, 38 insertions, 6 deletions
diff --git a/lib/libc/gen/sysconf.c b/lib/libc/gen/sysconf.c
index 30810ad3de5..2998ea2ec7b 100644
--- a/lib/libc/gen/sysconf.c
+++ b/lib/libc/gen/sysconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sysconf.c,v 1.16 2012/06/24 20:11:16 matthew Exp $ */
+/* $OpenBSD: sysconf.c,v 1.17 2012/08/29 21:46:29 matthew Exp $ */
/*-
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
@@ -75,7 +75,15 @@ sysconf(int name)
mib[1] = KERN_ARGMAX;
break;
case _SC_CHILD_MAX:
- return (getrlimit(RLIMIT_NPROC, &rl) ? -1 : rl.rlim_cur);
+ if (getrlimit(RLIMIT_NPROC, &rl) != 0)
+ return (-1);
+ if (rl.rlim_cur == RLIM_INFINITY)
+ return (-1);
+ if (rl.rlim_cur > LONG_MAX) {
+ errno = EOVERFLOW;
+ return (-1);
+ }
+ return ((long)rl.rlim_cur);
case _SC_CLK_TCK:
return (CLK_TCK);
case _SC_JOB_CONTROL:
@@ -85,9 +93,34 @@ sysconf(int name)
mib[1] = KERN_NGROUPS;
break;
case _SC_OPEN_MAX:
- return (getrlimit(RLIMIT_NOFILE, &rl) ? -1 : rl.rlim_cur);
+ if (getrlimit(RLIMIT_NOFILE, &rl) != 0)
+ return (-1);
+ if (rl.rlim_cur == RLIM_INFINITY)
+ return (-1);
+ if (rl.rlim_cur > LONG_MAX) {
+ errno = EOVERFLOW;
+ return (-1);
+ }
+ return ((long)rl.rlim_cur);
case _SC_STREAM_MAX:
- return (FOPEN_MAX);
+ if (getrlimit(RLIMIT_NOFILE, &rl) != 0)
+ return (-1);
+ if (rl.rlim_cur == RLIM_INFINITY)
+ return (-1);
+ if (rl.rlim_cur > LONG_MAX) {
+ errno = EOVERFLOW;
+ return (-1);
+ }
+ /*
+ * struct __sFILE currently has a limitation that
+ * file descriptors must fit in a signed short.
+ * This doesn't precisely capture the letter of POSIX
+ * but approximates the spirit.
+ */
+ if (rl.rlim_cur > SHRT_MAX)
+ return (SHRT_MAX);
+
+ return ((long)rl.rlim_cur);
case _SC_TZNAME_MAX:
return (NAME_MAX);
case _SC_SAVED_IDS:
@@ -158,8 +191,7 @@ sysconf(int name)
case _SC_XOPEN_SHM:
mib[0] = CTL_KERN;
mib[1] = KERN_SYSVSHM;
-
-yesno: if (sysctl(mib, namelen, &value, &len, NULL, 0) == -1)
+ if (sysctl(mib, namelen, &value, &len, NULL, 0) == -1)
return (-1);
if (value == 0)
return (-1);