Mir

Merge lp:~thomas-voss/mir/fix-fd-sharing into lp:~mir-team/mir/trunk

Proposed by Thomas Voß
Status: Work in progress
Proposed branch: lp:~thomas-voss/mir/fix-fd-sharing
Merge into: lp:~mir-team/mir/trunk
Diff against target: 113 lines (+38/-35)
2 files modified
src/client/rpc/mir_socket_rpc_channel.cpp (+2/-2)
src/server/frontend/socket_messenger.cpp (+36/-33)
To merge this branch: bzr merge lp:~thomas-voss/mir/fix-fd-sharing
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Needs Fixing
Alan Griffiths Needs Fixing
Daniel van Vugt Needs Information
Chris Halse Rogers Approve
Review via email: mp+180801@code.launchpad.net

Commit message

 * Use correct macros to calculate msg length and alignment when sharing fds.
 * Dispatch via io_service to ensure correct ordering.

Description of the change

 * Use correct macros to calculate msg length and alignment when sharing fds.
 * Dispatch via io_service to ensure correct ordering.

To post a comment you must log in.
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

1. Have we observed any problems with "incorrect" ordering? What's being fixed?

2. Please indent the lambda only 4 spaces in from the dispatch line. That should make it more readable.

review: Needs Information
Revision history for this message
Thomas Voß (thomas-voss) wrote :

> 1. Have we observed any problems with "incorrect" ordering? What's being
> fixed?
>

The issue reported in https://bugs.launchpad.net/mir/+bug/1204939 might be triggered by incorrect ordering of operations on the underlying socket.

> 2. Please indent the lambda only 4 spaces in from the dispatch line. That
> should make it more readable.

fixed.

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

Only the first really needs fixing, but while we're looking at this code...

There's corresponding code in MirSocketRpcChannel::receive_file_descriptors() that also uses "sizeof(struct cmsghdr) + sizeof(int) * n_fds" - the fix should be applied uniformly.

~~~~

77 + int i = 0;
78 + for (auto &fd: fds)
79 + data[i++] = fd;

I guess it is pre-existing, but what's wrong with using std::copy?

std::copy(fds.begin(), fds.end(), data);

~~~~

It is inefficiency rather than a bug, but we're copying a std::vector into the lambda simply to make it available as a data source for further copying.

review: Needs Fixing
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

For future safety I would change:
    message->cmsg_len = CMSG_LEN(sizeof(int) * n_fds);
to:
    message->cmsg_len = CMSG_LEN(header.msg_controllen);

But it's not that important.

review: Approve
Revision history for this message
Chris Halse Rogers (raof) wrote :

Looks good to me.

Mostly; the lambda's capturing ‘fds’ by value which IIUC will imply another copy of the vector. Although this does mean that we don't need to care about synchronisation.

review: Approve
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

Enough for now. We can worry about the extra copy *if* we measure a performance problem.

