From owner-freebsd-hackers@freebsd.org Sat Jun 16 23:32:09 2018 Return-Path: Delivered-To: freebsd-hackers@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 459881002034; Sat, 16 Jun 2018 23:32:09 +0000 (UTC) (envelope-from jamie@freebsd.org) Received: from gritton.org (gritton.org [199.192.165.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "gritton.org", Issuer "Let's Encrypt Authority X3" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id D315073A1B; Sat, 16 Jun 2018 23:32:08 +0000 (UTC) (envelope-from jamie@freebsd.org) Received: from gritton.org ([127.0.0.131]) by gritton.org (8.15.2/8.15.2) with ESMTP id w5GNC185071868; Sat, 16 Jun 2018 17:12:02 -0600 (MDT) (envelope-from jamie@freebsd.org) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Date: Sat, 16 Jun 2018 17:12:01 -0600 From: James Gritton To: Fabian Freyer Cc: freebsd-jail@freebsd.org, freebsd-hackers@freebsd.org Subject: Re: sizeof jail parameter values In-Reply-To: References: Message-ID: <92cb2f93a546e02a7fb5e11ea976e846@freebsd.org> X-Sender: jamie@freebsd.org User-Agent: Roundcube Webmail/1.3.6 X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 16 Jun 2018 23:32:09 -0000 On 2018-06-16 11:31, Fabian Freyer wrote: > On 05/18/2018 18:49, James Gritton wrote: > >> I would recommend skipping out on jail_getv(), which is really only >> good for getting a few well-known parameters, and instead use the more >> complete but more complex jailparam_init/get/export/free. > Thanks! I ended up writing wrappers around the jail_get(2) and > jail_set(2) interfaces and constructing the iovectors myself, which > ended up quite a bit cleaner. The jailparam_{init,get,export,free} > APIs are unnecessarily complex and don't seem to be a good fit > (writing wrappers around wrappers around wrappers etc...). They're an attempt to make generic handlers in C, which isn't exactly a language geared toward such things. If you're working only with a few specific known fields, your way is just as well. >> It gets more complicated with array parameters, those that can hold an >> arbitrary number of values.  The IP addresses are the best example of >> that. > I've now hit that snag. I see that the security.jail.param.ip4.addr > and security.jail.param.ip6.addr sysctls contain the sizes of an > in_addr_t and an in6_addr_t, respectively. How would I now determine > the number of IPv4 and IPv6 addresses, or should I just allocate > security.jail.jail_max_af_ips per family? I've tried to go through how > libjail does it, but don't quite understand it, nor the implied race > conditions (?) it attempts to mitigate by reading the vector multiple > times: > > lib/libjail/jail.c: > /* > * Get the prison. If there are array elements, retry a few times > * in case their sizes changed from under us. > */ > for (sanity = 0;; sanity++) { > [...] If you read a parameters with the value's iov_base set to NULL, it will return the parameter's length into your iov_len. So the way to read any variable-length parameter is to call jail_get(2) once with a NULL value, allocate a buffer according to the returned length, and then call it again with the allocated iov_base. The race condition I look for is the jail changing between the time I get the length and the time I read the value - like most races, very unlikely. Once again, this is for the generic case. If you have a value with a known (and reasonably sized) maximum, such as MAXHOSTNAMELEN or max_af_ips, it's easier to just use that. - James