sizeof jail parameter value strings

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

sizeof jail parameter value strings

Fabian Freyer
Hello lists,

From jail(3):

>     The jail_getv() function takes a null-terminated list of name and value
>     strings, and passes it to jail_get(2).  It is the caller's responsibility
>     to ensure that the value strings point to buffers large enough to hold
>     the string representation of the returned parameters.

What exactly does “large enough” mean here? Is there a way to query the size of
the corresponding kernel buffers at runtime? Is there a maximum length à la
MAX_JAIL_PARAM_LEN that the string representations of the returned parameters
are guaranteed to be shorter than?

I’m currently implementing a rust wrapper[1] around the jail(2) interface, and am
not sure how large buffers for the string parameters I’m querying with jail_get
jail_set have to be.

Fabian

(I’m not on the freebsd-jail mailing list, so I’d appreciate being kept in the CC)

[1] https://github.com/fubarnetes/libjail-rs

signature.asc (899 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: sizeof jail parameter value strings

James Gritton-2
[Sorry about bad headers and formatting - I took this off the archive
page]

"Fabian Freyer" <[hidden email]> wrote:

> From jail(3):
>
>>     The jail_getv() function takes a null-terminated list of name and
>> value
>>     strings, and passes it to jail_get(2).  It is the caller's
>> responsibility
>>     to ensure that the value strings point to buffers large enough to
>> hold
>>     the string representation of the returned parameters.
>
> What exactly does "large enough" mean here? Is there a way to query the
> size of
> the corresponding kernel buffers at runtime? Is there a maximum length
> a la
> MAX_JAIL_PARAM_LEN that the string representations of the returned
> parameters
> are guaranteed to be shorter than?
>
> I'm currently implementing a rust wrapper[1] around the jail(2)
> interface, and am
> not sure how large buffers for the string parameters I'm querying with
> jail_get
> jail_set have to be.

There is a way to find the length of a string parameter, though there
isn't a good library interface for it.  The security.jail.param.*
sysctls describe the form of the parameters, giving the type. The
"contents" of these sysctls  are generally unused (and set to zero), but
for string parameters there's actually the max length of the string
(itself in string form).  For non-string parameters, the length in
string form depends on the type of the parameters, so for an int you'll
need as long as the string representation of an ant can be, etc.  I  
don't know how much good C code will do for you for Rust work, but you
might want to take a look at jailparam_type() in the libjail source
code.

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.  jail_getv() just isn't a good fit for such a parameter.

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.  Again, if C
helps, take a glance at the jls source.

- Jamie
_______________________________________________
[hidden email] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-jail
To unsubscribe, send any mail to "[hidden email]"
Reply | Threaded
Open this post in threaded view
|

Re: sizeof jail parameter values

Fabian Freyer
[reordered parts of the reply for better reading flow]

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...).

> There is a way to find the length of a string parameter, though there
> isn't a good library interface for it.  The security.jail.param.*
> sysctls describe the form of the parameters, giving the type. The
> "contents" of these sysctls  are generally unused (and set to zero), but
> for string parameters there's actually the max length of the string
> (itself in string form).
Thanks, this works great for strings!

> For non-string parameters, the length in
> string form depends on the type of the parameters, so for an int you'll
> need as long as the string representation of an ant can be, etc.  I
> don't know how much good C code will do for you for Rust work, but you
> might want to take a look at jailparam_type() in the libjail source code.
> 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++) {
[...]

Fabian
_______________________________________________
[hidden email] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-jail
To unsubscribe, send any mail to "[hidden email]"
Reply | Threaded
Open this post in threaded view
|

Re: sizeof jail parameter values

James Gritton-2
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
_______________________________________________
[hidden email] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-jail
To unsubscribe, send any mail to "[hidden email]"