PERFORCE change 105906 for review

Marcin Cieslak saper at SYSTEM.PL
Wed Sep 27 06:27:38 PDT 2006


Wojciech A. Koszek wrote:

What I basically do is:

Try to copy safely whatever caller provided us with:

>> +	if (bsd_args.level == SOL_SOCKET && name == LOCAL_PEERCRED) {
>> +		if ((error = copyin(PTRIN(linux_args.optval),
>> +			&linux_ucred, sizeof(linux_ucred))))
>> +			return (error);
>> +		if ((error = copyin(PTRIN(linux_args.optlen),
>> +			&optlen, sizeof(optlen))))
>> +			return (error);
>> +		if (optlen < sizeof(linux_ucred))
>> +			return (EFAULT);
>> +		xuclen = sizeof(xuc);

I just really need to copy the result into different structure
(unfortunately I think I can't use Linux structure provided by the caller).

>> +		/* XXX get PID */
>> +		linux_ucred.pid = 0;
>> +		linux_ucred.uid = xuc.cr_uid;
>> +		linux_ucred.gid = xuc.cr_gid;
>> +		if ((error = copyout(&linux_ucred,
>> +			PTRIN(linux_args.optval), sizeof(linux_ucred))))
>> +			return (error);
>> +		return (rc);

> I'm not sure if this patch is correct. I looked briefly over Marcin's
> report, and the code path responsible for handling translation between what
> Linux relies on and what FreeBSD requires. We tend to push the whole job in
> sogetopt() function, which in turn deploys uipc_ctloutput() function. With
> this mechanism, I belive it is possible to handle LOCAL_PEERCRED without a
> problem. The only exception is that the SOL_SOCKET has to be mapped to other
> value, like 0. This is what we actually do in getpeereid() case:

I don't I know if I understand this correctly; I will try to explain why
I did it this way -  the most important reason being my limited
knowledge of BSD kernel inner workings (I only studied Steven's TCP/IP
vol. 2 for that purpose long time ago).

I faced following design choice:

1) Just wrap FreeBSD call with minimal effort (I only duplicate
functionality of sooptcopyin(), sooptcopyout() in my code).
Not a nice way, however such approach work for most of the cases in the
linuxolator.

2) Provide copy of kern_getsockopt(), sogetopt() etc. just to provide
own version of uipc_ctloutput() fragment to write the result down to the
Linux structure.

This requires some care about lock and freeing memory structures. Also
if somebody for some reason restructures FreeBSD networking code there,
Linux emulation will be probably left aside - I've seen already one case
where Linux emulation mmap() was not up to date with FreeBSD mmap()
advances.

3) Provide some other way to plug another return structure for
uipc_ctloutput().

Probably the right way will be something between 1) and 2) - decide how
deep Linux sockopt functions replace sogetopt() and go immediately to
the level below in the respective networking code.

But I think I have not enough experience to decide on that.

It may happen that implementing delivery of the process ID of the other
side of the socket - feature not available AFAIK in the FreeBSD right
now - will impose on us much deeper dive into internal socket structures.

-- 
              << Marcin Cieslak // saper at system.pl >>


More information about the p4-projects mailing list