1165503Sbms/*-
2165503Sbms * Copyright (c) 2006 Bruce M. Simpson
3165503Sbms * All rights reserved.
4165503Sbms *
5165503Sbms * Redistribution and use in source and binary forms, with or without
6165503Sbms * modification, are permitted provided that the following conditions
7165503Sbms * are met:
8165503Sbms * 1. Redistributions of source code must retain the above copyright
9165503Sbms *    notice, this list of conditions and the following disclaimer.
10165503Sbms * 2. Redistributions in binary form must reproduce the above copyright
11165503Sbms *    notice, this list of conditions and the following disclaimer in the
12165503Sbms *    documentation and/or other materials provided with the distribution.
13165503Sbms *
14165503Sbms * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15165503Sbms * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16165503Sbms * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17165503Sbms * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18165503Sbms * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19165503Sbms * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20165503Sbms * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21165503Sbms * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22165503Sbms * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23165503Sbms * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24165503Sbms * SUCH DAMAGE.
25165503Sbms *
26165503Sbms * $FreeBSD$
27165503Sbms */
28165503Sbms
29165503Sbms/*
30165503Sbms * Regression test for uiomove in kernel; specifically for PR kern/38495.
31165503Sbms */
32165503Sbms
33165503Sbms#include <sys/types.h>
34165503Sbms#include <sys/socket.h>
35165503Sbms#include <sys/un.h>
36165503Sbms
37165503Sbms#include <stdlib.h>
38165503Sbms#include <signal.h>
39165503Sbms#include <setjmp.h>
40165503Sbms#include <string.h>
41165503Sbms#include <err.h>
42165503Sbms#include <errno.h>
43165503Sbms#include <unistd.h>
44165503Sbms
45281974Sngiestatic char socket_path[] = "tmp.XXXXXX";
46165503Sbms
47165503Sbmsstatic jmp_buf myjmpbuf;
48165503Sbms
49281974Sngiestatic void handle_sigalrm(int signo __unused)
50165503Sbms{
51165503Sbms	longjmp(myjmpbuf, 1);
52165503Sbms}
53165503Sbms
54165503Sbmsint
55281974Sngiemain(void)
56165503Sbms{
57165503Sbms	struct sockaddr_un un;
58165503Sbms	pid_t pid;
59165503Sbms	int s;
60165503Sbms
61281974Sngie	if (mkstemp(socket_path) == -1)
62281974Sngie		err(1, "mkstemp");
63165503Sbms	s = socket(PF_LOCAL, SOCK_DGRAM, 0);
64165503Sbms	if (s == -1)
65165503Sbms		errx(-1, "socket");
66165503Sbms	memset(&un, 0, sizeof(un));
67165503Sbms	un.sun_family = AF_LOCAL;
68281974Sngie	unlink(socket_path);
69281974Sngie	strcpy(un.sun_path, socket_path);
70165503Sbms	if (bind(s, (struct sockaddr *)&un, sizeof(un)) == -1)
71165503Sbms		errx(-1, "bind");
72165503Sbms	pid = fork();
73165503Sbms	if (pid == -1)
74165503Sbms		errx(-1, "fork");
75165503Sbms	if (pid == 0) {
76165503Sbms		int conn;
77165503Sbms		char buf[] = "AAAAAAAAA";
78165503Sbms
79165503Sbms		close(s);
80165503Sbms		conn = socket(AF_LOCAL, SOCK_DGRAM, 0);
81165503Sbms		if (conn == -1)
82165503Sbms			errx(-1,"socket");
83165503Sbms		if (sendto(conn, buf, sizeof(buf), 0, (struct sockaddr *)&un,
84165503Sbms		    sizeof(un)) != sizeof(buf))
85165503Sbms			errx(-1,"sendto");
86165503Sbms		close(conn);
87165503Sbms		_exit(0);
88165503Sbms	}
89165503Sbms
90165503Sbms	sleep(5);
91165503Sbms
92165503Sbms	/* Make sure the data is there when we try to receive it. */
93165503Sbms	if (recvfrom(s, (void *)-1, 1, 0, NULL, NULL) != -1)
94165503Sbms		errx(-1,"recvfrom succeeded when failure expected");
95165503Sbms
96165503Sbms	(void)signal(SIGALRM, handle_sigalrm);
97165503Sbms	if (setjmp(myjmpbuf) == 0) {
98165503Sbms		/*
99165503Sbms	 	 * This recvfrom will panic an unpatched system, and block
100165503Sbms		 * a patched one.
101165503Sbms		 */
102165503Sbms		alarm(5);
103165503Sbms		(void)recvfrom(s, (void *)-1, 1, 0, NULL, NULL);
104165503Sbms	}
105165503Sbms
106165503Sbms	/* We should reach here via longjmp() and all should be well. */
107165503Sbms
108165503Sbms	return (0);
109165503Sbms}
110