review: Approve
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Is the lambda run in the same thread as the caller?
socket->get_io_service().dispatch(...

If not then it is using fds unsafely unlocked and/or potentially after the object is destroyed.

review: Needs Information
Revision history for this message
Thomas Voß (thomas-voss) wrote :

> Is the lambda run in the same thread as the caller?
> socket->get_io_service().dispatch(...
>

No, that's why the fds are copied into the lambda.

> If not then it is using fds unsafely unlocked and/or potentially after the
> object is destroyed.

It takes a copy of the fds to avoid this issue.

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> > Is the lambda run in the same thread as the caller?
> > socket->get_io_service().dispatch(...
> >
>
> No, that's why the fds are copied into the lambda.
>
> > If not then it is using fds unsafely unlocked and/or potentially after the
> > object is destroyed.
>
> It takes a copy of the fds to avoid this issue.

Actually, there is an issue here.

That doesn't avoid the issue: the lifetime of the FDs is controlled by the resource_cache. E.g. ~GBMPlatformIPCPackage() closes the FD after the caller returns.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)

Unmerged revisions

986. By Thomas Voß

* Use correct macros in the client-side protobuf communicator, too.
* Replace manual for-loop with std::copy.

985. By Thomas Voß

Fix indent as requested in review.

984. By Thomas Voß

 * Use correct macros to calculate msg length and alignment when sharing fds.
 * Dispatch via io_service to ensure correct ordering.

983. By Alexandros Frantzis

shell: Add infrastructure for emitting and handling session related events.

Approved by PS Jenkins bot, Alan Griffiths.

982. By Alan Griffiths

config: use the DisplayServer to hold ownership of system components, not the DefaultServerConfiguration.

Approved by Alexandros Frantzis, Robert Carr, PS Jenkins bot.

981. By Chris Halse Rogers

Add missing mutex around display config call.

Approved by Alexandros Frantzis, PS Jenkins bot, Daniel van Vugt.

980. By Brandon Schaefer

Clean up config->cards when were are deleting the display config.

Approved by Alexandros Frantzis, Chris Halse Rogers, PS Jenkins bot.

979. By Alan Griffiths

tests: Workaround for test timeout under valgrind. Fixes: https://bugs.launchpad.net/bugs/1212518.

Approved by Daniel van Vugt, Alexandros Frantzis, PS Jenkins bot.

978. By Alan Griffiths

graphics::nested: sketch out some more of the nested mir implementation.

Approved by Alexandros Frantzis, PS Jenkins bot.

977. By Alexandros Frantzis

shell: Notify sessions when the display configuration changes

This patchset implements client notifications for display configuration changes. It also adds a mir_demo_client_display_config example which can be used to test and demo client initiated display configuration changes. Use of the example uncovered some issues that are also fixed by this patchset (see individual commits for more info).

Approved by PS Jenkins bot, Alan Griffiths.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/client/rpc/mir_socket_rpc_channel.cpp'
--- src/client/rpc/mir_socket_rpc_channel.cpp 2013-08-08 02:34:31 +0000
+++ src/client/rpc/mir_socket_rpc_channel.cpp 2013-08-19 09:19:06 +0000
@@ -176,7 +176,7 @@
176176
177 // Allocate space for control message177 // Allocate space for control message
178 auto n_fds = fds.size();178 auto n_fds = fds.size();
179 std::vector<char> control(sizeof(struct cmsghdr) + sizeof(int) * n_fds);179 std::vector<char> control(CMSG_SPACE(sizeof(int) * n_fds));
180180
181 // Message to send181 // Message to send
182 struct msghdr header;182 struct msghdr header;
@@ -190,7 +190,7 @@
190190
191 // Control message contains file descriptors191 // Control message contains file descriptors
192 struct cmsghdr *message = CMSG_FIRSTHDR(&header);192 struct cmsghdr *message = CMSG_FIRSTHDR(&header);
193 message->cmsg_len = header.msg_controllen;193 message->cmsg_len = CMSG_LEN(sizeof(int) * n_fds);
194 message->cmsg_level = SOL_SOCKET;194 message->cmsg_level = SOL_SOCKET;
195 message->cmsg_type = SCM_RIGHTS;195 message->cmsg_type = SCM_RIGHTS;
196196
197197
=== modified file 'src/server/frontend/socket_messenger.cpp'
--- src/server/frontend/socket_messenger.cpp 2013-08-01 09:55:02 +0000
+++ src/server/frontend/socket_messenger.cpp 2013-08-19 09:19:06 +0000
@@ -33,9 +33,9 @@
33{33{
34 struct ucred cr;34 struct ucred cr;
35 socklen_t cl = sizeof(cr);35 socklen_t cl = sizeof(cr);
36 36
37 auto status = getsockopt(socket->native_handle(), SOL_SOCKET, SO_PEERCRED, &cr, &cl);37 auto status = getsockopt(socket->native_handle(), SOL_SOCKET, SO_PEERCRED, &cr, &cl);
38 38
39 if (status)39 if (status)
40 BOOST_THROW_EXCEPTION(std::runtime_error("Failed to query client socket credentials"));40 BOOST_THROW_EXCEPTION(std::runtime_error("Failed to query client socket credentials"));
41 return cr.pid;41 return cr.pid;
@@ -65,36 +65,39 @@
65 auto n_fds = fds.size();65 auto n_fds = fds.size();
66 if (n_fds > 0)66 if (n_fds > 0)
67 {67 {
68 // We send dummy data68 socket->get_io_service().dispatch(
69 struct iovec iov;69 [this, fds, n_fds]()
70 char dummy_iov_data = 'M';70 {
71 iov.iov_base = &dummy_iov_data;71 // We send dummy data
72 iov.iov_len = 1;72 struct iovec iov;
7373 char dummy_iov_data = 'M';
74 // Allocate space for control message74 iov.iov_base = &dummy_iov_data;
75 std::vector<char> control(sizeof(struct cmsghdr) + sizeof(int) * n_fds);75 iov.iov_len = 1;
7676
77 // Message to send77 // Allocate space for control message
78 struct msghdr header;78 std::vector<char> control(CMSG_SPACE(sizeof(int) * n_fds));
79 header.msg_name = NULL;79 // Message to send
80 header.msg_namelen = 0;80 struct msghdr header;
81 header.msg_iov = &iov;81 header.msg_name = NULL;
82 header.msg_iovlen = 1;82 header.msg_namelen = 0;
83 header.msg_controllen = control.size();83 header.msg_iov = &iov;
84 header.msg_control = control.data();84 header.msg_iovlen = 1;
85 header.msg_flags = 0;85 header.msg_controllen = control.size();
8686 header.msg_control = control.data();
87 // Control message contains file descriptors87 header.msg_flags = 0;
88 struct cmsghdr *message = CMSG_FIRSTHDR(&header);88
89 message->cmsg_len = header.msg_controllen;89 // Control message contains file descriptors
90 message->cmsg_level = SOL_SOCKET;90 struct cmsghdr *message = CMSG_FIRSTHDR(&header);
91 message->cmsg_type = SCM_RIGHTS;91 message->cmsg_len = CMSG_LEN(sizeof(int) * n_fds);
92 int *data = (int *)CMSG_DATA(message);92 message->cmsg_level = SOL_SOCKET;
93 int i = 0;93 message->cmsg_type = SCM_RIGHTS;
94 for (auto &fd: fds)94 std::copy(
95 data[i++] = fd;95 fds.begin(),
9696 fds.end(),
97 sendmsg(socket->native_handle(), &header, 0);97 reinterpret_cast<int*>(CMSG_DATA(message)));
98
99 sendmsg(socket->native_handle(), &header, 0);
100 });
98 }101 }
99}102}
100103
@@ -106,4 +109,4 @@
106 buffer,109 buffer,
107 boost::asio::transfer_exactly(size),110 boost::asio::transfer_exactly(size),
108 handler);111 handler);
109} 112}

Subscribers

People subscribed via source and target branches