--- /dev/null
+/*
+ * Copyright (c) 2014-2016 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "tests.h"
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static void
+check_overflow_id(const int id, const char *overflowid)
+{
+ int fd = open(overflowid, O_RDONLY);
+ if (fd < 0) {
+ if (ENOENT == errno)
+ return;
+ perror_msg_and_fail("open: %s", overflowid);
+ }
+
+ /* we trust the kernel */
+ char buf[sizeof(int)*3];
+ int n = read(fd, buf, sizeof(buf) - 1);
+ if (n > 0) {
+ buf[n] = '\0';
+ n = atoi(buf);
+ if (id == n)
+ error_msg_and_skip("%d matches %s", id, overflowid);
+ }
+
+ close(fd);
+}
+
+void
+check_overflowuid(const int uid)
+{
+ check_overflow_id(uid, "/proc/sys/kernel/overflowuid");
+}
+
+void
+check_overflowgid(const int gid)
+{
+ check_overflow_id(gid, "/proc/sys/kernel/overflowgid");
+}
unsigned long inode_of_sockfd(int);
/* Print string in quoted form. */
-void print_quoted_string(const char *str);
+void print_quoted_string(const char *);
+
+/* Check whether given uid matches kernel overflowuid. */
+void check_overflowuid(const int);
+
+/* Check whether given gid matches kernel overflowgid. */
+void check_overflowgid(const int);
# define ARRAY_SIZE(arg) ((unsigned int) (sizeof(arg) / sizeof((arg)[0])))
# define LENGTH_OF(arg) ((unsigned int) sizeof(arg) - 1)
# define __NR_getuid __NR_getxuid
# endif
uid = syscall(__NR_getuid);
-
- (void) close(0);
- if (open("/proc/sys/kernel/overflowuid", O_RDONLY) == 0) {
- /* we trust the kernel */
- char buf[sizeof(int)*3];
- int n = read(0, buf, sizeof(buf) - 1);
- if (n) {
- buf[n] = '\0';
- n = atoi(buf);
- if (uid == n)
- error_msg_and_skip("getuid() == overflowuid");
- }
- (void) close(0);
- }
+ check_overflowuid(uid);
assert(syscall(__NR_setuid, uid) == 0);
{
int *list = 0;
uid = syscall(__NR_getuid);
-
- (void) close(0);
- if (open("/proc/sys/kernel/overflowuid", O_RDONLY) == 0) {
- /* we trust the kernel */
- char buf[sizeof(int)*3];
- int n = read(0, buf, sizeof(buf) - 1);
- if (n) {
- buf[n] = '\0';
- n = atoi(buf);
- if (uid == n)
- error_msg_and_skip("getuid() == overflowuid");
- }
- close(0);
- }
+ check_overflowuid(uid);
assert(syscall(__NR_setuid, uid) == 0);
{