1140348Srwatson/*- 2140348Srwatson * Copyright (c) 2005 Robert N. M. Watson 3140348Srwatson * All rights reserved. 4140348Srwatson * 5140348Srwatson * Redistribution and use in source and binary forms, with or without 6140348Srwatson * modification, are permitted provided that the following conditions 7140348Srwatson * are met: 8140348Srwatson * 1. Redistributions of source code must retain the above copyright 9140348Srwatson * notice, this list of conditions and the following disclaimer. 10140348Srwatson * 2. Redistributions in binary form must reproduce the above copyright 11140348Srwatson * notice, this list of conditions and the following disclaimer in the 12140348Srwatson * documentation and/or other materials provided with the distribution. 13140348Srwatson * 14140348Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15140348Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16140348Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17140348Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18140348Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19140348Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20140348Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21140348Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22140348Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23140348Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24140348Srwatson * SUCH DAMAGE. 25140348Srwatson * 26140348Srwatson * $FreeBSD$ 27140348Srwatson */ 28140348Srwatson 29140348Srwatson#include <sys/param.h> 30140348Srwatson#include <sys/jail.h> 31140348Srwatson#include <sys/socket.h> 32140348Srwatson 33140348Srwatson#include <netinet/in.h> 34140348Srwatson 35140348Srwatson#include <arpa/inet.h> 36140348Srwatson 37140348Srwatson#include <err.h> 38140348Srwatson#include <errno.h> 39140348Srwatson#include <stdio.h> 40140348Srwatson#include <stdlib.h> 41140348Srwatson#include <string.h> 42140348Srwatson#include <unistd.h> 43140348Srwatson 44140348Srwatson/* 45140348Srwatson * A bug in the jail(8) code prevented processes in jail from properly 46140348Srwatson * connecting UDP sockets. This test program attempts to exercise that bug. 47140348Srwatson */ 48140348Srwatson 49140348Srwatsonstatic void 50140348Srwatsonusage(void) 51140348Srwatson{ 52140348Srwatson 53140348Srwatson fprintf(stderr, "udpconnectjail: no arguments\n"); 54140348Srwatson exit(-1); 55140348Srwatson} 56140348Srwatson 57140348Srwatsonstatic void 58140348Srwatsontest(const char *context, struct sockaddr_in *sin) 59140348Srwatson{ 60140348Srwatson int sock; 61140348Srwatson 62140348Srwatson sock = socket(PF_INET, SOCK_DGRAM, 0); 63140348Srwatson if (sock == -1) 64140348Srwatson errx(-1, "%s: socket(PF_INET, SOCK_DGRAM, 0): %s", context, 65140348Srwatson strerror(errno)); 66140348Srwatson 67140352Srwatson if (connect(sock, (struct sockaddr *)sin, sizeof(*sin)) < 0) 68140348Srwatson errx(-1, "%s: connect(%s): %s", context, 69140348Srwatson inet_ntoa(sin->sin_addr), strerror(errno)); 70140348Srwatson 71140348Srwatson if (close(sock) < 0) 72140348Srwatson errx(-1, "%s: close(): %s", context, strerror(errno)); 73140348Srwatson} 74140348Srwatson 75140348Srwatsonint 76140348Srwatsonmain(int argc, __unused char *argv[]) 77140348Srwatson{ 78140348Srwatson struct sockaddr_in sin; 79140348Srwatson struct jail thejail; 80222487Sbz struct in_addr ia4; 81140348Srwatson 82140348Srwatson if (argc != 1) 83140348Srwatson usage(); 84140348Srwatson 85140348Srwatson bzero(&sin, sizeof(sin)); 86140348Srwatson sin.sin_len = sizeof(sin); 87140348Srwatson sin.sin_family = AF_INET; 88140348Srwatson sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 89140352Srwatson sin.sin_port = htons(8080); /* Arbitrary */ 90140348Srwatson 91140348Srwatson /* 92140348Srwatson * First run the system call test outside of a jail. 93140348Srwatson */ 94140348Srwatson test("not in jail", &sin); 95140348Srwatson 96140348Srwatson /* 97140348Srwatson * Now re-run in a jail. 98222487Sbz * XXX-BZ should switch to jail_set(2). 99140348Srwatson */ 100222487Sbz ia4.s_addr = htonl(INADDR_LOOPBACK); 101222487Sbz 102140348Srwatson bzero(&thejail, sizeof(thejail)); 103222487Sbz thejail.version = JAIL_API_VERSION; 104140348Srwatson thejail.path = "/"; 105140348Srwatson thejail.hostname = "jail"; 106222487Sbz thejail.jailname = "udpconnectjail"; 107222487Sbz thejail.ip4s = 1; 108222487Sbz thejail.ip4 = &ia4; 109222487Sbz 110140348Srwatson if (jail(&thejail) < 0) 111140348Srwatson errx(-1, "jail: %s", strerror(errno)); 112140348Srwatson test("in jail", &sin); 113140348Srwatson 114140348Srwatson fprintf(stdout, "PASS\n"); 115140348Srwatson 116140348Srwatson return (0); 117140348Srwatson} 118