[prev in list] [next in list] [prev in thread] [next in thread]
List: freedesktop-dbus
Subject: Re: RFC: adding fd-passing to win32
From: Hailun Tan <dearambermini () gmail ! com>
Date: 2022-08-09 23:29:09
Message-ID: CAEjDU6r1=XXASFGGEkNE+abCQsJJ-Qfbsq2QczTZYtGwE7qtQw () mail ! gmail ! com
[Download RAW message or body]
Unsubscribed for the god sake.
On Fri, 5 Aug 2022 at 5:36 pm, Marc-André Lureau <marcandre.lureau@gmail.com>
wrote:
> Hi
>
> On Thu, Aug 4, 2022 at 11:36 PM Simon McVittie <smcv@collabora.com> wrote:
>
>> On Wed, 03 Aug 2022 at 14:54:21 +0400, Marc-André Lureau wrote:
>> > The array elements have
>> > the handle type & value or details for SOCKET. The body 'H' arguments
>> index the
>> > array, similar to 'h' FDs values.
>>
>> Is there a reason why the wire protocol can't use the same 'h' type as
>> on Unix? In the wire protocol, the 'h' type is just a special sort of
>> integer, with the conventional semantics being that it is an index into an
>> array of out-of-band file descriptors. Can the Windows equivalent be
>> making
>> it an index into an array of HANDLEs?
>>
>
> As you probably know, HANDLEs are not FD. And Windows has the 2 types, and
> functions to map to/from the 2 (_get_osfhandle/_open_osfhandle).
>
> With the addition of AF_UNIX socket support, Windows developers have shown
> interest in adding more features over time (
> https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/#unsupportedunavailable),
> including SCM_RIGHTS/fdpass.
>
> If some day, Windows has SCM_RIGHTS, we should enable that code too. For
> those reasons, I think we should add a new type. If 'H' is not a good
> character, please advise.
>
>
>> This would work very well for GDBus, which literally represents the 'h'
>> type as an integer index into the GUnixFdList, but might be a bit weird
>> in libdbus, which transparently replaces the integer index with the actual
>> file descriptor (which of course will usually be numerically unequal to
>> either the index, or the fd in the sender) while iterating a received
>> message's arguments, or transparently replaces a fd with an index into
>> the array of fds to be sent while building a new message to be sent.
>> HANDLEs are not the same size as int, so the ABI for dealing with handles
>> would be different on Unix and Windows.
>>
>
> I handled that in my dev branch. I introduced a new type to wrap HANDLE or
> SOCKET (or future handle kinds as needed):
>
> /*
> * Handles which are not yet supported:
> * - Change notification: FindCloseChangeNotification
> * - Event log: CloseEventLog
> * - Find file: FindClose
> * - Update resource: EndUpdateResource
> */
>
> typedef struct DBusWinHandle DBusWinHandle;
>
> struct DBusWinHandle {
> int type;
> union {
> SOCKET socket;
> HANDLE handle;
> } u;
> };
>
>
>
>> I can see why the authors of fd-passing in libdbus did it this way,
>> but with hindsight, GDBus' approach is probably better.
>>
>
> may be :) in my glib/gio wip branch, I re-use the fdlist (mapping HANDLEs
> to FD). The problem with that approach is that the client looses the HANDLE
> type information, which may be hard to get back (there are "bad" &
> undocumented windows API to do that). I plan to change that, to introduce a
> HANDLE list & API instead.
>
>
>
>> If the Windows HANDLEs or SOCKETs have to be sent in-band as ordinary
>> bytes in the message stream, rather than out-of-band as a special
>> kernel-mediated capability (which seems odd to me, but I'm not a
>> Windows expert), then they should probably be in a new header field of
>>
>
> yes, you have to use DuplicateHandle/wsaduplicatesocket and send the
> handle details to the target, via ipc.
>
>
>> an appropriate type (perhaps 'at' if a bare 64-bit integer is enough,
>> or 'a(t...)' if you need a 64-bit integer plus metadata, or something
>> along those lines).
>>
>> Something like this (in GVariant-ish pseudocode):
>>
>> header = (
>> byte endianness,
>> byte message type,
>> byte flags,
>> byte major_version,
>> uint32 body_length,
>> uint32 serial,
>> @a(yv) {
>> PATH: <'/foo'>,
>> INTERFACE: <'com.example.ArbitraryCodeExecution'>,
>> MEMBER: <'ExecCommand'>,
>> ...,
>> WINDOWS_HANDLES: @a(t...) [ # a new header field
>> (0x12345678, 'this one is stdin', ...),
>> (0x87654321, 'this one is stdout', ...),
>> (0x12121212, 'this one is stderr', ...),
>> ],
>> }
>> )
>>
>> # 0-7 bytes of padding here, to reach next 8-byte boundary
>>
>> body = (
>> bytestring b'dir c:\',
>> handle 0, # stdin is the 0'th item in WINDOWS_HANDLES, i.e.
>> 0x12345678
>> handle 1, # stdout is the 1st item
>> handle 2, # stderr is the 2nd item
>> ) # for a total of body_length bytes
>>
>> so that where Unix would have the number of out-of-band fds in the
>> existing UNIX_FDS header field, Windows would instead have the in-band
>> HANDLEs in the WINDOWS_HANDLES header field.
>>
>
>
> Yes, that's an idea I discussed with Thiago:
> > 2) if the 'handle array' is itself embedded in the header fields, the
> header content will need to be updated for each receiver when broadcasting.
> > The second option might not be so bad after all, but my original design
> kept the original message (header+body) untouched.
>
>
>
>> > It seems the D-Bus protocol was designed so that the message size can be
>> > computed from the header alone, with header + body + fields array size.
>> The
>> > reference implementation relies on that
>> (_dbus_header_have_message_untrusted
>> > for ex).
>>
>> Yes, the framing layer of the wire protocol is intended to make it
>> possible
>> to know how long the whole message is going to be by reading its first 16
>> bytes. This should remain true.
>>
>
> Ok
>
> --
> Marc-André Lureau
>
[Attachment #3 (text/html)]
<div dir="ltr"><div dir="auto">Unsubscribed for the god sake.</div><div><br><div \
class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, 5 Aug 2022 at 5:36 pm, \
Marc-André Lureau <<a href="mailto:marcandre.lureau@gmail.com" \
target="_blank">marcandre.lureau@gmail.com</a>> wrote:<br></div><blockquote \
class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc \
solid;padding-left:1ex"><div dir="ltr"><div dir="ltr">Hi<br></div><br><div \
class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Aug 4, 2022 at 11:36 PM \
Simon McVittie <<a href="mailto:smcv@collabora.com" \
target="_blank">smcv@collabora.com</a>> wrote:<br></div><blockquote \
class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid \
rgb(204,204,204);padding-left:1ex">On Wed, 03 Aug 2022 at 14:54:21 +0400, Marc-André \
Lureau wrote:<br> > The array elements have<br>
> the handle type & value or details for SOCKET. The body 'H' \
arguments index the<br> > array, similar to 'h' FDs values.<br>
<br>
Is there a reason why the wire protocol can't use the same 'h' type \
as<br> on Unix? In the wire protocol, the 'h' type is just a special sort \
of<br> integer, with the conventional semantics being that it is an index into an<br>
array of out-of-band file descriptors. Can the Windows equivalent be making<br>
it an index into an array of HANDLEs?<br></blockquote><div><br></div><div>As you \
probably know, HANDLEs are not FD. And Windows has the 2 types, and functions to map \
to/from the 2 (_get_osfhandle/_open_osfhandle).<br></div><div><br></div><div>With the \
addition of AF_UNIX socket support, Windows developers have shown interest in adding \
more features over time (<a \
href="https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/#unsupportedunavailable" \
target="_blank">https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/#unsupportedunavailable</a>), \
including SCM_RIGHTS/fdpass.<br></div><div> </div><div>If some day, Windows has \
SCM_RIGHTS, we should enable that code too. For those reasons, I think we should add \
a new type. If 'H' is not a good character, please \
advise.<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px \
0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> <br>
This would work very well for GDBus, which literally represents the 'h'<br>
type as an integer index into the GUnixFdList, but might be a bit weird<br>
in libdbus, which transparently replaces the integer index with the actual<br>
file descriptor (which of course will usually be numerically unequal to<br>
either the index, or the fd in the sender) while iterating a received<br>
message's arguments, or transparently replaces a fd with an index into<br>
the array of fds to be sent while building a new message to be sent.<br>
HANDLEs are not the same size as int, so the ABI for dealing with handles<br>
would be different on Unix and Windows.<br></blockquote><div><br></div><div>I handled \
that in my dev branch. I introduced a new type to wrap HANDLE or SOCKET (or future \
handle kinds as needed):<br></div><div><br></div><div>/*<br> * Handles which are not \
yet supported:<br> * - Change notification: FindCloseChangeNotification<br> * - \
Event log: CloseEventLog<br> * - Find file: FindClose<br> * - Update resource: \
EndUpdateResource<br> */<br><br>typedef struct DBusWinHandle \
DBusWinHandle;<br><br>struct DBusWinHandle {<br> int type;<br> union {<br> \
SOCKET socket;<br> HANDLE handle;<br> } \
u;<br>};</div><div><br></div><div><br></div><blockquote class="gmail_quote" \
style="margin:0px 0px 0px 0.8ex;border-left:1px solid \
rgb(204,204,204);padding-left:1ex"> <br>
I can see why the authors of fd-passing in libdbus did it this way,<br>
but with hindsight, GDBus' approach is probably \
better.<br></blockquote><div><br></div><div>may be :) in my glib/gio wip branch, I \
re-use the fdlist (mapping HANDLEs to FD). The problem with that approach is that the \
client looses the HANDLE type information, which may be hard to get back (there are \
"bad" & undocumented windows API to do that). I plan to change that, to \
introduce a HANDLE list & API \
instead.<br></div><div><br></div><div><br></div><blockquote class="gmail_quote" \
style="margin:0px 0px 0px 0.8ex;border-left:1px solid \
rgb(204,204,204);padding-left:1ex"> <br>
If the Windows HANDLEs or SOCKETs have to be sent in-band as ordinary<br>
bytes in the message stream, rather than out-of-band as a special<br>
kernel-mediated capability (which seems odd to me, but I'm not a<br>
Windows expert), then they should probably be in a new header field \
of<br></blockquote><div><br></div><div>yes, you have to use \
DuplicateHandle/wsaduplicatesocket and send the handle details to the target, via \
ipc.<br></div></div></div><div dir="ltr"><div class="gmail_quote"><div> \
</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px \
solid rgb(204,204,204);padding-left:1ex"> an appropriate type (perhaps 'at' \
if a bare 64-bit integer is enough,<br> or 'a(t...)' if you need a 64-bit \
integer plus metadata, or something<br> along those lines).<br>
<br>
Something like this (in GVariant-ish pseudocode):<br>
<br>
header = (<br>
byte endianness,<br>
byte message type,<br>
byte flags,<br>
byte major_version,<br>
uint32 body_length,<br>
uint32 serial,<br>
@a(yv) {<br>
PATH: <'/foo'>,<br>
INTERFACE: <'com.example.ArbitraryCodeExecution'>,<br>
MEMBER: <'ExecCommand'>,<br>
...,<br>
WINDOWS_HANDLES: @a(t...) [ # a new header \
field<br> (0x12345678, 'this one is stdin', ...),<br>
(0x87654321, 'this one is stdout', ...),<br>
(0x12121212, 'this one is stderr', ...),<br>
],<br>
}<br>
)<br>
<br>
# 0-7 bytes of padding here, to reach next 8-byte boundary<br>
<br>
body = (<br>
bytestring b'dir c:\',<br>
handle 0, # stdin is the 0'th item in WINDOWS_HANDLES, i.e. \
0x12345678<br> handle 1, # stdout is the 1st item<br>
handle 2, # stderr is the 2nd item<br>
) # for a total of body_length bytes<br>
<br>
so that where Unix would have the number of out-of-band fds in the<br>
existing UNIX_FDS header field, Windows would instead have the in-band<br>
HANDLEs in the WINDOWS_HANDLES header \
field.<br></blockquote><div><br></div><div><br></div></div></div><div dir="ltr"><div \
class="gmail_quote"><div>Yes, that's an idea I discussed with \
Thiago:</div><div>> 2) if the 'handle array' is itself embedded in the \
header fields, the header content will need to be updated for each receiver when \
broadcasting.<br><div>> The second option might not be so bad after all, but my \
original design kept the original message (header+body) untouched.</div></div><div> \
</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px \
0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> <br>
> It seems the D-Bus protocol was designed so that the message size can be<br>
> computed from the header alone, with header + body + fields array size. The<br>
> reference implementation relies on that (_dbus_header_have_message_untrusted<br>
> for ex).<br>
<br>
Yes, the framing layer of the wire protocol is intended to make it possible<br>
to know how long the whole message is going to be by reading its first 16<br>
bytes. This should remain true.<br></blockquote><div><br></div><div>Ok \
<br></div></div></div><div dir="ltr"><br>-- <br><div dir="ltr">Marc-André \
Lureau<br></div></div> </blockquote></div></div>
</div>
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic