Linux v4.2-rc1-33-gd6ac4ffc61ac
This commit is contained in:
parent
84bb446543
commit
8be443055e
27
Documentation-kdbus-Fix-description-of-KDBUS_SEND_SY.patch
Normal file
27
Documentation-kdbus-Fix-description-of-KDBUS_SEND_SY.patch
Normal file
@ -0,0 +1,27 @@
|
||||
From: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Date: Thu, 9 Apr 2015 13:08:05 +0300
|
||||
Subject: [PATCH] Documentation: kdbus: Fix description of
|
||||
KDBUS_SEND_SYNC_REPLY flag
|
||||
|
||||
Signed-off-by: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Acked-by: Daniel Mack <daniel@zonque.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
Documentation/kdbus/kdbus.message.xml | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/Documentation/kdbus/kdbus.message.xml b/Documentation/kdbus/kdbus.message.xml
|
||||
index 5e7c7a3f537e..90f6596dcc20 100644
|
||||
--- a/Documentation/kdbus/kdbus.message.xml
|
||||
+++ b/Documentation/kdbus/kdbus.message.xml
|
||||
@@ -242,8 +242,8 @@ struct kdbus_cmd_send {
|
||||
</citerefentry>.
|
||||
|
||||
The offset of the reply message in the sender's pool is stored
|
||||
- in in <varname>offset_reply</varname> when the ioctl has
|
||||
- returned without error. Hence, there is no need for another
|
||||
+ in <varname>reply</varname> when the ioctl has returned without
|
||||
+ error. Hence, there is no need for another
|
||||
<constant>KDBUS_CMD_RECV</constant> ioctl or anything else to
|
||||
receive the reply.
|
||||
</para>
|
32
Documentation-kdbus-Fix-list-of-KDBUS_CMD_ENDPOINT_U.patch
Normal file
32
Documentation-kdbus-Fix-list-of-KDBUS_CMD_ENDPOINT_U.patch
Normal file
@ -0,0 +1,32 @@
|
||||
From: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Date: Thu, 9 Apr 2015 13:08:07 +0300
|
||||
Subject: [PATCH] Documentation: kdbus: Fix list of KDBUS_CMD_ENDPOINT_UPDATE
|
||||
errors
|
||||
|
||||
Remove EEXIST.
|
||||
|
||||
Signed-off-by: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Acked-by: Daniel Mack <daniel@zonque.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
Documentation/kdbus/kdbus.endpoint.xml | 7 -------
|
||||
1 file changed, 7 deletions(-)
|
||||
|
||||
diff --git a/Documentation/kdbus/kdbus.endpoint.xml b/Documentation/kdbus/kdbus.endpoint.xml
|
||||
index 76e325d4e931..c36aa9781739 100644
|
||||
--- a/Documentation/kdbus/kdbus.endpoint.xml
|
||||
+++ b/Documentation/kdbus/kdbus.endpoint.xml
|
||||
@@ -369,13 +369,6 @@ struct kdbus_cmd {
|
||||
<constant>KDBUS_ITEM_POLICY_ACCESS</constant> was provided.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
-
|
||||
- <varlistentry>
|
||||
- <term><constant>EEXIST</constant></term>
|
||||
- <listitem><para>
|
||||
- An endpoint of that name already exists.
|
||||
- </para></listitem>
|
||||
- </varlistentry>
|
||||
</variablelist>
|
||||
</refsect2>
|
||||
</refsect1>
|
279
Documentation-kdbus-Fix-typos.patch
Normal file
279
Documentation-kdbus-Fix-typos.patch
Normal file
@ -0,0 +1,279 @@
|
||||
From: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Date: Thu, 9 Apr 2015 13:08:04 +0300
|
||||
Subject: [PATCH] Documentation: kdbus: Fix typos
|
||||
|
||||
Signed-off-by: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Acked-by: Daniel Mack <daniel@zonque.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
Documentation/kdbus/kdbus.bus.xml | 9 ++++-----
|
||||
Documentation/kdbus/kdbus.connection.xml | 10 ++++------
|
||||
Documentation/kdbus/kdbus.endpoint.xml | 2 +-
|
||||
Documentation/kdbus/kdbus.item.xml | 9 ++++-----
|
||||
Documentation/kdbus/kdbus.match.xml | 14 ++++++++------
|
||||
Documentation/kdbus/kdbus.message.xml | 11 +++++------
|
||||
Documentation/kdbus/kdbus.xml | 6 +++---
|
||||
7 files changed, 29 insertions(+), 32 deletions(-)
|
||||
|
||||
diff --git a/Documentation/kdbus/kdbus.bus.xml b/Documentation/kdbus/kdbus.bus.xml
|
||||
index 4d875e59ac02..4b9a0ac1b351 100644
|
||||
--- a/Documentation/kdbus/kdbus.bus.xml
|
||||
+++ b/Documentation/kdbus/kdbus.bus.xml
|
||||
@@ -28,8 +28,7 @@
|
||||
<citerefentry>
|
||||
<refentrytitle>kdbus.message</refentrytitle>
|
||||
<manvolnum>7</manvolnum>
|
||||
- </citerefentry>
|
||||
- ).
|
||||
+ </citerefentry>).
|
||||
Each bus is independent, and operations on the bus will not have any
|
||||
effect on other buses. A bus is a management entity that controls the
|
||||
addresses of its connections, their policies and message transactions
|
||||
@@ -42,7 +41,7 @@
|
||||
<refentrytitle>kdbus.fs</refentrytitle>
|
||||
<manvolnum>7</manvolnum>
|
||||
</citerefentry>
|
||||
- , a bus is presented as a directory. No operations can be performed on
|
||||
+ a bus is presented as a directory. No operations can be performed on
|
||||
the bus itself; instead you need to perform the operations on an endpoint
|
||||
associated with the bus. Endpoints are accessible as files underneath the
|
||||
bus directory. A default endpoint called <constant>bus</constant> is
|
||||
@@ -165,8 +164,8 @@ struct kdbus_cmd {
|
||||
<citerefentry>
|
||||
<refentrytitle>kdbus.item</refentrytitle>
|
||||
<manvolnum>7</manvolnum>
|
||||
- </citerefentry>
|
||||
- ) are expected for <constant>KDBUS_CMD_BUS_MAKE</constant>.
|
||||
+ </citerefentry>)
|
||||
+ are expected for <constant>KDBUS_CMD_BUS_MAKE</constant>.
|
||||
</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
diff --git a/Documentation/kdbus/kdbus.connection.xml b/Documentation/kdbus/kdbus.connection.xml
|
||||
index 09852125b2d4..cefb419f1093 100644
|
||||
--- a/Documentation/kdbus/kdbus.connection.xml
|
||||
+++ b/Documentation/kdbus/kdbus.connection.xml
|
||||
@@ -50,8 +50,7 @@
|
||||
<citerefentry>
|
||||
<refentrytitle>kdbus.match</refentrytitle>
|
||||
<manvolnum>7</manvolnum>
|
||||
- </citerefentry>
|
||||
- ).
|
||||
+ </citerefentry>).
|
||||
</para>
|
||||
<para>
|
||||
Messages synthesized and sent directly by the kernel will carry the
|
||||
@@ -595,13 +594,13 @@ struct kdbus_cmd_info {
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
- <term><varname>flags</varname></term>
|
||||
+ <term><varname>attach_flags</varname></term>
|
||||
<listitem><para>
|
||||
Specifies which metadata items should be attached to the answer. See
|
||||
<citerefentry>
|
||||
<refentrytitle>kdbus.message</refentrytitle>
|
||||
<manvolnum>7</manvolnum>
|
||||
- </citerefentry>
|
||||
+ </citerefentry>.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
@@ -986,8 +985,7 @@ struct kdbus_cmd {
|
||||
<term><varname>items</varname></term>
|
||||
<listitem>
|
||||
<para>
|
||||
- Items to describe the connection details to be updated. The
|
||||
- following item types are supported.
|
||||
+ The following item types are supported.
|
||||
</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
diff --git a/Documentation/kdbus/kdbus.endpoint.xml b/Documentation/kdbus/kdbus.endpoint.xml
|
||||
index c36aa9781739..6632485f3e84 100644
|
||||
--- a/Documentation/kdbus/kdbus.endpoint.xml
|
||||
+++ b/Documentation/kdbus/kdbus.endpoint.xml
|
||||
@@ -201,7 +201,7 @@ struct kdbus_cmd {
|
||||
<para>
|
||||
To update an existing endpoint, the
|
||||
<constant>KDBUS_CMD_ENDPOINT_UPDATE</constant> command is used on the file
|
||||
- descriptor that was used to create the update, using
|
||||
+ descriptor that was used to create the endpoint, using
|
||||
<constant>KDBUS_CMD_ENDPOINT_MAKE</constant>. The only relevant detail of
|
||||
the endpoint that can be updated is the policy. When the command is
|
||||
employed, the policy of the endpoint is <emphasis>replaced</emphasis>
|
||||
diff --git a/Documentation/kdbus/kdbus.item.xml b/Documentation/kdbus/kdbus.item.xml
|
||||
index bfe47362097f..09f8b903116f 100644
|
||||
--- a/Documentation/kdbus/kdbus.item.xml
|
||||
+++ b/Documentation/kdbus/kdbus.item.xml
|
||||
@@ -139,7 +139,7 @@ struct kdbus_item {
|
||||
<term><constant>KDBUS_ITEM_NEGOTIATE</constant></term>
|
||||
<listitem><para>
|
||||
With this item is attached to any ioctl, programs can
|
||||
- <emphasis>probe</emphasis> the kernel for known item items.
|
||||
+ <emphasis>probe</emphasis> the kernel for known item types.
|
||||
The item carries an array of <type>uint64_t</type> values in
|
||||
<varname>item.data64</varname>, each set to an item type to
|
||||
probe. The kernel will reset each member of this array that is
|
||||
@@ -232,7 +232,6 @@ struct kdbus_memfd {
|
||||
When received as item attached to a message, the array will
|
||||
contain the numbers of the installed file descriptors, or
|
||||
<constant>-1</constant> in case an error occurred.
|
||||
- file descriptor.
|
||||
In either case, the number of entries in the array is derived from
|
||||
the item's total size. See
|
||||
<citerefentry>
|
||||
@@ -487,7 +486,7 @@ struct kdbus_pids {
|
||||
a remote peer is a member of, stored as array of
|
||||
<type>uint32_t</type> values in <varname>item.data32</varname>.
|
||||
The array length can be determined by looking at the item's total
|
||||
- size, subtracting the size of the header and and dividing the
|
||||
+ size, subtracting the size of the header and dividing the
|
||||
remainder by <constant>sizeof(uint32_t)</constant>.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
@@ -748,7 +747,7 @@ struct kdbus_notify_name_change {
|
||||
This item is sent as attachment to a
|
||||
<emphasis>kernel notification</emphasis>. It informs the receiver
|
||||
that an expected reply to a message was not received in time.
|
||||
- The remote peer ID and the message cookie is stored in the message
|
||||
+ The remote peer ID and the message cookie are stored in the message
|
||||
header. See
|
||||
<citerefentry>
|
||||
<refentrytitle>kdbus.message</refentrytitle>
|
||||
@@ -765,7 +764,7 @@ struct kdbus_notify_name_change {
|
||||
<emphasis>kernel notification</emphasis>. It informs the receiver
|
||||
that a remote connection a reply is expected from was disconnected
|
||||
before that reply was sent. The remote peer ID and the message
|
||||
- cookie is stored in the message header. See
|
||||
+ cookie are stored in the message header. See
|
||||
<citerefentry>
|
||||
<refentrytitle>kdbus.message</refentrytitle>
|
||||
<manvolnum>7</manvolnum>
|
||||
diff --git a/Documentation/kdbus/kdbus.match.xml b/Documentation/kdbus/kdbus.match.xml
|
||||
index ef77b64e5890..ae38e04ab4d6 100644
|
||||
--- a/Documentation/kdbus/kdbus.match.xml
|
||||
+++ b/Documentation/kdbus/kdbus.match.xml
|
||||
@@ -55,7 +55,7 @@
|
||||
possibly along with some other rules to further limit the match.
|
||||
|
||||
The kernel will match the signal message's bloom filter against the
|
||||
- connections bloom mask (simply by &-ing it), and will decide whether
|
||||
+ connection's bloom mask (simply by &-ing it), and will decide whether
|
||||
the message should be delivered to a connection.
|
||||
</para>
|
||||
<para>
|
||||
@@ -138,9 +138,9 @@
|
||||
<title>Generations</title>
|
||||
|
||||
<para>
|
||||
- Uploaded matches may contain multiple masks, which have are as large as
|
||||
- the bloom size defined by the bus. Each block of a mask is called a
|
||||
- <emphasis>generation</emphasis>, starting at index 0.
|
||||
+ Uploaded matches may contain multiple masks, which have to be as large
|
||||
+ as the bloom filter size defined by the bus. Each block of a mask is
|
||||
+ called a <emphasis>generation</emphasis>, starting at index 0.
|
||||
|
||||
At match time, when a signal is about to be delivered, a bloom mask
|
||||
generation is passed, which denotes which of the bloom masks the filter
|
||||
@@ -171,7 +171,8 @@
|
||||
<title>Adding a match</title>
|
||||
<para>
|
||||
To add a match, the <constant>KDBUS_CMD_MATCH_ADD</constant> ioctl is
|
||||
- used, which takes a struct of the struct described below.
|
||||
+ used, which takes a <type>struct kdbus_cmd_match</type> as an argument
|
||||
+ described below.
|
||||
|
||||
Note that each of the items attached to this command will internally
|
||||
create one match <emphasis>rule</emphasis>, and the collection of them,
|
||||
@@ -266,7 +267,8 @@ struct kdbus_cmd_match {
|
||||
An item that carries the bloom filter mask to match against
|
||||
in its data field. The payload size must match the bloom
|
||||
filter size that was specified when the bus was created.
|
||||
- See the section below for more information on bloom filters.
|
||||
+ See the "Bloom filters" section above for more information on
|
||||
+ bloom filters.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
diff --git a/Documentation/kdbus/kdbus.message.xml b/Documentation/kdbus/kdbus.message.xml
|
||||
index 90f6596dcc20..0115d9d50db3 100644
|
||||
--- a/Documentation/kdbus/kdbus.message.xml
|
||||
+++ b/Documentation/kdbus/kdbus.message.xml
|
||||
@@ -344,8 +344,7 @@ struct kdbus_cmd_send {
|
||||
</variablelist>
|
||||
|
||||
<para>
|
||||
- The fields in this struct are described below.
|
||||
- The message referenced the <varname>msg_address</varname> above has
|
||||
+ The message referenced by the <varname>msg_address</varname> above has
|
||||
the following layout.
|
||||
</para>
|
||||
|
||||
@@ -528,7 +527,7 @@ struct kdbus_msg {
|
||||
<listitem>
|
||||
<para>
|
||||
Actual data records containing the payload. See section
|
||||
- "Passing of Payload Data".
|
||||
+ "Message payload".
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@@ -707,7 +706,7 @@ struct kdbus_cmd_recv {
|
||||
<listitem><para>
|
||||
Whenever a message with <constant>KDBUS_MSG_SIGNAL</constant> is sent
|
||||
but cannot be queued on a peer (e.g., as it contains FDs but the peer
|
||||
- does not support FDs, or there is no space left in the peer's pool..)
|
||||
+ does not support FDs, or there is no space left in the peer's pool)
|
||||
the 'dropped_msgs' counter of the peer is incremented. On the next
|
||||
RECV ioctl, the 'dropped_msgs' field is copied into the ioctl struct
|
||||
and cleared on the peer. If it was non-zero, the
|
||||
@@ -963,7 +962,7 @@ struct kdbus_msg_info {
|
||||
<varlistentry>
|
||||
<term><constant>E2BIG</constant></term>
|
||||
<listitem><para>
|
||||
- Too many items
|
||||
+ Too many items.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
@@ -1172,7 +1171,7 @@ struct kdbus_msg_info {
|
||||
<varlistentry>
|
||||
<term><constant>EAGAIN</constant></term>
|
||||
<listitem><para>
|
||||
- No message found in the queue
|
||||
+ No message found in the queue.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
diff --git a/Documentation/kdbus/kdbus.xml b/Documentation/kdbus/kdbus.xml
|
||||
index 194abd2e76cc..d8e7400df2af 100644
|
||||
--- a/Documentation/kdbus/kdbus.xml
|
||||
+++ b/Documentation/kdbus/kdbus.xml
|
||||
@@ -379,7 +379,7 @@
|
||||
<listitem>
|
||||
<para>
|
||||
When a message is sent (<constant>KDBUS_CMD_SEND</constant>),
|
||||
- information about the sending task and the sending connection are
|
||||
+ information about the sending task and the sending connection is
|
||||
collected. This metadata will be attached to the message when it
|
||||
arrives in the receiver's pool. If the connection sending the
|
||||
message installed faked credentials (see
|
||||
@@ -514,7 +514,7 @@
|
||||
To let the kernel know which metadata information to attach as items
|
||||
to the aforementioned commands, it uses a bitmask. In those, the
|
||||
following <emphasis>attach flags</emphasis> are currently supported.
|
||||
- Both the the <varname>attach_flags_recv</varname> and
|
||||
+ Both the <varname>attach_flags_recv</varname> and
|
||||
<varname>attach_flags_send</varname> fields of
|
||||
<type>struct kdbus_cmd_hello</type>, as well as the payload of the
|
||||
<constant>KDBUS_ITEM_ATTACH_FLAGS_SEND</constant> and
|
||||
@@ -924,7 +924,7 @@
|
||||
|
||||
<para>
|
||||
These ioctls, along with the structs they transport, are explained in
|
||||
- detail in the other documents linked to in the 'see also' section below.
|
||||
+ detail in the other documents linked to in the "See Also" section below.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
31
Documentation-kdbus-Update-list-of-ioctls-which-caus.patch
Normal file
31
Documentation-kdbus-Update-list-of-ioctls-which-caus.patch
Normal file
@ -0,0 +1,31 @@
|
||||
From: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Date: Thu, 9 Apr 2015 13:08:06 +0300
|
||||
Subject: [PATCH] Documentation: kdbus: Update list of ioctls which cause
|
||||
writing to receiver's pool
|
||||
|
||||
Add KDBUS_CMD_BUS_CREATOR_INFO.
|
||||
|
||||
Signed-off-by: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Acked-by: Daniel Mack <daniel@zonque.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
Documentation/kdbus/kdbus.pool.xml | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/Documentation/kdbus/kdbus.pool.xml b/Documentation/kdbus/kdbus.pool.xml
|
||||
index 05fd01902ad4..a9e16f196d39 100644
|
||||
--- a/Documentation/kdbus/kdbus.pool.xml
|
||||
+++ b/Documentation/kdbus/kdbus.pool.xml
|
||||
@@ -66,6 +66,12 @@
|
||||
... to retrieve information on a connection
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
+ <varlistentry>
|
||||
+ <term><constant>KDBUS_CMD_BUS_CREATOR_INFO</constant></term>
|
||||
+ <listitem><para>
|
||||
+ ... to retrieve information about a connection's bus creator
|
||||
+ </para></listitem>
|
||||
+ </varlistentry>
|
||||
</variablelist>
|
||||
|
||||
</para>
|
41
Documentation-kdbus-fix-location-for-generated-files.patch
Normal file
41
Documentation-kdbus-fix-location-for-generated-files.patch
Normal file
@ -0,0 +1,41 @@
|
||||
From: Daniel Mack <daniel@zonque.org>
|
||||
Date: Mon, 9 Mar 2015 18:00:46 +0100
|
||||
Subject: [PATCH] Documentation: kdbus: fix location for generated files
|
||||
|
||||
The generated files should reside in Documentation/kdbus, not in the
|
||||
top-level of the source tree. Also add a .gitignore file and ignore
|
||||
everything that was built from the XML files.
|
||||
|
||||
Signed-off-by: Daniel Mack <daniel@zonque.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
Documentation/kdbus/.gitignore | 2 ++
|
||||
Documentation/kdbus/Makefile | 4 ++--
|
||||
2 files changed, 4 insertions(+), 2 deletions(-)
|
||||
create mode 100644 Documentation/kdbus/.gitignore
|
||||
|
||||
diff --git a/Documentation/kdbus/.gitignore b/Documentation/kdbus/.gitignore
|
||||
new file mode 100644
|
||||
index 000000000000..b4a77ccba9b4
|
||||
--- /dev/null
|
||||
+++ b/Documentation/kdbus/.gitignore
|
||||
@@ -0,0 +1,2 @@
|
||||
+*.7
|
||||
+*.html
|
||||
diff --git a/Documentation/kdbus/Makefile b/Documentation/kdbus/Makefile
|
||||
index cd6b48ee41bf..f6d491251c25 100644
|
||||
--- a/Documentation/kdbus/Makefile
|
||||
+++ b/Documentation/kdbus/Makefile
|
||||
@@ -18,10 +18,10 @@ HTMLFILES := $(patsubst %.xml, %.html, $(XMLFILES))
|
||||
XMLTO_ARGS := -m $(obj)/stylesheet.xsl
|
||||
|
||||
%.7: %.xml
|
||||
- xmlto man $(XMLTO_ARGS) -o . $<
|
||||
+ xmlto man $(XMLTO_ARGS) -o $(obj) $<
|
||||
|
||||
%.html: %.xml
|
||||
- xmlto html-nochunks $(XMLTO_ARGS) -o . $<
|
||||
+ xmlto html-nochunks $(XMLTO_ARGS) -o $(obj) $<
|
||||
|
||||
mandocs: $(MANFILES)
|
||||
|
33
Documentation-kdbus-fix-operator-precedence-issue-in.patch
Normal file
33
Documentation-kdbus-fix-operator-precedence-issue-in.patch
Normal file
@ -0,0 +1,33 @@
|
||||
From: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Date: Wed, 10 Jun 2015 00:00:01 +0300
|
||||
Subject: [PATCH] Documentation/kdbus: fix operator precedence issue in
|
||||
KDBUS_ITEM_NEXT macro
|
||||
|
||||
`item' argument in KDBUS_ITEM_NEXT macro example is not enclosed into
|
||||
parentheses when the cast operator is applied, which leads to improper
|
||||
type conversion if `item' is supplied as a complex expression, e.g.
|
||||
|
||||
KDBUS_ITEM_NEXT(condition ? a : b)
|
||||
|
||||
Use parentheses properly to guarantee right precedence.
|
||||
|
||||
Signed-off-by: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
Documentation/kdbus/kdbus.item.xml | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Documentation/kdbus/kdbus.item.xml b/Documentation/kdbus/kdbus.item.xml
|
||||
index 09f8b903116f..b0eeeef995af 100644
|
||||
--- a/Documentation/kdbus/kdbus.item.xml
|
||||
+++ b/Documentation/kdbus/kdbus.item.xml
|
||||
@@ -69,7 +69,7 @@
|
||||
#define KDBUS_ALIGN8(val) (((val) + 7) & ~7)
|
||||
|
||||
#define KDBUS_ITEM_NEXT(item) \
|
||||
- (typeof(item))(((uint8_t *)item) + KDBUS_ALIGN8((item)->size))
|
||||
+ (typeof(item))((uint8_t *)(item) + KDBUS_ALIGN8((item)->size))
|
||||
|
||||
#define KDBUS_ITEM_FOREACH(item, head, first) \
|
||||
for (item = (head)->first; \
|
27
Documentation-kdbus-fix-out-of-tree-builds.patch
Normal file
27
Documentation-kdbus-fix-out-of-tree-builds.patch
Normal file
@ -0,0 +1,27 @@
|
||||
From: David Herrmann <dh.herrmann@gmail.com>
|
||||
Date: Mon, 16 Mar 2015 10:17:11 +0100
|
||||
Subject: [PATCH] Documentation/kdbus: fix out-of-tree builds
|
||||
|
||||
Don't use $(obj) to access source files, but use $(srctree)/$(src)/
|
||||
instead. This fixes build issues if you use O= with a directory other than
|
||||
the source directory.
|
||||
|
||||
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
Documentation/kdbus/Makefile | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Documentation/kdbus/Makefile b/Documentation/kdbus/Makefile
|
||||
index f6d491251c25..d8e6bf37d53b 100644
|
||||
--- a/Documentation/kdbus/Makefile
|
||||
+++ b/Documentation/kdbus/Makefile
|
||||
@@ -15,7 +15,7 @@ XMLFILES := $(addprefix $(obj)/,$(DOCS))
|
||||
MANFILES := $(patsubst %.xml, %.7, $(XMLFILES))
|
||||
HTMLFILES := $(patsubst %.xml, %.html, $(XMLFILES))
|
||||
|
||||
-XMLTO_ARGS := -m $(obj)/stylesheet.xsl
|
||||
+XMLTO_ARGS := -m $(srctree)/$(src)/stylesheet.xsl
|
||||
|
||||
%.7: %.xml
|
||||
xmlto man $(XMLTO_ARGS) -o $(obj) $<
|
28
Documentation-kdbus-replace-reply_cookie-with-cookie.patch
Normal file
28
Documentation-kdbus-replace-reply_cookie-with-cookie.patch
Normal file
@ -0,0 +1,28 @@
|
||||
From: Lukasz Skalski <l.skalski@samsung.com>
|
||||
Date: Mon, 16 Mar 2015 10:35:08 +0100
|
||||
Subject: [PATCH] Documentation/kdbus: replace 'reply_cookie' with
|
||||
'cookie_reply'
|
||||
|
||||
The member field is called 'cookie_reply', fix the documentation which
|
||||
incorrectly used 'reply_cookie'.
|
||||
|
||||
Signed-off-by: Lukasz Skalski <l.skalski@samsung.com>
|
||||
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
Documentation/kdbus/kdbus.message.xml | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Documentation/kdbus/kdbus.message.xml b/Documentation/kdbus/kdbus.message.xml
|
||||
index c25000dcfbc7..5e7c7a3f537e 100644
|
||||
--- a/Documentation/kdbus/kdbus.message.xml
|
||||
+++ b/Documentation/kdbus/kdbus.message.xml
|
||||
@@ -393,7 +393,7 @@ struct kdbus_msg {
|
||||
For a message to be accepted as reply, it must be a direct
|
||||
message to the original sender (not a broadcast and not a
|
||||
signal message), and its
|
||||
- <varname>kdbus_msg.reply_cookie</varname> must match the
|
||||
+ <varname>kdbus_msg.cookie_reply</varname> must match the
|
||||
previous message's <varname>kdbus_msg.cookie</varname>.
|
||||
</para><para>
|
||||
Expected replies also temporarily open the policy of the
|
44
Documentation-kdbus-support-quiet-builds.patch
Normal file
44
Documentation-kdbus-support-quiet-builds.patch
Normal file
@ -0,0 +1,44 @@
|
||||
From: David Herrmann <dh.herrmann@gmail.com>
|
||||
Date: Mon, 16 Mar 2015 10:17:12 +0100
|
||||
Subject: [PATCH] Documentation/kdbus: support quiet builds
|
||||
|
||||
Add support for quiet builds, just like Documentation/DocBook/Makefile
|
||||
supports.
|
||||
|
||||
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
Documentation/kdbus/Makefile | 16 +++++++++++++---
|
||||
1 file changed, 13 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/Documentation/kdbus/Makefile b/Documentation/kdbus/Makefile
|
||||
index d8e6bf37d53b..af87641db416 100644
|
||||
--- a/Documentation/kdbus/Makefile
|
||||
+++ b/Documentation/kdbus/Makefile
|
||||
@@ -15,13 +15,23 @@ XMLFILES := $(addprefix $(obj)/,$(DOCS))
|
||||
MANFILES := $(patsubst %.xml, %.7, $(XMLFILES))
|
||||
HTMLFILES := $(patsubst %.xml, %.html, $(XMLFILES))
|
||||
|
||||
-XMLTO_ARGS := -m $(srctree)/$(src)/stylesheet.xsl
|
||||
+XMLTO_ARGS := -m $(srctree)/$(src)/stylesheet.xsl --skip-validation
|
||||
|
||||
+quiet_cmd_db2man = MAN $@
|
||||
+ cmd_db2man = xmlto man $(XMLTO_ARGS) -o $(obj) $<
|
||||
%.7: %.xml
|
||||
- xmlto man $(XMLTO_ARGS) -o $(obj) $<
|
||||
+ @(which xmlto > /dev/null 2>&1) || \
|
||||
+ (echo "*** You need to install xmlto ***"; \
|
||||
+ exit 1)
|
||||
+ $(call cmd,db2man)
|
||||
|
||||
+quiet_cmd_db2html = HTML $@
|
||||
+ cmd_db2html = xmlto html-nochunks $(XMLTO_ARGS) -o $(obj) $<
|
||||
%.html: %.xml
|
||||
- xmlto html-nochunks $(XMLTO_ARGS) -o $(obj) $<
|
||||
+ @(which xmlto > /dev/null 2>&1) || \
|
||||
+ (echo "*** You need to install xmlto ***"; \
|
||||
+ exit 1)
|
||||
+ $(call cmd,db2html)
|
||||
|
||||
mandocs: $(MANFILES)
|
||||
|
32
Documentation-kdbus-use-parentheses-uniformly-in-KDB.patch
Normal file
32
Documentation-kdbus-use-parentheses-uniformly-in-KDB.patch
Normal file
@ -0,0 +1,32 @@
|
||||
From: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Date: Wed, 10 Jun 2015 00:00:02 +0300
|
||||
Subject: [PATCH] Documentation/kdbus: use parentheses uniformly in
|
||||
KDBUS_ITEM_FOREACH macro
|
||||
|
||||
Enclose all arguments into parentheses to stay consistent across the
|
||||
whole macro.
|
||||
|
||||
Signed-off-by: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
Documentation/kdbus/kdbus.item.xml | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/Documentation/kdbus/kdbus.item.xml b/Documentation/kdbus/kdbus.item.xml
|
||||
index b0eeeef995af..ee09dfa443b8 100644
|
||||
--- a/Documentation/kdbus/kdbus.item.xml
|
||||
+++ b/Documentation/kdbus/kdbus.item.xml
|
||||
@@ -72,10 +72,10 @@
|
||||
(typeof(item))((uint8_t *)(item) + KDBUS_ALIGN8((item)->size))
|
||||
|
||||
#define KDBUS_ITEM_FOREACH(item, head, first) \
|
||||
- for (item = (head)->first; \
|
||||
+ for ((item) = (head)->first; \
|
||||
((uint8_t *)(item) < (uint8_t *)(head) + (head)->size) && \
|
||||
((uint8_t *)(item) >= (uint8_t *)(head)); \
|
||||
- item = KDBUS_ITEM_NEXT(item))
|
||||
+ (item) = KDBUS_ITEM_NEXT(item))
|
||||
]]></programlisting>
|
||||
</refsect2>
|
||||
</refsect1>
|
@ -67,6 +67,7 @@ CONFIG_NET_NS=y
|
||||
CONFIG_USER_NS=y
|
||||
|
||||
CONFIG_POSIX_MQUEUE=y
|
||||
CONFIG_KDBUS=m
|
||||
# CONFIG_PREEMPT_NONE is not set
|
||||
CONFIG_PREEMPT_VOLUNTARY=y
|
||||
# CONFIG_PREEMPT is not set
|
||||
|
35
kdbus-Fix-CONFIG_KDBUS-help-text.patch
Normal file
35
kdbus-Fix-CONFIG_KDBUS-help-text.patch
Normal file
@ -0,0 +1,35 @@
|
||||
From: Daniel Mack <daniel@zonque.org>
|
||||
Date: Tue, 24 Mar 2015 19:51:55 +0100
|
||||
Subject: [PATCH] kdbus: Fix CONFIG_KDBUS help text
|
||||
|
||||
Drop a left-over from the times when documentation lived in a
|
||||
simple text file, which is no longer the case. Mention the
|
||||
auto-generated man-pages and HTML files instead.
|
||||
|
||||
Reported-by: Jiri Slaby <jslaby@suse.cz>
|
||||
Signed-off-by: Daniel Mack <daniel@zonque.org>
|
||||
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
init/Kconfig | 7 ++++---
|
||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/init/Kconfig b/init/Kconfig
|
||||
index 02735f91836e..c4075075295d 100644
|
||||
--- a/init/Kconfig
|
||||
+++ b/init/Kconfig
|
||||
@@ -268,10 +268,11 @@ config KDBUS
|
||||
D-Bus is a system for low-latency, low-overhead, easy to use
|
||||
interprocess communication (IPC).
|
||||
|
||||
- See Documentation/kdbus.txt
|
||||
+ See the man-pages and HTML files in Documentation/kdbus/
|
||||
+ that are generated by 'make mandocs' and 'make htmldocs'.
|
||||
|
||||
- To compile this driver as a module, choose M here: the
|
||||
- module will be called kdbus.
|
||||
+ If you have an ordinary machine, select M here. The module
|
||||
+ will be called kdbus.
|
||||
|
||||
config CROSS_MEMORY_ATTACH
|
||||
bool "Enable process_vm_readv/writev syscalls"
|
106
kdbus-add-Makefile-Kconfig-and-MAINTAINERS-entry.patch
Normal file
106
kdbus-add-Makefile-Kconfig-and-MAINTAINERS-entry.patch
Normal file
@ -0,0 +1,106 @@
|
||||
From: Daniel Mack <daniel@zonque.org>
|
||||
Date: Thu, 11 Sep 2014 18:48:06 +0200
|
||||
Subject: [PATCH] kdbus: add Makefile, Kconfig and MAINTAINERS entry
|
||||
|
||||
This patch hooks up the build system to actually compile the files
|
||||
added by previous patches. It also adds an entry to MAINTAINERS to
|
||||
direct people to Greg KH, David Herrmann, Djalal Harouni and me for
|
||||
questions and patches.
|
||||
|
||||
Signed-off-by: Daniel Mack <daniel@zonque.org>
|
||||
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Signed-off-by: Djalal Harouni <tixxdz@opendz.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
MAINTAINERS | 13 +++++++++++++
|
||||
init/Kconfig | 12 ++++++++++++
|
||||
ipc/Makefile | 2 +-
|
||||
ipc/kdbus/Makefile | 22 ++++++++++++++++++++++
|
||||
4 files changed, 48 insertions(+), 1 deletion(-)
|
||||
create mode 100644 ipc/kdbus/Makefile
|
||||
|
||||
diff --git a/MAINTAINERS b/MAINTAINERS
|
||||
index 8133cefb6b6e..11a76301dde3 100644
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -5780,6 +5780,19 @@ S: Maintained
|
||||
F: Documentation/kbuild/kconfig-language.txt
|
||||
F: scripts/kconfig/
|
||||
|
||||
+KDBUS
|
||||
+M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
+M: Daniel Mack <daniel@zonque.org>
|
||||
+M: David Herrmann <dh.herrmann@googlemail.com>
|
||||
+M: Djalal Harouni <tixxdz@opendz.org>
|
||||
+L: linux-kernel@vger.kernel.org
|
||||
+S: Maintained
|
||||
+F: ipc/kdbus/*
|
||||
+F: samples/kdbus/*
|
||||
+F: Documentation/kdbus/*
|
||||
+F: include/uapi/linux/kdbus.h
|
||||
+F: tools/testing/selftests/kdbus/
|
||||
+
|
||||
KDUMP
|
||||
M: Vivek Goyal <vgoyal@redhat.com>
|
||||
M: Haren Myneni <hbabu@us.ibm.com>
|
||||
diff --git a/init/Kconfig b/init/Kconfig
|
||||
index 860ca236975f..02735f91836e 100644
|
||||
--- a/init/Kconfig
|
||||
+++ b/init/Kconfig
|
||||
@@ -261,6 +261,18 @@ config POSIX_MQUEUE_SYSCTL
|
||||
depends on SYSCTL
|
||||
default y
|
||||
|
||||
+config KDBUS
|
||||
+ tristate "kdbus interprocess communication"
|
||||
+ depends on TMPFS
|
||||
+ help
|
||||
+ D-Bus is a system for low-latency, low-overhead, easy to use
|
||||
+ interprocess communication (IPC).
|
||||
+
|
||||
+ See Documentation/kdbus.txt
|
||||
+
|
||||
+ To compile this driver as a module, choose M here: the
|
||||
+ module will be called kdbus.
|
||||
+
|
||||
config CROSS_MEMORY_ATTACH
|
||||
bool "Enable process_vm_readv/writev syscalls"
|
||||
depends on MMU
|
||||
diff --git a/ipc/Makefile b/ipc/Makefile
|
||||
index 86c7300ecdf5..68ec4167d11b 100644
|
||||
--- a/ipc/Makefile
|
||||
+++ b/ipc/Makefile
|
||||
@@ -9,4 +9,4 @@ obj_mq-$(CONFIG_COMPAT) += compat_mq.o
|
||||
obj-$(CONFIG_POSIX_MQUEUE) += mqueue.o msgutil.o $(obj_mq-y)
|
||||
obj-$(CONFIG_IPC_NS) += namespace.o
|
||||
obj-$(CONFIG_POSIX_MQUEUE_SYSCTL) += mq_sysctl.o
|
||||
-
|
||||
+obj-$(CONFIG_KDBUS) += kdbus/
|
||||
diff --git a/ipc/kdbus/Makefile b/ipc/kdbus/Makefile
|
||||
new file mode 100644
|
||||
index 000000000000..7ee9271e1449
|
||||
--- /dev/null
|
||||
+++ b/ipc/kdbus/Makefile
|
||||
@@ -0,0 +1,22 @@
|
||||
+kdbus-y := \
|
||||
+ bus.o \
|
||||
+ connection.o \
|
||||
+ endpoint.o \
|
||||
+ fs.o \
|
||||
+ handle.o \
|
||||
+ item.o \
|
||||
+ main.o \
|
||||
+ match.o \
|
||||
+ message.o \
|
||||
+ metadata.o \
|
||||
+ names.o \
|
||||
+ node.o \
|
||||
+ notify.o \
|
||||
+ domain.o \
|
||||
+ policy.o \
|
||||
+ pool.o \
|
||||
+ reply.o \
|
||||
+ queue.o \
|
||||
+ util.o
|
||||
+
|
||||
+obj-$(CONFIG_KDBUS) += kdbus.o
|
1466
kdbus-add-code-for-buses-domains-and-endpoints.patch
Normal file
1466
kdbus-add-code-for-buses-domains-and-endpoints.patch
Normal file
File diff suppressed because it is too large
Load Diff
929
kdbus-add-code-for-notifications-and-matches.patch
Normal file
929
kdbus-add-code-for-notifications-and-matches.patch
Normal file
@ -0,0 +1,929 @@
|
||||
From: Daniel Mack <daniel@zonque.org>
|
||||
Date: Thu, 11 Sep 2014 18:59:16 +0200
|
||||
Subject: [PATCH] kdbus: add code for notifications and matches
|
||||
|
||||
This patch adds code for matches and notifications.
|
||||
|
||||
Notifications are broadcast messages generated by the kernel, which
|
||||
notify subscribes when connections are created or destroyed, when
|
||||
well-known-names have been claimed, released or changed ownership,
|
||||
or when reply messages have timed out.
|
||||
|
||||
Matches are used to tell the kernel driver which broadcast messages
|
||||
a connection is interested in. Matches can either be specific on one
|
||||
of the kernel-generated notification types, or carry a bloom filter
|
||||
mask to match against a message from userspace. The latter is a way
|
||||
to pre-filter messages from other connections in order to mitigate
|
||||
unnecessary wakeups.
|
||||
|
||||
Signed-off-by: Daniel Mack <daniel@zonque.org>
|
||||
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Signed-off-by: Djalal Harouni <tixxdz@opendz.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
ipc/kdbus/match.c | 559 +++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
ipc/kdbus/match.h | 35 ++++
|
||||
ipc/kdbus/notify.c | 248 ++++++++++++++++++++++++
|
||||
ipc/kdbus/notify.h | 30 +++
|
||||
4 files changed, 872 insertions(+)
|
||||
create mode 100644 ipc/kdbus/match.c
|
||||
create mode 100644 ipc/kdbus/match.h
|
||||
create mode 100644 ipc/kdbus/notify.c
|
||||
create mode 100644 ipc/kdbus/notify.h
|
||||
|
||||
diff --git a/ipc/kdbus/match.c b/ipc/kdbus/match.c
|
||||
new file mode 100644
|
||||
index 000000000000..30cec1ca819f
|
||||
--- /dev/null
|
||||
+++ b/ipc/kdbus/match.c
|
||||
@@ -0,0 +1,559 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2013-2015 Kay Sievers
|
||||
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
|
||||
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
|
||||
+ * Copyright (C) 2013-2015 Linux Foundation
|
||||
+ * Copyright (C) 2014-2015 Djalal Harouni <tixxdz@opendz.org>
|
||||
+ *
|
||||
+ * kdbus is free software; you can redistribute it and/or modify it under
|
||||
+ * the terms of the GNU Lesser General Public License as published by the
|
||||
+ * Free Software Foundation; either version 2.1 of the License, or (at
|
||||
+ * your option) any later version.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/fs.h>
|
||||
+#include <linux/hash.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/mutex.h>
|
||||
+#include <linux/sched.h>
|
||||
+#include <linux/sizes.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/uaccess.h>
|
||||
+
|
||||
+#include "bus.h"
|
||||
+#include "connection.h"
|
||||
+#include "endpoint.h"
|
||||
+#include "handle.h"
|
||||
+#include "item.h"
|
||||
+#include "match.h"
|
||||
+#include "message.h"
|
||||
+#include "names.h"
|
||||
+
|
||||
+/**
|
||||
+ * struct kdbus_match_db - message filters
|
||||
+ * @entries_list: List of matches
|
||||
+ * @mdb_rwlock: Match data lock
|
||||
+ * @entries_count: Number of entries in database
|
||||
+ */
|
||||
+struct kdbus_match_db {
|
||||
+ struct list_head entries_list;
|
||||
+ struct rw_semaphore mdb_rwlock;
|
||||
+ unsigned int entries_count;
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct kdbus_match_entry - a match database entry
|
||||
+ * @cookie: User-supplied cookie to lookup the entry
|
||||
+ * @list_entry: The list entry element for the db list
|
||||
+ * @rules_list: The list head for tracking rules of this entry
|
||||
+ */
|
||||
+struct kdbus_match_entry {
|
||||
+ u64 cookie;
|
||||
+ struct list_head list_entry;
|
||||
+ struct list_head rules_list;
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct kdbus_bloom_mask - mask to match against filter
|
||||
+ * @generations: Number of generations carried
|
||||
+ * @data: Array of bloom bit fields
|
||||
+ */
|
||||
+struct kdbus_bloom_mask {
|
||||
+ u64 generations;
|
||||
+ u64 *data;
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct kdbus_match_rule - a rule appended to a match entry
|
||||
+ * @type: An item type to match agains
|
||||
+ * @bloom_mask: Bloom mask to match a message's filter against, used
|
||||
+ * with KDBUS_ITEM_BLOOM_MASK
|
||||
+ * @name: Name to match against, used with KDBUS_ITEM_NAME,
|
||||
+ * KDBUS_ITEM_NAME_{ADD,REMOVE,CHANGE}
|
||||
+ * @old_id: ID to match against, used with
|
||||
+ * KDBUS_ITEM_NAME_{ADD,REMOVE,CHANGE},
|
||||
+ * KDBUS_ITEM_ID_REMOVE
|
||||
+ * @new_id: ID to match against, used with
|
||||
+ * KDBUS_ITEM_NAME_{ADD,REMOVE,CHANGE},
|
||||
+ * KDBUS_ITEM_ID_REMOVE
|
||||
+ * @src_id: ID to match against, used with KDBUS_ITEM_ID
|
||||
+ * @rules_entry: Entry in the entry's rules list
|
||||
+ */
|
||||
+struct kdbus_match_rule {
|
||||
+ u64 type;
|
||||
+ union {
|
||||
+ struct kdbus_bloom_mask bloom_mask;
|
||||
+ struct {
|
||||
+ char *name;
|
||||
+ u64 old_id;
|
||||
+ u64 new_id;
|
||||
+ };
|
||||
+ u64 src_id;
|
||||
+ };
|
||||
+ struct list_head rules_entry;
|
||||
+};
|
||||
+
|
||||
+static void kdbus_match_rule_free(struct kdbus_match_rule *rule)
|
||||
+{
|
||||
+ if (!rule)
|
||||
+ return;
|
||||
+
|
||||
+ switch (rule->type) {
|
||||
+ case KDBUS_ITEM_BLOOM_MASK:
|
||||
+ kfree(rule->bloom_mask.data);
|
||||
+ break;
|
||||
+
|
||||
+ case KDBUS_ITEM_NAME:
|
||||
+ case KDBUS_ITEM_NAME_ADD:
|
||||
+ case KDBUS_ITEM_NAME_REMOVE:
|
||||
+ case KDBUS_ITEM_NAME_CHANGE:
|
||||
+ kfree(rule->name);
|
||||
+ break;
|
||||
+
|
||||
+ case KDBUS_ITEM_ID:
|
||||
+ case KDBUS_ITEM_ID_ADD:
|
||||
+ case KDBUS_ITEM_ID_REMOVE:
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ BUG();
|
||||
+ }
|
||||
+
|
||||
+ list_del(&rule->rules_entry);
|
||||
+ kfree(rule);
|
||||
+}
|
||||
+
|
||||
+static void kdbus_match_entry_free(struct kdbus_match_entry *entry)
|
||||
+{
|
||||
+ struct kdbus_match_rule *r, *tmp;
|
||||
+
|
||||
+ if (!entry)
|
||||
+ return;
|
||||
+
|
||||
+ list_for_each_entry_safe(r, tmp, &entry->rules_list, rules_entry)
|
||||
+ kdbus_match_rule_free(r);
|
||||
+
|
||||
+ list_del(&entry->list_entry);
|
||||
+ kfree(entry);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_match_db_free() - free match db resources
|
||||
+ * @mdb: The match database
|
||||
+ */
|
||||
+void kdbus_match_db_free(struct kdbus_match_db *mdb)
|
||||
+{
|
||||
+ struct kdbus_match_entry *entry, *tmp;
|
||||
+
|
||||
+ if (!mdb)
|
||||
+ return;
|
||||
+
|
||||
+ list_for_each_entry_safe(entry, tmp, &mdb->entries_list, list_entry)
|
||||
+ kdbus_match_entry_free(entry);
|
||||
+
|
||||
+ kfree(mdb);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_match_db_new() - create a new match database
|
||||
+ *
|
||||
+ * Return: a new kdbus_match_db on success, ERR_PTR on failure.
|
||||
+ */
|
||||
+struct kdbus_match_db *kdbus_match_db_new(void)
|
||||
+{
|
||||
+ struct kdbus_match_db *d;
|
||||
+
|
||||
+ d = kzalloc(sizeof(*d), GFP_KERNEL);
|
||||
+ if (!d)
|
||||
+ return ERR_PTR(-ENOMEM);
|
||||
+
|
||||
+ init_rwsem(&d->mdb_rwlock);
|
||||
+ INIT_LIST_HEAD(&d->entries_list);
|
||||
+
|
||||
+ return d;
|
||||
+}
|
||||
+
|
||||
+static bool kdbus_match_bloom(const struct kdbus_bloom_filter *filter,
|
||||
+ const struct kdbus_bloom_mask *mask,
|
||||
+ const struct kdbus_conn *conn)
|
||||
+{
|
||||
+ size_t n = conn->ep->bus->bloom.size / sizeof(u64);
|
||||
+ const u64 *m;
|
||||
+ size_t i;
|
||||
+
|
||||
+ /*
|
||||
+ * The message's filter carries a generation identifier, the
|
||||
+ * match's mask possibly carries an array of multiple generations
|
||||
+ * of the mask. Select the mask with the closest match of the
|
||||
+ * filter's generation.
|
||||
+ */
|
||||
+ m = mask->data + (min(filter->generation, mask->generations - 1) * n);
|
||||
+
|
||||
+ /*
|
||||
+ * The message's filter contains the messages properties,
|
||||
+ * the match's mask contains the properties to look for in the
|
||||
+ * message. Check the mask bit field against the filter bit field,
|
||||
+ * if the message possibly carries the properties the connection
|
||||
+ * has subscribed to.
|
||||
+ */
|
||||
+ for (i = 0; i < n; i++)
|
||||
+ if ((filter->data[i] & m[i]) != m[i])
|
||||
+ return false;
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+static bool kdbus_match_rules(const struct kdbus_match_entry *entry,
|
||||
+ struct kdbus_conn *conn_src,
|
||||
+ struct kdbus_kmsg *kmsg)
|
||||
+{
|
||||
+ struct kdbus_match_rule *r;
|
||||
+
|
||||
+ if (conn_src)
|
||||
+ lockdep_assert_held(&conn_src->ep->bus->name_registry->rwlock);
|
||||
+
|
||||
+ /*
|
||||
+ * Walk all the rules and bail out immediately
|
||||
+ * if any of them is unsatisfied.
|
||||
+ */
|
||||
+
|
||||
+ list_for_each_entry(r, &entry->rules_list, rules_entry) {
|
||||
+ if (conn_src) {
|
||||
+ /* messages from userspace */
|
||||
+
|
||||
+ switch (r->type) {
|
||||
+ case KDBUS_ITEM_BLOOM_MASK:
|
||||
+ if (!kdbus_match_bloom(kmsg->bloom_filter,
|
||||
+ &r->bloom_mask,
|
||||
+ conn_src))
|
||||
+ return false;
|
||||
+ break;
|
||||
+
|
||||
+ case KDBUS_ITEM_ID:
|
||||
+ if (r->src_id != conn_src->id &&
|
||||
+ r->src_id != KDBUS_MATCH_ID_ANY)
|
||||
+ return false;
|
||||
+
|
||||
+ break;
|
||||
+
|
||||
+ case KDBUS_ITEM_NAME:
|
||||
+ if (!kdbus_conn_has_name(conn_src, r->name))
|
||||
+ return false;
|
||||
+
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ return false;
|
||||
+ }
|
||||
+ } else {
|
||||
+ /* kernel notifications */
|
||||
+
|
||||
+ if (kmsg->notify_type != r->type)
|
||||
+ return false;
|
||||
+
|
||||
+ switch (r->type) {
|
||||
+ case KDBUS_ITEM_ID_ADD:
|
||||
+ if (r->new_id != KDBUS_MATCH_ID_ANY &&
|
||||
+ r->new_id != kmsg->notify_new_id)
|
||||
+ return false;
|
||||
+
|
||||
+ break;
|
||||
+
|
||||
+ case KDBUS_ITEM_ID_REMOVE:
|
||||
+ if (r->old_id != KDBUS_MATCH_ID_ANY &&
|
||||
+ r->old_id != kmsg->notify_old_id)
|
||||
+ return false;
|
||||
+
|
||||
+ break;
|
||||
+
|
||||
+ case KDBUS_ITEM_NAME_ADD:
|
||||
+ case KDBUS_ITEM_NAME_CHANGE:
|
||||
+ case KDBUS_ITEM_NAME_REMOVE:
|
||||
+ if ((r->old_id != KDBUS_MATCH_ID_ANY &&
|
||||
+ r->old_id != kmsg->notify_old_id) ||
|
||||
+ (r->new_id != KDBUS_MATCH_ID_ANY &&
|
||||
+ r->new_id != kmsg->notify_new_id) ||
|
||||
+ (r->name && kmsg->notify_name &&
|
||||
+ strcmp(r->name, kmsg->notify_name) != 0))
|
||||
+ return false;
|
||||
+
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_match_db_match_kmsg() - match a kmsg object agains the database entries
|
||||
+ * @mdb: The match database
|
||||
+ * @conn_src: The connection object originating the message
|
||||
+ * @kmsg: The kmsg to perform the match on
|
||||
+ *
|
||||
+ * This function will walk through all the database entries previously uploaded
|
||||
+ * with kdbus_match_db_add(). As soon as any of them has an all-satisfied rule
|
||||
+ * set, this function will return true.
|
||||
+ *
|
||||
+ * The caller must hold the registry lock of conn_src->ep->bus, in case conn_src
|
||||
+ * is non-NULL.
|
||||
+ *
|
||||
+ * Return: true if there was a matching database entry, false otherwise.
|
||||
+ */
|
||||
+bool kdbus_match_db_match_kmsg(struct kdbus_match_db *mdb,
|
||||
+ struct kdbus_conn *conn_src,
|
||||
+ struct kdbus_kmsg *kmsg)
|
||||
+{
|
||||
+ struct kdbus_match_entry *entry;
|
||||
+ bool matched = false;
|
||||
+
|
||||
+ down_read(&mdb->mdb_rwlock);
|
||||
+ list_for_each_entry(entry, &mdb->entries_list, list_entry) {
|
||||
+ matched = kdbus_match_rules(entry, conn_src, kmsg);
|
||||
+ if (matched)
|
||||
+ break;
|
||||
+ }
|
||||
+ up_read(&mdb->mdb_rwlock);
|
||||
+
|
||||
+ return matched;
|
||||
+}
|
||||
+
|
||||
+static int kdbus_match_db_remove_unlocked(struct kdbus_match_db *mdb,
|
||||
+ u64 cookie)
|
||||
+{
|
||||
+ struct kdbus_match_entry *entry, *tmp;
|
||||
+ bool found = false;
|
||||
+
|
||||
+ list_for_each_entry_safe(entry, tmp, &mdb->entries_list, list_entry)
|
||||
+ if (entry->cookie == cookie) {
|
||||
+ kdbus_match_entry_free(entry);
|
||||
+ --mdb->entries_count;
|
||||
+ found = true;
|
||||
+ }
|
||||
+
|
||||
+ return found ? 0 : -EBADSLT;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_cmd_match_add() - handle KDBUS_CMD_MATCH_ADD
|
||||
+ * @conn: connection to operate on
|
||||
+ * @argp: command payload
|
||||
+ *
|
||||
+ * One call to this function (or one ioctl(KDBUS_CMD_MATCH_ADD), respectively,
|
||||
+ * adds one new database entry with n rules attached to it. Each rule is
|
||||
+ * described with an kdbus_item, and an entry is considered matching if all
|
||||
+ * its rules are satisfied.
|
||||
+ *
|
||||
+ * The items attached to a kdbus_cmd_match struct have the following mapping:
|
||||
+ *
|
||||
+ * KDBUS_ITEM_BLOOM_MASK: A bloom mask
|
||||
+ * KDBUS_ITEM_NAME: A connection's source name
|
||||
+ * KDBUS_ITEM_ID: A connection ID
|
||||
+ * KDBUS_ITEM_NAME_ADD:
|
||||
+ * KDBUS_ITEM_NAME_REMOVE:
|
||||
+ * KDBUS_ITEM_NAME_CHANGE: Well-known name changes, carry
|
||||
+ * kdbus_notify_name_change
|
||||
+ * KDBUS_ITEM_ID_ADD:
|
||||
+ * KDBUS_ITEM_ID_REMOVE: Connection ID changes, carry
|
||||
+ * kdbus_notify_id_change
|
||||
+ *
|
||||
+ * For kdbus_notify_{id,name}_change structs, only the ID and name fields
|
||||
+ * are looked at when adding an entry. The flags are unused.
|
||||
+ *
|
||||
+ * Also note that KDBUS_ITEM_BLOOM_MASK, KDBUS_ITEM_NAME and KDBUS_ITEM_ID
|
||||
+ * are used to match messages from userspace, while the others apply to
|
||||
+ * kernel-generated notifications.
|
||||
+ *
|
||||
+ * Return: 0 on success, negative error code on failure.
|
||||
+ */
|
||||
+int kdbus_cmd_match_add(struct kdbus_conn *conn, void __user *argp)
|
||||
+{
|
||||
+ struct kdbus_match_db *mdb = conn->match_db;
|
||||
+ struct kdbus_match_entry *entry = NULL;
|
||||
+ struct kdbus_cmd_match *cmd;
|
||||
+ struct kdbus_item *item;
|
||||
+ int ret;
|
||||
+
|
||||
+ struct kdbus_arg argv[] = {
|
||||
+ { .type = KDBUS_ITEM_NEGOTIATE },
|
||||
+ { .type = KDBUS_ITEM_BLOOM_MASK, .multiple = true },
|
||||
+ { .type = KDBUS_ITEM_NAME, .multiple = true },
|
||||
+ { .type = KDBUS_ITEM_ID, .multiple = true },
|
||||
+ { .type = KDBUS_ITEM_NAME_ADD, .multiple = true },
|
||||
+ { .type = KDBUS_ITEM_NAME_REMOVE, .multiple = true },
|
||||
+ { .type = KDBUS_ITEM_NAME_CHANGE, .multiple = true },
|
||||
+ { .type = KDBUS_ITEM_ID_ADD, .multiple = true },
|
||||
+ { .type = KDBUS_ITEM_ID_REMOVE, .multiple = true },
|
||||
+ };
|
||||
+ struct kdbus_args args = {
|
||||
+ .allowed_flags = KDBUS_FLAG_NEGOTIATE |
|
||||
+ KDBUS_MATCH_REPLACE,
|
||||
+ .argv = argv,
|
||||
+ .argc = ARRAY_SIZE(argv),
|
||||
+ };
|
||||
+
|
||||
+ if (!kdbus_conn_is_ordinary(conn))
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ ret = kdbus_args_parse(&args, argp, &cmd);
|
||||
+ if (ret != 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ entry = kzalloc(sizeof(*entry), GFP_KERNEL);
|
||||
+ if (!entry) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ entry->cookie = cmd->cookie;
|
||||
+ INIT_LIST_HEAD(&entry->list_entry);
|
||||
+ INIT_LIST_HEAD(&entry->rules_list);
|
||||
+
|
||||
+ KDBUS_ITEMS_FOREACH(item, cmd->items, KDBUS_ITEMS_SIZE(cmd, items)) {
|
||||
+ struct kdbus_match_rule *rule;
|
||||
+ size_t size = item->size - offsetof(struct kdbus_item, data);
|
||||
+
|
||||
+ rule = kzalloc(sizeof(*rule), GFP_KERNEL);
|
||||
+ if (!rule) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ rule->type = item->type;
|
||||
+ INIT_LIST_HEAD(&rule->rules_entry);
|
||||
+
|
||||
+ switch (item->type) {
|
||||
+ case KDBUS_ITEM_BLOOM_MASK: {
|
||||
+ u64 bsize = conn->ep->bus->bloom.size;
|
||||
+ u64 generations;
|
||||
+ u64 remainder;
|
||||
+
|
||||
+ generations = div64_u64_rem(size, bsize, &remainder);
|
||||
+ if (size < bsize || remainder > 0) {
|
||||
+ ret = -EDOM;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ rule->bloom_mask.data = kmemdup(item->data,
|
||||
+ size, GFP_KERNEL);
|
||||
+ if (!rule->bloom_mask.data) {
|
||||
+ ret = -ENOMEM;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ rule->bloom_mask.generations = generations;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ case KDBUS_ITEM_NAME:
|
||||
+ if (!kdbus_name_is_valid(item->str, false)) {
|
||||
+ ret = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ rule->name = kstrdup(item->str, GFP_KERNEL);
|
||||
+ if (!rule->name)
|
||||
+ ret = -ENOMEM;
|
||||
+
|
||||
+ break;
|
||||
+
|
||||
+ case KDBUS_ITEM_ID:
|
||||
+ rule->src_id = item->id;
|
||||
+ break;
|
||||
+
|
||||
+ case KDBUS_ITEM_NAME_ADD:
|
||||
+ case KDBUS_ITEM_NAME_REMOVE:
|
||||
+ case KDBUS_ITEM_NAME_CHANGE:
|
||||
+ rule->old_id = item->name_change.old_id.id;
|
||||
+ rule->new_id = item->name_change.new_id.id;
|
||||
+
|
||||
+ if (size > sizeof(struct kdbus_notify_name_change)) {
|
||||
+ rule->name = kstrdup(item->name_change.name,
|
||||
+ GFP_KERNEL);
|
||||
+ if (!rule->name)
|
||||
+ ret = -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ break;
|
||||
+
|
||||
+ case KDBUS_ITEM_ID_ADD:
|
||||
+ case KDBUS_ITEM_ID_REMOVE:
|
||||
+ if (item->type == KDBUS_ITEM_ID_ADD)
|
||||
+ rule->new_id = item->id_change.id;
|
||||
+ else
|
||||
+ rule->old_id = item->id_change.id;
|
||||
+
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (ret < 0) {
|
||||
+ kdbus_match_rule_free(rule);
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ list_add_tail(&rule->rules_entry, &entry->rules_list);
|
||||
+ }
|
||||
+
|
||||
+ down_write(&mdb->mdb_rwlock);
|
||||
+
|
||||
+ /* Remove any entry that has the same cookie as the current one. */
|
||||
+ if (cmd->flags & KDBUS_MATCH_REPLACE)
|
||||
+ kdbus_match_db_remove_unlocked(mdb, entry->cookie);
|
||||
+
|
||||
+ /*
|
||||
+ * If the above removal caught any entry, there will be room for the
|
||||
+ * new one.
|
||||
+ */
|
||||
+ if (++mdb->entries_count > KDBUS_MATCH_MAX) {
|
||||
+ --mdb->entries_count;
|
||||
+ ret = -EMFILE;
|
||||
+ } else {
|
||||
+ list_add_tail(&entry->list_entry, &mdb->entries_list);
|
||||
+ entry = NULL;
|
||||
+ }
|
||||
+
|
||||
+ up_write(&mdb->mdb_rwlock);
|
||||
+
|
||||
+exit:
|
||||
+ kdbus_match_entry_free(entry);
|
||||
+ return kdbus_args_clear(&args, ret);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_cmd_match_remove() - handle KDBUS_CMD_MATCH_REMOVE
|
||||
+ * @conn: connection to operate on
|
||||
+ * @argp: command payload
|
||||
+ *
|
||||
+ * Return: 0 on success, negative error code on failure.
|
||||
+ */
|
||||
+int kdbus_cmd_match_remove(struct kdbus_conn *conn, void __user *argp)
|
||||
+{
|
||||
+ struct kdbus_cmd_match *cmd;
|
||||
+ int ret;
|
||||
+
|
||||
+ struct kdbus_arg argv[] = {
|
||||
+ { .type = KDBUS_ITEM_NEGOTIATE },
|
||||
+ };
|
||||
+ struct kdbus_args args = {
|
||||
+ .allowed_flags = KDBUS_FLAG_NEGOTIATE,
|
||||
+ .argv = argv,
|
||||
+ .argc = ARRAY_SIZE(argv),
|
||||
+ };
|
||||
+
|
||||
+ if (!kdbus_conn_is_ordinary(conn))
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ ret = kdbus_args_parse(&args, argp, &cmd);
|
||||
+ if (ret != 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ down_write(&conn->match_db->mdb_rwlock);
|
||||
+ ret = kdbus_match_db_remove_unlocked(conn->match_db, cmd->cookie);
|
||||
+ up_write(&conn->match_db->mdb_rwlock);
|
||||
+
|
||||
+ return kdbus_args_clear(&args, ret);
|
||||
+}
|
||||
diff --git a/ipc/kdbus/match.h b/ipc/kdbus/match.h
|
||||
new file mode 100644
|
||||
index 000000000000..ea4292938deb
|
||||
--- /dev/null
|
||||
+++ b/ipc/kdbus/match.h
|
||||
@@ -0,0 +1,35 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2013-2015 Kay Sievers
|
||||
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
|
||||
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
|
||||
+ * Copyright (C) 2013-2015 Linux Foundation
|
||||
+ * Copyright (C) 2014-2015 Djalal Harouni <tixxdz@opendz.org>
|
||||
+ *
|
||||
+ * kdbus is free software; you can redistribute it and/or modify it under
|
||||
+ * the terms of the GNU Lesser General Public License as published by the
|
||||
+ * Free Software Foundation; either version 2.1 of the License, or (at
|
||||
+ * your option) any later version.
|
||||
+ */
|
||||
+
|
||||
+#ifndef __KDBUS_MATCH_H
|
||||
+#define __KDBUS_MATCH_H
|
||||
+
|
||||
+struct kdbus_conn;
|
||||
+struct kdbus_kmsg;
|
||||
+struct kdbus_match_db;
|
||||
+
|
||||
+struct kdbus_match_db *kdbus_match_db_new(void);
|
||||
+void kdbus_match_db_free(struct kdbus_match_db *db);
|
||||
+int kdbus_match_db_add(struct kdbus_conn *conn,
|
||||
+ struct kdbus_cmd_match *cmd);
|
||||
+int kdbus_match_db_remove(struct kdbus_conn *conn,
|
||||
+ struct kdbus_cmd_match *cmd);
|
||||
+bool kdbus_match_db_match_kmsg(struct kdbus_match_db *db,
|
||||
+ struct kdbus_conn *conn_src,
|
||||
+ struct kdbus_kmsg *kmsg);
|
||||
+
|
||||
+int kdbus_cmd_match_add(struct kdbus_conn *conn, void __user *argp);
|
||||
+int kdbus_cmd_match_remove(struct kdbus_conn *conn, void __user *argp);
|
||||
+
|
||||
+#endif
|
||||
diff --git a/ipc/kdbus/notify.c b/ipc/kdbus/notify.c
|
||||
new file mode 100644
|
||||
index 000000000000..e4a454222f09
|
||||
--- /dev/null
|
||||
+++ b/ipc/kdbus/notify.c
|
||||
@@ -0,0 +1,248 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2013-2015 Kay Sievers
|
||||
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
|
||||
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
|
||||
+ * Copyright (C) 2013-2015 Linux Foundation
|
||||
+ * Copyright (C) 2014-2015 Djalal Harouni <tixxdz@opendz.org>
|
||||
+ *
|
||||
+ * kdbus is free software; you can redistribute it and/or modify it under
|
||||
+ * the terms of the GNU Lesser General Public License as published by the
|
||||
+ * Free Software Foundation; either version 2.1 of the License, or (at
|
||||
+ * your option) any later version.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/fs.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/mutex.h>
|
||||
+#include <linux/spinlock.h>
|
||||
+#include <linux/sched.h>
|
||||
+#include <linux/slab.h>
|
||||
+
|
||||
+#include "bus.h"
|
||||
+#include "connection.h"
|
||||
+#include "domain.h"
|
||||
+#include "endpoint.h"
|
||||
+#include "item.h"
|
||||
+#include "message.h"
|
||||
+#include "notify.h"
|
||||
+
|
||||
+static inline void kdbus_notify_add_tail(struct kdbus_kmsg *kmsg,
|
||||
+ struct kdbus_bus *bus)
|
||||
+{
|
||||
+ spin_lock(&bus->notify_lock);
|
||||
+ list_add_tail(&kmsg->notify_entry, &bus->notify_list);
|
||||
+ spin_unlock(&bus->notify_lock);
|
||||
+}
|
||||
+
|
||||
+static int kdbus_notify_reply(struct kdbus_bus *bus, u64 id,
|
||||
+ u64 cookie, u64 msg_type)
|
||||
+{
|
||||
+ struct kdbus_kmsg *kmsg = NULL;
|
||||
+
|
||||
+ WARN_ON(id == 0);
|
||||
+
|
||||
+ kmsg = kdbus_kmsg_new(bus, 0);
|
||||
+ if (IS_ERR(kmsg))
|
||||
+ return PTR_ERR(kmsg);
|
||||
+
|
||||
+ /*
|
||||
+ * a kernel-generated notification can only contain one
|
||||
+ * struct kdbus_item, so make a shortcut here for
|
||||
+ * faster lookup in the match db.
|
||||
+ */
|
||||
+ kmsg->notify_type = msg_type;
|
||||
+ kmsg->msg.flags = KDBUS_MSG_SIGNAL;
|
||||
+ kmsg->msg.dst_id = id;
|
||||
+ kmsg->msg.src_id = KDBUS_SRC_ID_KERNEL;
|
||||
+ kmsg->msg.payload_type = KDBUS_PAYLOAD_KERNEL;
|
||||
+ kmsg->msg.cookie_reply = cookie;
|
||||
+ kmsg->msg.items[0].type = msg_type;
|
||||
+
|
||||
+ kdbus_notify_add_tail(kmsg, bus);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_notify_reply_timeout() - queue a timeout reply
|
||||
+ * @bus: Bus which queues the messages
|
||||
+ * @id: The destination's connection ID
|
||||
+ * @cookie: The cookie to set in the reply.
|
||||
+ *
|
||||
+ * Queues a message that has a KDBUS_ITEM_REPLY_TIMEOUT item attached.
|
||||
+ *
|
||||
+ * Return: 0 on success, negative errno on failure.
|
||||
+ */
|
||||
+int kdbus_notify_reply_timeout(struct kdbus_bus *bus, u64 id, u64 cookie)
|
||||
+{
|
||||
+ return kdbus_notify_reply(bus, id, cookie, KDBUS_ITEM_REPLY_TIMEOUT);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_notify_reply_dead() - queue a 'dead' reply
|
||||
+ * @bus: Bus which queues the messages
|
||||
+ * @id: The destination's connection ID
|
||||
+ * @cookie: The cookie to set in the reply.
|
||||
+ *
|
||||
+ * Queues a message that has a KDBUS_ITEM_REPLY_DEAD item attached.
|
||||
+ *
|
||||
+ * Return: 0 on success, negative errno on failure.
|
||||
+ */
|
||||
+int kdbus_notify_reply_dead(struct kdbus_bus *bus, u64 id, u64 cookie)
|
||||
+{
|
||||
+ return kdbus_notify_reply(bus, id, cookie, KDBUS_ITEM_REPLY_DEAD);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_notify_name_change() - queue a notification about a name owner change
|
||||
+ * @bus: Bus which queues the messages
|
||||
+ * @type: The type if the notification; KDBUS_ITEM_NAME_ADD,
|
||||
+ * KDBUS_ITEM_NAME_CHANGE or KDBUS_ITEM_NAME_REMOVE
|
||||
+ * @old_id: The id of the connection that used to own the name
|
||||
+ * @new_id: The id of the new owner connection
|
||||
+ * @old_flags: The flags to pass in the KDBUS_ITEM flags field for
|
||||
+ * the old owner
|
||||
+ * @new_flags: The flags to pass in the KDBUS_ITEM flags field for
|
||||
+ * the new owner
|
||||
+ * @name: The name that was removed or assigned to a new owner
|
||||
+ *
|
||||
+ * Return: 0 on success, negative errno on failure.
|
||||
+ */
|
||||
+int kdbus_notify_name_change(struct kdbus_bus *bus, u64 type,
|
||||
+ u64 old_id, u64 new_id,
|
||||
+ u64 old_flags, u64 new_flags,
|
||||
+ const char *name)
|
||||
+{
|
||||
+ struct kdbus_kmsg *kmsg = NULL;
|
||||
+ size_t name_len, extra_size;
|
||||
+
|
||||
+ name_len = strlen(name) + 1;
|
||||
+ extra_size = sizeof(struct kdbus_notify_name_change) + name_len;
|
||||
+ kmsg = kdbus_kmsg_new(bus, extra_size);
|
||||
+ if (IS_ERR(kmsg))
|
||||
+ return PTR_ERR(kmsg);
|
||||
+
|
||||
+ kmsg->msg.flags = KDBUS_MSG_SIGNAL;
|
||||
+ kmsg->msg.dst_id = KDBUS_DST_ID_BROADCAST;
|
||||
+ kmsg->msg.src_id = KDBUS_SRC_ID_KERNEL;
|
||||
+ kmsg->msg.payload_type = KDBUS_PAYLOAD_KERNEL;
|
||||
+ kmsg->notify_type = type;
|
||||
+ kmsg->notify_old_id = old_id;
|
||||
+ kmsg->notify_new_id = new_id;
|
||||
+ kmsg->msg.items[0].type = type;
|
||||
+ kmsg->msg.items[0].name_change.old_id.id = old_id;
|
||||
+ kmsg->msg.items[0].name_change.old_id.flags = old_flags;
|
||||
+ kmsg->msg.items[0].name_change.new_id.id = new_id;
|
||||
+ kmsg->msg.items[0].name_change.new_id.flags = new_flags;
|
||||
+ memcpy(kmsg->msg.items[0].name_change.name, name, name_len);
|
||||
+ kmsg->notify_name = kmsg->msg.items[0].name_change.name;
|
||||
+
|
||||
+ kdbus_notify_add_tail(kmsg, bus);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_notify_id_change() - queue a notification about a unique ID change
|
||||
+ * @bus: Bus which queues the messages
|
||||
+ * @type: The type if the notification; KDBUS_ITEM_ID_ADD or
|
||||
+ * KDBUS_ITEM_ID_REMOVE
|
||||
+ * @id: The id of the connection that was added or removed
|
||||
+ * @flags: The flags to pass in the KDBUS_ITEM flags field
|
||||
+ *
|
||||
+ * Return: 0 on success, negative errno on failure.
|
||||
+ */
|
||||
+int kdbus_notify_id_change(struct kdbus_bus *bus, u64 type, u64 id, u64 flags)
|
||||
+{
|
||||
+ struct kdbus_kmsg *kmsg = NULL;
|
||||
+
|
||||
+ kmsg = kdbus_kmsg_new(bus, sizeof(struct kdbus_notify_id_change));
|
||||
+ if (IS_ERR(kmsg))
|
||||
+ return PTR_ERR(kmsg);
|
||||
+
|
||||
+ kmsg->msg.flags = KDBUS_MSG_SIGNAL;
|
||||
+ kmsg->msg.dst_id = KDBUS_DST_ID_BROADCAST;
|
||||
+ kmsg->msg.src_id = KDBUS_SRC_ID_KERNEL;
|
||||
+ kmsg->msg.payload_type = KDBUS_PAYLOAD_KERNEL;
|
||||
+ kmsg->notify_type = type;
|
||||
+
|
||||
+ switch (type) {
|
||||
+ case KDBUS_ITEM_ID_ADD:
|
||||
+ kmsg->notify_new_id = id;
|
||||
+ break;
|
||||
+
|
||||
+ case KDBUS_ITEM_ID_REMOVE:
|
||||
+ kmsg->notify_old_id = id;
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ BUG();
|
||||
+ }
|
||||
+
|
||||
+ kmsg->msg.items[0].type = type;
|
||||
+ kmsg->msg.items[0].id_change.id = id;
|
||||
+ kmsg->msg.items[0].id_change.flags = flags;
|
||||
+
|
||||
+ kdbus_notify_add_tail(kmsg, bus);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_notify_flush() - send a list of collected messages
|
||||
+ * @bus: Bus which queues the messages
|
||||
+ *
|
||||
+ * The list is empty after sending the messages.
|
||||
+ */
|
||||
+void kdbus_notify_flush(struct kdbus_bus *bus)
|
||||
+{
|
||||
+ LIST_HEAD(notify_list);
|
||||
+ struct kdbus_kmsg *kmsg, *tmp;
|
||||
+
|
||||
+ mutex_lock(&bus->notify_flush_lock);
|
||||
+ down_read(&bus->name_registry->rwlock);
|
||||
+
|
||||
+ spin_lock(&bus->notify_lock);
|
||||
+ list_splice_init(&bus->notify_list, ¬ify_list);
|
||||
+ spin_unlock(&bus->notify_lock);
|
||||
+
|
||||
+ list_for_each_entry_safe(kmsg, tmp, ¬ify_list, notify_entry) {
|
||||
+ kdbus_meta_conn_collect(kmsg->conn_meta, kmsg, NULL,
|
||||
+ KDBUS_ATTACH_TIMESTAMP);
|
||||
+
|
||||
+ if (kmsg->msg.dst_id != KDBUS_DST_ID_BROADCAST) {
|
||||
+ struct kdbus_conn *conn;
|
||||
+
|
||||
+ conn = kdbus_bus_find_conn_by_id(bus, kmsg->msg.dst_id);
|
||||
+ if (conn) {
|
||||
+ kdbus_bus_eavesdrop(bus, NULL, kmsg);
|
||||
+ kdbus_conn_entry_insert(NULL, conn, kmsg, NULL);
|
||||
+ kdbus_conn_unref(conn);
|
||||
+ }
|
||||
+ } else {
|
||||
+ kdbus_bus_broadcast(bus, NULL, kmsg);
|
||||
+ }
|
||||
+
|
||||
+ list_del(&kmsg->notify_entry);
|
||||
+ kdbus_kmsg_free(kmsg);
|
||||
+ }
|
||||
+
|
||||
+ up_read(&bus->name_registry->rwlock);
|
||||
+ mutex_unlock(&bus->notify_flush_lock);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_notify_free() - free a list of collected messages
|
||||
+ * @bus: Bus which queues the messages
|
||||
+ */
|
||||
+void kdbus_notify_free(struct kdbus_bus *bus)
|
||||
+{
|
||||
+ struct kdbus_kmsg *kmsg, *tmp;
|
||||
+
|
||||
+ list_for_each_entry_safe(kmsg, tmp, &bus->notify_list, notify_entry) {
|
||||
+ list_del(&kmsg->notify_entry);
|
||||
+ kdbus_kmsg_free(kmsg);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/ipc/kdbus/notify.h b/ipc/kdbus/notify.h
|
||||
new file mode 100644
|
||||
index 000000000000..03df464cb735
|
||||
--- /dev/null
|
||||
+++ b/ipc/kdbus/notify.h
|
||||
@@ -0,0 +1,30 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2013-2015 Kay Sievers
|
||||
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
|
||||
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
|
||||
+ * Copyright (C) 2013-2015 Linux Foundation
|
||||
+ * Copyright (C) 2014-2015 Djalal Harouni <tixxdz@opendz.org>
|
||||
+ *
|
||||
+ * kdbus is free software; you can redistribute it and/or modify it under
|
||||
+ * the terms of the GNU Lesser General Public License as published by the
|
||||
+ * Free Software Foundation; either version 2.1 of the License, or (at
|
||||
+ * your option) any later version.
|
||||
+ */
|
||||
+
|
||||
+#ifndef __KDBUS_NOTIFY_H
|
||||
+#define __KDBUS_NOTIFY_H
|
||||
+
|
||||
+struct kdbus_bus;
|
||||
+
|
||||
+int kdbus_notify_id_change(struct kdbus_bus *bus, u64 type, u64 id, u64 flags);
|
||||
+int kdbus_notify_reply_timeout(struct kdbus_bus *bus, u64 id, u64 cookie);
|
||||
+int kdbus_notify_reply_dead(struct kdbus_bus *bus, u64 id, u64 cookie);
|
||||
+int kdbus_notify_name_change(struct kdbus_bus *bus, u64 type,
|
||||
+ u64 old_id, u64 new_id,
|
||||
+ u64 old_flags, u64 new_flags,
|
||||
+ const char *name);
|
||||
+void kdbus_notify_flush(struct kdbus_bus *bus);
|
||||
+void kdbus_notify_free(struct kdbus_bus *bus);
|
||||
+
|
||||
+#endif
|
1320
kdbus-add-code-to-gather-metadata.patch
Normal file
1320
kdbus-add-code-to-gather-metadata.patch
Normal file
File diff suppressed because it is too large
Load Diff
822
kdbus-add-connection-pool-implementation.patch
Normal file
822
kdbus-add-connection-pool-implementation.patch
Normal file
@ -0,0 +1,822 @@
|
||||
From: Daniel Mack <daniel@zonque.org>
|
||||
Date: Thu, 11 Sep 2014 18:56:41 +0200
|
||||
Subject: [PATCH] kdbus: add connection pool implementation
|
||||
|
||||
A pool for data received from the kernel is installed for every
|
||||
connection of the bus, and it is used to copy data from the kernel to
|
||||
userspace clients, for messages and other information.
|
||||
|
||||
It is accessed when one of the following ioctls is issued:
|
||||
|
||||
* KDBUS_CMD_MSG_RECV, to receive a message
|
||||
* KDBUS_CMD_NAME_LIST, to dump the name registry
|
||||
* KDBUS_CMD_CONN_INFO, to retrieve information on a connection
|
||||
|
||||
The offsets returned by either one of the aforementioned ioctls
|
||||
describe offsets inside the pool. Internally, the pool is organized in
|
||||
slices, that are dynamically allocated on demand. The overall size of
|
||||
the pool is chosen by the connection when it connects to the bus with
|
||||
KDBUS_CMD_HELLO.
|
||||
|
||||
In order to make the slice available for subsequent calls,
|
||||
KDBUS_CMD_FREE has to be called on the offset.
|
||||
|
||||
To access the memory, the caller is expected to mmap() it to its task.
|
||||
|
||||
Signed-off-by: Daniel Mack <daniel@zonque.org>
|
||||
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Signed-off-by: Djalal Harouni <tixxdz@opendz.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
ipc/kdbus/pool.c | 728 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
ipc/kdbus/pool.h | 46 ++++
|
||||
2 files changed, 774 insertions(+)
|
||||
create mode 100644 ipc/kdbus/pool.c
|
||||
create mode 100644 ipc/kdbus/pool.h
|
||||
|
||||
diff --git a/ipc/kdbus/pool.c b/ipc/kdbus/pool.c
|
||||
new file mode 100644
|
||||
index 000000000000..139bb77056b3
|
||||
--- /dev/null
|
||||
+++ b/ipc/kdbus/pool.c
|
||||
@@ -0,0 +1,728 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2013-2015 Kay Sievers
|
||||
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
|
||||
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
|
||||
+ * Copyright (C) 2013-2015 Linux Foundation
|
||||
+ * Copyright (C) 2014-2015 Djalal Harouni <tixxdz@opendz.org>
|
||||
+ *
|
||||
+ * kdbus is free software; you can redistribute it and/or modify it under
|
||||
+ * the terms of the GNU Lesser General Public License as published by the
|
||||
+ * Free Software Foundation; either version 2.1 of the License, or (at
|
||||
+ * your option) any later version.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/aio.h>
|
||||
+#include <linux/file.h>
|
||||
+#include <linux/fs.h>
|
||||
+#include <linux/highmem.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/mm.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/pagemap.h>
|
||||
+#include <linux/rbtree.h>
|
||||
+#include <linux/sched.h>
|
||||
+#include <linux/shmem_fs.h>
|
||||
+#include <linux/sizes.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/uaccess.h>
|
||||
+#include <linux/uio.h>
|
||||
+
|
||||
+#include "pool.h"
|
||||
+#include "util.h"
|
||||
+
|
||||
+/**
|
||||
+ * struct kdbus_pool - the receiver's buffer
|
||||
+ * @f: The backing shmem file
|
||||
+ * @size: The size of the file
|
||||
+ * @accounted_size: Currently accounted memory in bytes
|
||||
+ * @lock: Pool data lock
|
||||
+ * @slices: All slices sorted by address
|
||||
+ * @slices_busy: Tree of allocated slices
|
||||
+ * @slices_free: Tree of free slices
|
||||
+ *
|
||||
+ * The receiver's buffer, managed as a pool of allocated and free
|
||||
+ * slices containing the queued messages.
|
||||
+ *
|
||||
+ * Messages sent with KDBUS_CMD_SEND are copied direcly by the
|
||||
+ * sending process into the receiver's pool.
|
||||
+ *
|
||||
+ * Messages received with KDBUS_CMD_RECV just return the offset
|
||||
+ * to the data placed in the pool.
|
||||
+ *
|
||||
+ * The internally allocated memory needs to be returned by the receiver
|
||||
+ * with KDBUS_CMD_FREE.
|
||||
+ */
|
||||
+struct kdbus_pool {
|
||||
+ struct file *f;
|
||||
+ size_t size;
|
||||
+ size_t accounted_size;
|
||||
+ struct mutex lock;
|
||||
+
|
||||
+ struct list_head slices;
|
||||
+ struct rb_root slices_busy;
|
||||
+ struct rb_root slices_free;
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct kdbus_pool_slice - allocated element in kdbus_pool
|
||||
+ * @pool: Pool this slice belongs to
|
||||
+ * @off: Offset of slice in the shmem file
|
||||
+ * @size: Size of slice
|
||||
+ * @entry: Entry in "all slices" list
|
||||
+ * @rb_node: Entry in free or busy list
|
||||
+ * @free: Unused slice
|
||||
+ * @accounted: Accounted as queue slice
|
||||
+ * @ref_kernel: Kernel holds a reference
|
||||
+ * @ref_user: Userspace holds a reference
|
||||
+ *
|
||||
+ * The pool has one or more slices, always spanning the entire size of the
|
||||
+ * pool.
|
||||
+ *
|
||||
+ * Every slice is an element in a list sorted by the buffer address, to
|
||||
+ * provide access to the next neighbor slice.
|
||||
+ *
|
||||
+ * Every slice is member in either the busy or the free tree. The free
|
||||
+ * tree is organized by slice size, the busy tree organized by buffer
|
||||
+ * offset.
|
||||
+ */
|
||||
+struct kdbus_pool_slice {
|
||||
+ struct kdbus_pool *pool;
|
||||
+ size_t off;
|
||||
+ size_t size;
|
||||
+
|
||||
+ struct list_head entry;
|
||||
+ struct rb_node rb_node;
|
||||
+
|
||||
+ bool free:1;
|
||||
+ bool accounted:1;
|
||||
+ bool ref_kernel:1;
|
||||
+ bool ref_user:1;
|
||||
+};
|
||||
+
|
||||
+static struct kdbus_pool_slice *kdbus_pool_slice_new(struct kdbus_pool *pool,
|
||||
+ size_t off, size_t size)
|
||||
+{
|
||||
+ struct kdbus_pool_slice *slice;
|
||||
+
|
||||
+ slice = kzalloc(sizeof(*slice), GFP_KERNEL);
|
||||
+ if (!slice)
|
||||
+ return NULL;
|
||||
+
|
||||
+ slice->pool = pool;
|
||||
+ slice->off = off;
|
||||
+ slice->size = size;
|
||||
+ slice->free = true;
|
||||
+ return slice;
|
||||
+}
|
||||
+
|
||||
+/* insert a slice into the free tree */
|
||||
+static void kdbus_pool_add_free_slice(struct kdbus_pool *pool,
|
||||
+ struct kdbus_pool_slice *slice)
|
||||
+{
|
||||
+ struct rb_node **n;
|
||||
+ struct rb_node *pn = NULL;
|
||||
+
|
||||
+ n = &pool->slices_free.rb_node;
|
||||
+ while (*n) {
|
||||
+ struct kdbus_pool_slice *pslice;
|
||||
+
|
||||
+ pn = *n;
|
||||
+ pslice = rb_entry(pn, struct kdbus_pool_slice, rb_node);
|
||||
+ if (slice->size < pslice->size)
|
||||
+ n = &pn->rb_left;
|
||||
+ else
|
||||
+ n = &pn->rb_right;
|
||||
+ }
|
||||
+
|
||||
+ rb_link_node(&slice->rb_node, pn, n);
|
||||
+ rb_insert_color(&slice->rb_node, &pool->slices_free);
|
||||
+}
|
||||
+
|
||||
+/* insert a slice into the busy tree */
|
||||
+static void kdbus_pool_add_busy_slice(struct kdbus_pool *pool,
|
||||
+ struct kdbus_pool_slice *slice)
|
||||
+{
|
||||
+ struct rb_node **n;
|
||||
+ struct rb_node *pn = NULL;
|
||||
+
|
||||
+ n = &pool->slices_busy.rb_node;
|
||||
+ while (*n) {
|
||||
+ struct kdbus_pool_slice *pslice;
|
||||
+
|
||||
+ pn = *n;
|
||||
+ pslice = rb_entry(pn, struct kdbus_pool_slice, rb_node);
|
||||
+ if (slice->off < pslice->off)
|
||||
+ n = &pn->rb_left;
|
||||
+ else if (slice->off > pslice->off)
|
||||
+ n = &pn->rb_right;
|
||||
+ else
|
||||
+ BUG();
|
||||
+ }
|
||||
+
|
||||
+ rb_link_node(&slice->rb_node, pn, n);
|
||||
+ rb_insert_color(&slice->rb_node, &pool->slices_busy);
|
||||
+}
|
||||
+
|
||||
+static struct kdbus_pool_slice *kdbus_pool_find_slice(struct kdbus_pool *pool,
|
||||
+ size_t off)
|
||||
+{
|
||||
+ struct rb_node *n;
|
||||
+
|
||||
+ n = pool->slices_busy.rb_node;
|
||||
+ while (n) {
|
||||
+ struct kdbus_pool_slice *s;
|
||||
+
|
||||
+ s = rb_entry(n, struct kdbus_pool_slice, rb_node);
|
||||
+ if (off < s->off)
|
||||
+ n = n->rb_left;
|
||||
+ else if (off > s->off)
|
||||
+ n = n->rb_right;
|
||||
+ else
|
||||
+ return s;
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_pool_slice_alloc() - allocate memory from a pool
|
||||
+ * @pool: The receiver's pool
|
||||
+ * @size: The number of bytes to allocate
|
||||
+ * @accounted: Whether this slice should be accounted for
|
||||
+ *
|
||||
+ * The returned slice is used for kdbus_pool_slice_release() to
|
||||
+ * free the allocated memory. If either @kvec or @iovec is non-NULL, the data
|
||||
+ * will be copied from kernel or userspace memory into the new slice at
|
||||
+ * offset 0.
|
||||
+ *
|
||||
+ * Return: the allocated slice on success, ERR_PTR on failure.
|
||||
+ */
|
||||
+struct kdbus_pool_slice *kdbus_pool_slice_alloc(struct kdbus_pool *pool,
|
||||
+ size_t size, bool accounted)
|
||||
+{
|
||||
+ size_t slice_size = KDBUS_ALIGN8(size);
|
||||
+ struct rb_node *n, *found = NULL;
|
||||
+ struct kdbus_pool_slice *s;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if (WARN_ON(!size))
|
||||
+ return ERR_PTR(-EINVAL);
|
||||
+
|
||||
+ /* search a free slice with the closest matching size */
|
||||
+ mutex_lock(&pool->lock);
|
||||
+ n = pool->slices_free.rb_node;
|
||||
+ while (n) {
|
||||
+ s = rb_entry(n, struct kdbus_pool_slice, rb_node);
|
||||
+ if (slice_size < s->size) {
|
||||
+ found = n;
|
||||
+ n = n->rb_left;
|
||||
+ } else if (slice_size > s->size) {
|
||||
+ n = n->rb_right;
|
||||
+ } else {
|
||||
+ found = n;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* no slice with the minimum size found in the pool */
|
||||
+ if (!found) {
|
||||
+ ret = -EXFULL;
|
||||
+ goto exit_unlock;
|
||||
+ }
|
||||
+
|
||||
+ /* no exact match, use the closest one */
|
||||
+ if (!n) {
|
||||
+ struct kdbus_pool_slice *s_new;
|
||||
+
|
||||
+ s = rb_entry(found, struct kdbus_pool_slice, rb_node);
|
||||
+
|
||||
+ /* split-off the remainder of the size to its own slice */
|
||||
+ s_new = kdbus_pool_slice_new(pool, s->off + slice_size,
|
||||
+ s->size - slice_size);
|
||||
+ if (!s_new) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto exit_unlock;
|
||||
+ }
|
||||
+
|
||||
+ list_add(&s_new->entry, &s->entry);
|
||||
+ kdbus_pool_add_free_slice(pool, s_new);
|
||||
+
|
||||
+ /* adjust our size now that we split-off another slice */
|
||||
+ s->size = slice_size;
|
||||
+ }
|
||||
+
|
||||
+ /* move slice from free to the busy tree */
|
||||
+ rb_erase(found, &pool->slices_free);
|
||||
+ kdbus_pool_add_busy_slice(pool, s);
|
||||
+
|
||||
+ WARN_ON(s->ref_kernel || s->ref_user);
|
||||
+
|
||||
+ s->ref_kernel = true;
|
||||
+ s->free = false;
|
||||
+ s->accounted = accounted;
|
||||
+ if (accounted)
|
||||
+ pool->accounted_size += s->size;
|
||||
+ mutex_unlock(&pool->lock);
|
||||
+
|
||||
+ return s;
|
||||
+
|
||||
+exit_unlock:
|
||||
+ mutex_unlock(&pool->lock);
|
||||
+ return ERR_PTR(ret);
|
||||
+}
|
||||
+
|
||||
+static void __kdbus_pool_slice_release(struct kdbus_pool_slice *slice)
|
||||
+{
|
||||
+ struct kdbus_pool *pool = slice->pool;
|
||||
+
|
||||
+ /* don't free the slice if either has a reference */
|
||||
+ if (slice->ref_kernel || slice->ref_user)
|
||||
+ return;
|
||||
+
|
||||
+ if (WARN_ON(slice->free))
|
||||
+ return;
|
||||
+
|
||||
+ rb_erase(&slice->rb_node, &pool->slices_busy);
|
||||
+
|
||||
+ /* merge with the next free slice */
|
||||
+ if (!list_is_last(&slice->entry, &pool->slices)) {
|
||||
+ struct kdbus_pool_slice *s;
|
||||
+
|
||||
+ s = list_entry(slice->entry.next,
|
||||
+ struct kdbus_pool_slice, entry);
|
||||
+ if (s->free) {
|
||||
+ rb_erase(&s->rb_node, &pool->slices_free);
|
||||
+ list_del(&s->entry);
|
||||
+ slice->size += s->size;
|
||||
+ kfree(s);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* merge with previous free slice */
|
||||
+ if (pool->slices.next != &slice->entry) {
|
||||
+ struct kdbus_pool_slice *s;
|
||||
+
|
||||
+ s = list_entry(slice->entry.prev,
|
||||
+ struct kdbus_pool_slice, entry);
|
||||
+ if (s->free) {
|
||||
+ rb_erase(&s->rb_node, &pool->slices_free);
|
||||
+ list_del(&slice->entry);
|
||||
+ s->size += slice->size;
|
||||
+ kfree(slice);
|
||||
+ slice = s;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ slice->free = true;
|
||||
+ kdbus_pool_add_free_slice(pool, slice);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_pool_slice_release() - drop kernel-reference on allocated slice
|
||||
+ * @slice: Slice allocated from the pool
|
||||
+ *
|
||||
+ * This releases the kernel-reference on the given slice. If the
|
||||
+ * kernel-reference and the user-reference on a slice are dropped, the slice is
|
||||
+ * returned to the pool.
|
||||
+ *
|
||||
+ * So far, we do not implement full ref-counting on slices. Each, kernel and
|
||||
+ * user-space can have exactly one reference to a slice. If both are dropped at
|
||||
+ * the same time, the slice is released.
|
||||
+ */
|
||||
+void kdbus_pool_slice_release(struct kdbus_pool_slice *slice)
|
||||
+{
|
||||
+ struct kdbus_pool *pool;
|
||||
+
|
||||
+ if (!slice)
|
||||
+ return;
|
||||
+
|
||||
+ /* @slice may be freed, so keep local ptr to @pool */
|
||||
+ pool = slice->pool;
|
||||
+
|
||||
+ mutex_lock(&pool->lock);
|
||||
+ /* kernel must own a ref to @slice to drop it */
|
||||
+ WARN_ON(!slice->ref_kernel);
|
||||
+ slice->ref_kernel = false;
|
||||
+ /* no longer kernel-owned, de-account slice */
|
||||
+ if (slice->accounted && !WARN_ON(pool->accounted_size < slice->size))
|
||||
+ pool->accounted_size -= slice->size;
|
||||
+ __kdbus_pool_slice_release(slice);
|
||||
+ mutex_unlock(&pool->lock);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_pool_release_offset() - release a public offset
|
||||
+ * @pool: pool to operate on
|
||||
+ * @off: offset to release
|
||||
+ *
|
||||
+ * This should be called whenever user-space frees a slice given to them. It
|
||||
+ * verifies the slice is available and public, and then drops it. It ensures
|
||||
+ * correct locking and barriers against queues.
|
||||
+ *
|
||||
+ * Return: 0 on success, ENXIO if the offset is invalid or not public.
|
||||
+ */
|
||||
+int kdbus_pool_release_offset(struct kdbus_pool *pool, size_t off)
|
||||
+{
|
||||
+ struct kdbus_pool_slice *slice;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ /* 'pool->size' is used as dummy offset for empty slices */
|
||||
+ if (off == pool->size)
|
||||
+ return 0;
|
||||
+
|
||||
+ mutex_lock(&pool->lock);
|
||||
+ slice = kdbus_pool_find_slice(pool, off);
|
||||
+ if (slice && slice->ref_user) {
|
||||
+ slice->ref_user = false;
|
||||
+ __kdbus_pool_slice_release(slice);
|
||||
+ } else {
|
||||
+ ret = -ENXIO;
|
||||
+ }
|
||||
+ mutex_unlock(&pool->lock);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_pool_publish_empty() - publish empty slice to user-space
|
||||
+ * @pool: pool to operate on
|
||||
+ * @off: output storage for offset, or NULL
|
||||
+ * @size: output storage for size, or NULL
|
||||
+ *
|
||||
+ * This is the same as kdbus_pool_slice_publish(), but uses a dummy slice with
|
||||
+ * size 0. The returned offset points to the end of the pool and is never
|
||||
+ * returned on real slices.
|
||||
+ */
|
||||
+void kdbus_pool_publish_empty(struct kdbus_pool *pool, u64 *off, u64 *size)
|
||||
+{
|
||||
+ if (off)
|
||||
+ *off = pool->size;
|
||||
+ if (size)
|
||||
+ *size = 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_pool_slice_publish() - publish slice to user-space
|
||||
+ * @slice: The slice
|
||||
+ * @out_offset: Output storage for offset, or NULL
|
||||
+ * @out_size: Output storage for size, or NULL
|
||||
+ *
|
||||
+ * This prepares a slice to be published to user-space.
|
||||
+ *
|
||||
+ * This call combines the following operations:
|
||||
+ * * the memory region is flushed so the user's memory view is consistent
|
||||
+ * * the slice is marked as referenced by user-space, so user-space has to
|
||||
+ * call KDBUS_CMD_FREE to release it
|
||||
+ * * the offset and size of the slice are written to the given output
|
||||
+ * arguments, if non-NULL
|
||||
+ */
|
||||
+void kdbus_pool_slice_publish(struct kdbus_pool_slice *slice,
|
||||
+ u64 *out_offset, u64 *out_size)
|
||||
+{
|
||||
+ mutex_lock(&slice->pool->lock);
|
||||
+ /* kernel must own a ref to @slice to gain a user-space ref */
|
||||
+ WARN_ON(!slice->ref_kernel);
|
||||
+ slice->ref_user = true;
|
||||
+ mutex_unlock(&slice->pool->lock);
|
||||
+
|
||||
+ if (out_offset)
|
||||
+ *out_offset = slice->off;
|
||||
+ if (out_size)
|
||||
+ *out_size = slice->size;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_pool_slice_offset() - Get a slice's offset inside the pool
|
||||
+ * @slice: Slice to return the offset of
|
||||
+ *
|
||||
+ * Return: The internal offset @slice inside the pool.
|
||||
+ */
|
||||
+off_t kdbus_pool_slice_offset(const struct kdbus_pool_slice *slice)
|
||||
+{
|
||||
+ return slice->off;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_pool_slice_size() - get size of a pool slice
|
||||
+ * @slice: slice to query
|
||||
+ *
|
||||
+ * Return: size of the given slice
|
||||
+ */
|
||||
+size_t kdbus_pool_slice_size(const struct kdbus_pool_slice *slice)
|
||||
+{
|
||||
+ return slice->size;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_pool_new() - create a new pool
|
||||
+ * @name: Name of the (deleted) file which shows up in
|
||||
+ * /proc, used for debugging
|
||||
+ * @size: Maximum size of the pool
|
||||
+ *
|
||||
+ * Return: a new kdbus_pool on success, ERR_PTR on failure.
|
||||
+ */
|
||||
+struct kdbus_pool *kdbus_pool_new(const char *name, size_t size)
|
||||
+{
|
||||
+ struct kdbus_pool_slice *s;
|
||||
+ struct kdbus_pool *p;
|
||||
+ struct file *f;
|
||||
+ char *n = NULL;
|
||||
+ int ret;
|
||||
+
|
||||
+ p = kzalloc(sizeof(*p), GFP_KERNEL);
|
||||
+ if (!p)
|
||||
+ return ERR_PTR(-ENOMEM);
|
||||
+
|
||||
+ if (name) {
|
||||
+ n = kasprintf(GFP_KERNEL, KBUILD_MODNAME "-conn:%s", name);
|
||||
+ if (!n) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto exit_free;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ f = shmem_file_setup(n ?: KBUILD_MODNAME "-conn", size, 0);
|
||||
+ kfree(n);
|
||||
+
|
||||
+ if (IS_ERR(f)) {
|
||||
+ ret = PTR_ERR(f);
|
||||
+ goto exit_free;
|
||||
+ }
|
||||
+
|
||||
+ ret = get_write_access(file_inode(f));
|
||||
+ if (ret < 0)
|
||||
+ goto exit_put_shmem;
|
||||
+
|
||||
+ /* allocate first slice spanning the entire pool */
|
||||
+ s = kdbus_pool_slice_new(p, 0, size);
|
||||
+ if (!s) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto exit_put_write;
|
||||
+ }
|
||||
+
|
||||
+ p->f = f;
|
||||
+ p->size = size;
|
||||
+ p->slices_free = RB_ROOT;
|
||||
+ p->slices_busy = RB_ROOT;
|
||||
+ mutex_init(&p->lock);
|
||||
+
|
||||
+ INIT_LIST_HEAD(&p->slices);
|
||||
+ list_add(&s->entry, &p->slices);
|
||||
+
|
||||
+ kdbus_pool_add_free_slice(p, s);
|
||||
+ return p;
|
||||
+
|
||||
+exit_put_write:
|
||||
+ put_write_access(file_inode(f));
|
||||
+exit_put_shmem:
|
||||
+ fput(f);
|
||||
+exit_free:
|
||||
+ kfree(p);
|
||||
+ return ERR_PTR(ret);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_pool_free() - destroy pool
|
||||
+ * @pool: The receiver's pool
|
||||
+ */
|
||||
+void kdbus_pool_free(struct kdbus_pool *pool)
|
||||
+{
|
||||
+ struct kdbus_pool_slice *s, *tmp;
|
||||
+
|
||||
+ if (!pool)
|
||||
+ return;
|
||||
+
|
||||
+ list_for_each_entry_safe(s, tmp, &pool->slices, entry) {
|
||||
+ list_del(&s->entry);
|
||||
+ kfree(s);
|
||||
+ }
|
||||
+
|
||||
+ put_write_access(file_inode(pool->f));
|
||||
+ fput(pool->f);
|
||||
+ kfree(pool);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_pool_accounted() - retrieve accounting information
|
||||
+ * @pool: pool to query
|
||||
+ * @size: output for overall pool size
|
||||
+ * @acc: output for currently accounted size
|
||||
+ *
|
||||
+ * This returns accounting information of the pool. Note that the data might
|
||||
+ * change after the function returns, as the pool lock is dropped. You need to
|
||||
+ * protect the data via other means, if you need reliable accounting.
|
||||
+ */
|
||||
+void kdbus_pool_accounted(struct kdbus_pool *pool, size_t *size, size_t *acc)
|
||||
+{
|
||||
+ mutex_lock(&pool->lock);
|
||||
+ if (size)
|
||||
+ *size = pool->size;
|
||||
+ if (acc)
|
||||
+ *acc = pool->accounted_size;
|
||||
+ mutex_unlock(&pool->lock);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_pool_slice_copy_iovec() - copy user memory to a slice
|
||||
+ * @slice: The slice to write to
|
||||
+ * @off: Offset in the slice to write to
|
||||
+ * @iov: iovec array, pointing to data to copy
|
||||
+ * @iov_len: Number of elements in @iov
|
||||
+ * @total_len: Total number of bytes described in members of @iov
|
||||
+ *
|
||||
+ * User memory referenced by @iov will be copied into @slice at offset @off.
|
||||
+ *
|
||||
+ * Return: the numbers of bytes copied, negative errno on failure.
|
||||
+ */
|
||||
+ssize_t
|
||||
+kdbus_pool_slice_copy_iovec(const struct kdbus_pool_slice *slice, loff_t off,
|
||||
+ struct iovec *iov, size_t iov_len, size_t total_len)
|
||||
+{
|
||||
+ struct iov_iter iter;
|
||||
+ ssize_t len;
|
||||
+
|
||||
+ if (WARN_ON(off + total_len > slice->size))
|
||||
+ return -EFAULT;
|
||||
+
|
||||
+ off += slice->off;
|
||||
+ iov_iter_init(&iter, WRITE, iov, iov_len, total_len);
|
||||
+ len = vfs_iter_write(slice->pool->f, &iter, &off);
|
||||
+
|
||||
+ return (len >= 0 && len != total_len) ? -EFAULT : len;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_pool_slice_copy_kvec() - copy kernel memory to a slice
|
||||
+ * @slice: The slice to write to
|
||||
+ * @off: Offset in the slice to write to
|
||||
+ * @kvec: kvec array, pointing to data to copy
|
||||
+ * @kvec_len: Number of elements in @kvec
|
||||
+ * @total_len: Total number of bytes described in members of @kvec
|
||||
+ *
|
||||
+ * Kernel memory referenced by @kvec will be copied into @slice at offset @off.
|
||||
+ *
|
||||
+ * Return: the numbers of bytes copied, negative errno on failure.
|
||||
+ */
|
||||
+ssize_t kdbus_pool_slice_copy_kvec(const struct kdbus_pool_slice *slice,
|
||||
+ loff_t off, struct kvec *kvec,
|
||||
+ size_t kvec_len, size_t total_len)
|
||||
+{
|
||||
+ struct iov_iter iter;
|
||||
+ mm_segment_t old_fs;
|
||||
+ ssize_t len;
|
||||
+
|
||||
+ if (WARN_ON(off + total_len > slice->size))
|
||||
+ return -EFAULT;
|
||||
+
|
||||
+ off += slice->off;
|
||||
+ iov_iter_kvec(&iter, WRITE | ITER_KVEC, kvec, kvec_len, total_len);
|
||||
+
|
||||
+ old_fs = get_fs();
|
||||
+ set_fs(get_ds());
|
||||
+ len = vfs_iter_write(slice->pool->f, &iter, &off);
|
||||
+ set_fs(old_fs);
|
||||
+
|
||||
+ return (len >= 0 && len != total_len) ? -EFAULT : len;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_pool_slice_copy() - copy data from one slice into another
|
||||
+ * @slice_dst: destination slice
|
||||
+ * @slice_src: source slice
|
||||
+ *
|
||||
+ * Return: 0 on success, negative error number on failure.
|
||||
+ */
|
||||
+int kdbus_pool_slice_copy(const struct kdbus_pool_slice *slice_dst,
|
||||
+ const struct kdbus_pool_slice *slice_src)
|
||||
+{
|
||||
+ struct file *f_src = slice_src->pool->f;
|
||||
+ struct file *f_dst = slice_dst->pool->f;
|
||||
+ struct inode *i_dst = file_inode(f_dst);
|
||||
+ struct address_space *mapping_dst = f_dst->f_mapping;
|
||||
+ const struct address_space_operations *aops = mapping_dst->a_ops;
|
||||
+ unsigned long len = slice_src->size;
|
||||
+ loff_t off_src = slice_src->off;
|
||||
+ loff_t off_dst = slice_dst->off;
|
||||
+ mm_segment_t old_fs;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if (WARN_ON(slice_src->size != slice_dst->size) ||
|
||||
+ WARN_ON(slice_src->free || slice_dst->free))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ mutex_lock(&i_dst->i_mutex);
|
||||
+ old_fs = get_fs();
|
||||
+ set_fs(get_ds());
|
||||
+ while (len > 0) {
|
||||
+ unsigned long page_off;
|
||||
+ unsigned long copy_len;
|
||||
+ char __user *kaddr;
|
||||
+ struct page *page;
|
||||
+ ssize_t n_read;
|
||||
+ void *fsdata;
|
||||
+ long status;
|
||||
+
|
||||
+ page_off = off_dst & (PAGE_CACHE_SIZE - 1);
|
||||
+ copy_len = min_t(unsigned long,
|
||||
+ PAGE_CACHE_SIZE - page_off, len);
|
||||
+
|
||||
+ status = aops->write_begin(f_dst, mapping_dst, off_dst,
|
||||
+ copy_len, 0, &page, &fsdata);
|
||||
+ if (unlikely(status < 0)) {
|
||||
+ ret = status;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ kaddr = (char __force __user *)kmap(page) + page_off;
|
||||
+ n_read = f_src->f_op->read(f_src, kaddr, copy_len, &off_src);
|
||||
+ kunmap(page);
|
||||
+ mark_page_accessed(page);
|
||||
+ flush_dcache_page(page);
|
||||
+
|
||||
+ if (unlikely(n_read != copy_len)) {
|
||||
+ ret = -EFAULT;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ status = aops->write_end(f_dst, mapping_dst, off_dst,
|
||||
+ copy_len, copy_len, page, fsdata);
|
||||
+ if (unlikely(status != copy_len)) {
|
||||
+ ret = -EFAULT;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ off_dst += copy_len;
|
||||
+ len -= copy_len;
|
||||
+ }
|
||||
+ set_fs(old_fs);
|
||||
+ mutex_unlock(&i_dst->i_mutex);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_pool_mmap() - map the pool into the process
|
||||
+ * @pool: The receiver's pool
|
||||
+ * @vma: passed by mmap() syscall
|
||||
+ *
|
||||
+ * Return: the result of the mmap() call, negative errno on failure.
|
||||
+ */
|
||||
+int kdbus_pool_mmap(const struct kdbus_pool *pool, struct vm_area_struct *vma)
|
||||
+{
|
||||
+ /* deny write access to the pool */
|
||||
+ if (vma->vm_flags & VM_WRITE)
|
||||
+ return -EPERM;
|
||||
+ vma->vm_flags &= ~VM_MAYWRITE;
|
||||
+
|
||||
+ /* do not allow to map more than the size of the file */
|
||||
+ if ((vma->vm_end - vma->vm_start) > pool->size)
|
||||
+ return -EFAULT;
|
||||
+
|
||||
+ /* replace the connection file with our shmem file */
|
||||
+ if (vma->vm_file)
|
||||
+ fput(vma->vm_file);
|
||||
+ vma->vm_file = get_file(pool->f);
|
||||
+
|
||||
+ return pool->f->f_op->mmap(pool->f, vma);
|
||||
+}
|
||||
diff --git a/ipc/kdbus/pool.h b/ipc/kdbus/pool.h
|
||||
new file mode 100644
|
||||
index 000000000000..a9038213aa4d
|
||||
--- /dev/null
|
||||
+++ b/ipc/kdbus/pool.h
|
||||
@@ -0,0 +1,46 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2013-2015 Kay Sievers
|
||||
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
|
||||
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
|
||||
+ * Copyright (C) 2013-2015 Linux Foundation
|
||||
+ * Copyright (C) 2014-2015 Djalal Harouni <tixxdz@opendz.org>
|
||||
+ *
|
||||
+ * kdbus is free software; you can redistribute it and/or modify it under
|
||||
+ * the terms of the GNU Lesser General Public License as published by the
|
||||
+ * Free Software Foundation; either version 2.1 of the License, or (at
|
||||
+ * your option) any later version.
|
||||
+ */
|
||||
+
|
||||
+#ifndef __KDBUS_POOL_H
|
||||
+#define __KDBUS_POOL_H
|
||||
+
|
||||
+#include <linux/uio.h>
|
||||
+
|
||||
+struct kdbus_pool;
|
||||
+struct kdbus_pool_slice;
|
||||
+
|
||||
+struct kdbus_pool *kdbus_pool_new(const char *name, size_t size);
|
||||
+void kdbus_pool_free(struct kdbus_pool *pool);
|
||||
+void kdbus_pool_accounted(struct kdbus_pool *pool, size_t *size, size_t *acc);
|
||||
+int kdbus_pool_mmap(const struct kdbus_pool *pool, struct vm_area_struct *vma);
|
||||
+int kdbus_pool_release_offset(struct kdbus_pool *pool, size_t off);
|
||||
+void kdbus_pool_publish_empty(struct kdbus_pool *pool, u64 *off, u64 *size);
|
||||
+
|
||||
+struct kdbus_pool_slice *kdbus_pool_slice_alloc(struct kdbus_pool *pool,
|
||||
+ size_t size, bool accounted);
|
||||
+void kdbus_pool_slice_release(struct kdbus_pool_slice *slice);
|
||||
+void kdbus_pool_slice_publish(struct kdbus_pool_slice *slice,
|
||||
+ u64 *out_offset, u64 *out_size);
|
||||
+off_t kdbus_pool_slice_offset(const struct kdbus_pool_slice *slice);
|
||||
+size_t kdbus_pool_slice_size(const struct kdbus_pool_slice *slice);
|
||||
+int kdbus_pool_slice_copy(const struct kdbus_pool_slice *slice_dst,
|
||||
+ const struct kdbus_pool_slice *slice_src);
|
||||
+ssize_t kdbus_pool_slice_copy_kvec(const struct kdbus_pool_slice *slice,
|
||||
+ loff_t off, struct kvec *kvec,
|
||||
+ size_t kvec_count, size_t total_len);
|
||||
+ssize_t kdbus_pool_slice_copy_iovec(const struct kdbus_pool_slice *slice,
|
||||
+ loff_t off, struct iovec *iov,
|
||||
+ size_t iov_count, size_t total_len);
|
||||
+
|
||||
+#endif
|
4834
kdbus-add-connection-queue-handling-and-message-vali.patch
Normal file
4834
kdbus-add-connection-queue-handling-and-message-vali.patch
Normal file
File diff suppressed because it is too large
Load Diff
7488
kdbus-add-documentation.patch
Normal file
7488
kdbus-add-documentation.patch
Normal file
File diff suppressed because it is too large
Load Diff
1253
kdbus-add-driver-skeleton-ioctl-entry-points-and-uti.patch
Normal file
1253
kdbus-add-driver-skeleton-ioctl-entry-points-and-uti.patch
Normal file
File diff suppressed because it is too large
Load Diff
883
kdbus-add-name-registry-implementation.patch
Normal file
883
kdbus-add-name-registry-implementation.patch
Normal file
@ -0,0 +1,883 @@
|
||||
From: Daniel Mack <daniel@zonque.org>
|
||||
Date: Thu, 11 Sep 2014 19:00:00 +0200
|
||||
Subject: [PATCH] kdbus: add name registry implementation
|
||||
|
||||
This patch adds the name registry implementation.
|
||||
|
||||
Each bus instantiates a name registry to resolve well-known names
|
||||
into unique connection IDs for message delivery. The registry will
|
||||
be queried when a message is sent with kdbus_msg.dst_id set to
|
||||
KDBUS_DST_ID_NAME, or when a registry dump is requested.
|
||||
|
||||
It's important to have this registry implemented in the kernel to
|
||||
implement lookups and take-overs in a race-free way.
|
||||
|
||||
Signed-off-by: Daniel Mack <daniel@zonque.org>
|
||||
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Signed-off-by: Djalal Harouni <tixxdz@opendz.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
ipc/kdbus/names.c | 772 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
ipc/kdbus/names.h | 74 ++++++
|
||||
2 files changed, 846 insertions(+)
|
||||
create mode 100644 ipc/kdbus/names.c
|
||||
create mode 100644 ipc/kdbus/names.h
|
||||
|
||||
diff --git a/ipc/kdbus/names.c b/ipc/kdbus/names.c
|
||||
new file mode 100644
|
||||
index 000000000000..657008e1bb37
|
||||
--- /dev/null
|
||||
+++ b/ipc/kdbus/names.c
|
||||
@@ -0,0 +1,772 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2013-2015 Kay Sievers
|
||||
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
|
||||
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
|
||||
+ * Copyright (C) 2013-2015 Linux Foundation
|
||||
+ * Copyright (C) 2014-2015 Djalal Harouni <tixxdz@opendz.org>
|
||||
+ *
|
||||
+ * kdbus is free software; you can redistribute it and/or modify it under
|
||||
+ * the terms of the GNU Lesser General Public License as published by the
|
||||
+ * Free Software Foundation; either version 2.1 of the License, or (at
|
||||
+ * your option) any later version.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/ctype.h>
|
||||
+#include <linux/fs.h>
|
||||
+#include <linux/hash.h>
|
||||
+#include <linux/idr.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/mutex.h>
|
||||
+#include <linux/rwsem.h>
|
||||
+#include <linux/sched.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/uaccess.h>
|
||||
+#include <linux/uio.h>
|
||||
+
|
||||
+#include "bus.h"
|
||||
+#include "connection.h"
|
||||
+#include "endpoint.h"
|
||||
+#include "handle.h"
|
||||
+#include "item.h"
|
||||
+#include "names.h"
|
||||
+#include "notify.h"
|
||||
+#include "policy.h"
|
||||
+
|
||||
+struct kdbus_name_pending {
|
||||
+ u64 flags;
|
||||
+ struct kdbus_conn *conn;
|
||||
+ struct kdbus_name_entry *name;
|
||||
+ struct list_head conn_entry;
|
||||
+ struct list_head name_entry;
|
||||
+};
|
||||
+
|
||||
+static int kdbus_name_pending_new(struct kdbus_name_entry *e,
|
||||
+ struct kdbus_conn *conn, u64 flags)
|
||||
+{
|
||||
+ struct kdbus_name_pending *p;
|
||||
+
|
||||
+ kdbus_conn_assert_active(conn);
|
||||
+
|
||||
+ p = kmalloc(sizeof(*p), GFP_KERNEL);
|
||||
+ if (!p)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ p->flags = flags;
|
||||
+ p->conn = conn;
|
||||
+ p->name = e;
|
||||
+ list_add_tail(&p->conn_entry, &conn->names_queue_list);
|
||||
+ list_add_tail(&p->name_entry, &e->queue);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void kdbus_name_pending_free(struct kdbus_name_pending *p)
|
||||
+{
|
||||
+ if (!p)
|
||||
+ return;
|
||||
+
|
||||
+ list_del(&p->name_entry);
|
||||
+ list_del(&p->conn_entry);
|
||||
+ kfree(p);
|
||||
+}
|
||||
+
|
||||
+static struct kdbus_name_entry *
|
||||
+kdbus_name_entry_new(struct kdbus_name_registry *r, u32 hash, const char *name)
|
||||
+{
|
||||
+ struct kdbus_name_entry *e;
|
||||
+ size_t namelen;
|
||||
+
|
||||
+ namelen = strlen(name);
|
||||
+
|
||||
+ e = kmalloc(sizeof(*e) + namelen + 1, GFP_KERNEL);
|
||||
+ if (!e)
|
||||
+ return ERR_PTR(-ENOMEM);
|
||||
+
|
||||
+ e->name_id = ++r->name_seq_last;
|
||||
+ e->flags = 0;
|
||||
+ e->conn = NULL;
|
||||
+ e->activator = NULL;
|
||||
+ INIT_LIST_HEAD(&e->queue);
|
||||
+ INIT_LIST_HEAD(&e->conn_entry);
|
||||
+ hash_add(r->entries_hash, &e->hentry, hash);
|
||||
+ memcpy(e->name, name, namelen + 1);
|
||||
+
|
||||
+ return e;
|
||||
+}
|
||||
+
|
||||
+static void kdbus_name_entry_free(struct kdbus_name_entry *e)
|
||||
+{
|
||||
+ if (!e)
|
||||
+ return;
|
||||
+
|
||||
+ WARN_ON(!list_empty(&e->conn_entry));
|
||||
+ WARN_ON(!list_empty(&e->queue));
|
||||
+ WARN_ON(e->activator);
|
||||
+ WARN_ON(e->conn);
|
||||
+
|
||||
+ hash_del(&e->hentry);
|
||||
+ kfree(e);
|
||||
+}
|
||||
+
|
||||
+static void kdbus_name_entry_set_owner(struct kdbus_name_entry *e,
|
||||
+ struct kdbus_conn *conn, u64 flags)
|
||||
+{
|
||||
+ WARN_ON(e->conn);
|
||||
+
|
||||
+ e->conn = kdbus_conn_ref(conn);
|
||||
+ e->flags = flags;
|
||||
+ atomic_inc(&conn->name_count);
|
||||
+ list_add_tail(&e->conn_entry, &e->conn->names_list);
|
||||
+}
|
||||
+
|
||||
+static void kdbus_name_entry_remove_owner(struct kdbus_name_entry *e)
|
||||
+{
|
||||
+ WARN_ON(!e->conn);
|
||||
+
|
||||
+ list_del_init(&e->conn_entry);
|
||||
+ atomic_dec(&e->conn->name_count);
|
||||
+ e->flags = 0;
|
||||
+ e->conn = kdbus_conn_unref(e->conn);
|
||||
+}
|
||||
+
|
||||
+static void kdbus_name_entry_replace_owner(struct kdbus_name_entry *e,
|
||||
+ struct kdbus_conn *conn, u64 flags)
|
||||
+{
|
||||
+ if (WARN_ON(!e->conn) || WARN_ON(conn == e->conn))
|
||||
+ return;
|
||||
+
|
||||
+ kdbus_notify_name_change(conn->ep->bus, KDBUS_ITEM_NAME_CHANGE,
|
||||
+ e->conn->id, conn->id,
|
||||
+ e->flags, flags, e->name);
|
||||
+ kdbus_name_entry_remove_owner(e);
|
||||
+ kdbus_name_entry_set_owner(e, conn, flags);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_name_is_valid() - check if a name is valid
|
||||
+ * @p: The name to check
|
||||
+ * @allow_wildcard: Whether or not to allow a wildcard name
|
||||
+ *
|
||||
+ * A name is valid if all of the following criterias are met:
|
||||
+ *
|
||||
+ * - The name has two or more elements separated by a period ('.') character.
|
||||
+ * - All elements must contain at least one character.
|
||||
+ * - Each element must only contain the ASCII characters "[A-Z][a-z][0-9]_-"
|
||||
+ * and must not begin with a digit.
|
||||
+ * - The name must not exceed KDBUS_NAME_MAX_LEN.
|
||||
+ * - If @allow_wildcard is true, the name may end on '.*'
|
||||
+ */
|
||||
+bool kdbus_name_is_valid(const char *p, bool allow_wildcard)
|
||||
+{
|
||||
+ bool dot, found_dot = false;
|
||||
+ const char *q;
|
||||
+
|
||||
+ for (dot = true, q = p; *q; q++) {
|
||||
+ if (*q == '.') {
|
||||
+ if (dot)
|
||||
+ return false;
|
||||
+
|
||||
+ found_dot = true;
|
||||
+ dot = true;
|
||||
+ } else {
|
||||
+ bool good;
|
||||
+
|
||||
+ good = isalpha(*q) || (!dot && isdigit(*q)) ||
|
||||
+ *q == '_' || *q == '-' ||
|
||||
+ (allow_wildcard && dot &&
|
||||
+ *q == '*' && *(q + 1) == '\0');
|
||||
+
|
||||
+ if (!good)
|
||||
+ return false;
|
||||
+
|
||||
+ dot = false;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (q - p > KDBUS_NAME_MAX_LEN)
|
||||
+ return false;
|
||||
+
|
||||
+ if (dot)
|
||||
+ return false;
|
||||
+
|
||||
+ if (!found_dot)
|
||||
+ return false;
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_name_registry_new() - create a new name registry
|
||||
+ *
|
||||
+ * Return: a new kdbus_name_registry on success, ERR_PTR on failure.
|
||||
+ */
|
||||
+struct kdbus_name_registry *kdbus_name_registry_new(void)
|
||||
+{
|
||||
+ struct kdbus_name_registry *r;
|
||||
+
|
||||
+ r = kmalloc(sizeof(*r), GFP_KERNEL);
|
||||
+ if (!r)
|
||||
+ return ERR_PTR(-ENOMEM);
|
||||
+
|
||||
+ hash_init(r->entries_hash);
|
||||
+ init_rwsem(&r->rwlock);
|
||||
+ r->name_seq_last = 0;
|
||||
+
|
||||
+ return r;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_name_registry_free() - drop a name reg's reference
|
||||
+ * @reg: The name registry, may be %NULL
|
||||
+ *
|
||||
+ * Cleanup the name registry's internal structures.
|
||||
+ */
|
||||
+void kdbus_name_registry_free(struct kdbus_name_registry *reg)
|
||||
+{
|
||||
+ if (!reg)
|
||||
+ return;
|
||||
+
|
||||
+ WARN_ON(!hash_empty(reg->entries_hash));
|
||||
+ kfree(reg);
|
||||
+}
|
||||
+
|
||||
+static struct kdbus_name_entry *
|
||||
+kdbus_name_find(struct kdbus_name_registry *reg, u32 hash, const char *name)
|
||||
+{
|
||||
+ struct kdbus_name_entry *e;
|
||||
+
|
||||
+ lockdep_assert_held(®->rwlock);
|
||||
+
|
||||
+ hash_for_each_possible(reg->entries_hash, e, hentry, hash)
|
||||
+ if (strcmp(e->name, name) == 0)
|
||||
+ return e;
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_name_lookup_unlocked() - lookup name in registry
|
||||
+ * @reg: name registry
|
||||
+ * @name: name to lookup
|
||||
+ *
|
||||
+ * This looks up @name in the given name-registry and returns the
|
||||
+ * kdbus_name_entry object. The caller must hold the registry-lock and must not
|
||||
+ * access the returned object after releasing the lock.
|
||||
+ *
|
||||
+ * Return: Pointer to name-entry, or NULL if not found.
|
||||
+ */
|
||||
+struct kdbus_name_entry *
|
||||
+kdbus_name_lookup_unlocked(struct kdbus_name_registry *reg, const char *name)
|
||||
+{
|
||||
+ return kdbus_name_find(reg, kdbus_strhash(name), name);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_name_acquire() - acquire a name
|
||||
+ * @reg: The name registry
|
||||
+ * @conn: The connection to pin this entry to
|
||||
+ * @name: The name to acquire
|
||||
+ * @flags: Acquisition flags (KDBUS_NAME_*)
|
||||
+ * @return_flags: Pointer to return flags for the acquired name
|
||||
+ * (KDBUS_NAME_*), may be %NULL
|
||||
+ *
|
||||
+ * Callers must ensure that @conn is either a privileged bus user or has
|
||||
+ * sufficient privileges in the policy-db to own the well-known name @name.
|
||||
+ *
|
||||
+ * Return: 0 success, negative error number on failure.
|
||||
+ */
|
||||
+int kdbus_name_acquire(struct kdbus_name_registry *reg,
|
||||
+ struct kdbus_conn *conn, const char *name,
|
||||
+ u64 flags, u64 *return_flags)
|
||||
+{
|
||||
+ struct kdbus_name_entry *e;
|
||||
+ u64 rflags = 0;
|
||||
+ int ret = 0;
|
||||
+ u32 hash;
|
||||
+
|
||||
+ kdbus_conn_assert_active(conn);
|
||||
+
|
||||
+ down_write(®->rwlock);
|
||||
+
|
||||
+ if (!kdbus_conn_policy_own_name(conn, current_cred(), name)) {
|
||||
+ ret = -EPERM;
|
||||
+ goto exit_unlock;
|
||||
+ }
|
||||
+
|
||||
+ hash = kdbus_strhash(name);
|
||||
+ e = kdbus_name_find(reg, hash, name);
|
||||
+ if (!e) {
|
||||
+ /* claim new name */
|
||||
+
|
||||
+ if (conn->activator_of) {
|
||||
+ ret = -EINVAL;
|
||||
+ goto exit_unlock;
|
||||
+ }
|
||||
+
|
||||
+ e = kdbus_name_entry_new(reg, hash, name);
|
||||
+ if (IS_ERR(e)) {
|
||||
+ ret = PTR_ERR(e);
|
||||
+ goto exit_unlock;
|
||||
+ }
|
||||
+
|
||||
+ if (kdbus_conn_is_activator(conn)) {
|
||||
+ e->activator = kdbus_conn_ref(conn);
|
||||
+ conn->activator_of = e;
|
||||
+ }
|
||||
+
|
||||
+ kdbus_name_entry_set_owner(e, conn, flags);
|
||||
+ kdbus_notify_name_change(e->conn->ep->bus, KDBUS_ITEM_NAME_ADD,
|
||||
+ 0, e->conn->id, 0, e->flags, e->name);
|
||||
+ } else if (e->conn == conn || e == conn->activator_of) {
|
||||
+ /* connection already owns that name */
|
||||
+ ret = -EALREADY;
|
||||
+ } else if (kdbus_conn_is_activator(conn)) {
|
||||
+ /* activator claims existing name */
|
||||
+
|
||||
+ if (conn->activator_of) {
|
||||
+ ret = -EINVAL; /* multiple names not allowed */
|
||||
+ } else if (e->activator) {
|
||||
+ ret = -EEXIST; /* only one activator per name */
|
||||
+ } else {
|
||||
+ e->activator = kdbus_conn_ref(conn);
|
||||
+ conn->activator_of = e;
|
||||
+ }
|
||||
+ } else if (e->flags & KDBUS_NAME_ACTIVATOR) {
|
||||
+ /* claim name of an activator */
|
||||
+
|
||||
+ kdbus_conn_move_messages(conn, e->activator, 0);
|
||||
+ kdbus_name_entry_replace_owner(e, conn, flags);
|
||||
+ } else if ((flags & KDBUS_NAME_REPLACE_EXISTING) &&
|
||||
+ (e->flags & KDBUS_NAME_ALLOW_REPLACEMENT)) {
|
||||
+ /* claim name of a previous owner */
|
||||
+
|
||||
+ if (e->flags & KDBUS_NAME_QUEUE) {
|
||||
+ /* move owner back to queue if they asked for it */
|
||||
+ ret = kdbus_name_pending_new(e, e->conn, e->flags);
|
||||
+ if (ret < 0)
|
||||
+ goto exit_unlock;
|
||||
+ }
|
||||
+
|
||||
+ kdbus_name_entry_replace_owner(e, conn, flags);
|
||||
+ } else if (flags & KDBUS_NAME_QUEUE) {
|
||||
+ /* add to waiting-queue of the name */
|
||||
+
|
||||
+ ret = kdbus_name_pending_new(e, conn, flags);
|
||||
+ if (ret >= 0)
|
||||
+ /* tell the caller that we queued it */
|
||||
+ rflags |= KDBUS_NAME_IN_QUEUE;
|
||||
+ } else {
|
||||
+ /* the name is busy, return a failure */
|
||||
+ ret = -EEXIST;
|
||||
+ }
|
||||
+
|
||||
+ if (ret == 0 && return_flags)
|
||||
+ *return_flags = rflags;
|
||||
+
|
||||
+exit_unlock:
|
||||
+ up_write(®->rwlock);
|
||||
+ kdbus_notify_flush(conn->ep->bus);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void kdbus_name_release_unlocked(struct kdbus_name_registry *reg,
|
||||
+ struct kdbus_name_entry *e)
|
||||
+{
|
||||
+ struct kdbus_name_pending *p;
|
||||
+
|
||||
+ lockdep_assert_held(®->rwlock);
|
||||
+
|
||||
+ p = list_first_entry_or_null(&e->queue, struct kdbus_name_pending,
|
||||
+ name_entry);
|
||||
+
|
||||
+ if (p) {
|
||||
+ /* give it to first active waiter in the queue */
|
||||
+ kdbus_name_entry_replace_owner(e, p->conn, p->flags);
|
||||
+ kdbus_name_pending_free(p);
|
||||
+ } else if (e->activator && e->activator != e->conn) {
|
||||
+ /* hand it back to an active activator connection */
|
||||
+ kdbus_conn_move_messages(e->activator, e->conn, e->name_id);
|
||||
+ kdbus_name_entry_replace_owner(e, e->activator,
|
||||
+ KDBUS_NAME_ACTIVATOR);
|
||||
+ } else {
|
||||
+ /* release the name */
|
||||
+ kdbus_notify_name_change(e->conn->ep->bus,
|
||||
+ KDBUS_ITEM_NAME_REMOVE,
|
||||
+ e->conn->id, 0, e->flags, 0, e->name);
|
||||
+ kdbus_name_entry_remove_owner(e);
|
||||
+ kdbus_name_entry_free(e);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int kdbus_name_release(struct kdbus_name_registry *reg,
|
||||
+ struct kdbus_conn *conn,
|
||||
+ const char *name)
|
||||
+{
|
||||
+ struct kdbus_name_pending *p;
|
||||
+ struct kdbus_name_entry *e;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ down_write(®->rwlock);
|
||||
+ e = kdbus_name_find(reg, kdbus_strhash(name), name);
|
||||
+ if (!e) {
|
||||
+ ret = -ESRCH;
|
||||
+ } else if (e->conn == conn) {
|
||||
+ kdbus_name_release_unlocked(reg, e);
|
||||
+ } else {
|
||||
+ ret = -EADDRINUSE;
|
||||
+ list_for_each_entry(p, &e->queue, name_entry) {
|
||||
+ if (p->conn == conn) {
|
||||
+ kdbus_name_pending_free(p);
|
||||
+ ret = 0;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ up_write(®->rwlock);
|
||||
+
|
||||
+ kdbus_notify_flush(conn->ep->bus);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_name_release_all() - remove all name entries of a given connection
|
||||
+ * @reg: name registry
|
||||
+ * @conn: connection
|
||||
+ */
|
||||
+void kdbus_name_release_all(struct kdbus_name_registry *reg,
|
||||
+ struct kdbus_conn *conn)
|
||||
+{
|
||||
+ struct kdbus_name_pending *p;
|
||||
+ struct kdbus_conn *activator = NULL;
|
||||
+ struct kdbus_name_entry *e;
|
||||
+
|
||||
+ down_write(®->rwlock);
|
||||
+
|
||||
+ if (kdbus_conn_is_activator(conn)) {
|
||||
+ activator = conn->activator_of->activator;
|
||||
+ conn->activator_of->activator = NULL;
|
||||
+ }
|
||||
+
|
||||
+ while ((p = list_first_entry_or_null(&conn->names_queue_list,
|
||||
+ struct kdbus_name_pending,
|
||||
+ conn_entry)))
|
||||
+ kdbus_name_pending_free(p);
|
||||
+ while ((e = list_first_entry_or_null(&conn->names_list,
|
||||
+ struct kdbus_name_entry,
|
||||
+ conn_entry)))
|
||||
+ kdbus_name_release_unlocked(reg, e);
|
||||
+
|
||||
+ up_write(®->rwlock);
|
||||
+
|
||||
+ kdbus_conn_unref(activator);
|
||||
+ kdbus_notify_flush(conn->ep->bus);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_cmd_name_acquire() - handle KDBUS_CMD_NAME_ACQUIRE
|
||||
+ * @conn: connection to operate on
|
||||
+ * @argp: command payload
|
||||
+ *
|
||||
+ * Return: 0 on success, negative error code on failure.
|
||||
+ */
|
||||
+int kdbus_cmd_name_acquire(struct kdbus_conn *conn, void __user *argp)
|
||||
+{
|
||||
+ const char *item_name;
|
||||
+ struct kdbus_cmd *cmd;
|
||||
+ int ret;
|
||||
+
|
||||
+ struct kdbus_arg argv[] = {
|
||||
+ { .type = KDBUS_ITEM_NEGOTIATE },
|
||||
+ { .type = KDBUS_ITEM_NAME, .mandatory = true },
|
||||
+ };
|
||||
+ struct kdbus_args args = {
|
||||
+ .allowed_flags = KDBUS_FLAG_NEGOTIATE |
|
||||
+ KDBUS_NAME_REPLACE_EXISTING |
|
||||
+ KDBUS_NAME_ALLOW_REPLACEMENT |
|
||||
+ KDBUS_NAME_QUEUE,
|
||||
+ .argv = argv,
|
||||
+ .argc = ARRAY_SIZE(argv),
|
||||
+ };
|
||||
+
|
||||
+ if (!kdbus_conn_is_ordinary(conn))
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ ret = kdbus_args_parse(&args, argp, &cmd);
|
||||
+ if (ret != 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ item_name = argv[1].item->str;
|
||||
+ if (!kdbus_name_is_valid(item_name, false)) {
|
||||
+ ret = -EINVAL;
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Do atomic_inc_return here to reserve our slot, then decrement
|
||||
+ * it before returning.
|
||||
+ */
|
||||
+ if (atomic_inc_return(&conn->name_count) > KDBUS_CONN_MAX_NAMES) {
|
||||
+ ret = -E2BIG;
|
||||
+ goto exit_dec;
|
||||
+ }
|
||||
+
|
||||
+ ret = kdbus_name_acquire(conn->ep->bus->name_registry, conn, item_name,
|
||||
+ cmd->flags, &cmd->return_flags);
|
||||
+ if (ret < 0)
|
||||
+ goto exit_dec;
|
||||
+
|
||||
+exit_dec:
|
||||
+ atomic_dec(&conn->name_count);
|
||||
+exit:
|
||||
+ return kdbus_args_clear(&args, ret);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_cmd_name_release() - handle KDBUS_CMD_NAME_RELEASE
|
||||
+ * @conn: connection to operate on
|
||||
+ * @argp: command payload
|
||||
+ *
|
||||
+ * Return: 0 on success, negative error code on failure.
|
||||
+ */
|
||||
+int kdbus_cmd_name_release(struct kdbus_conn *conn, void __user *argp)
|
||||
+{
|
||||
+ struct kdbus_cmd *cmd;
|
||||
+ int ret;
|
||||
+
|
||||
+ struct kdbus_arg argv[] = {
|
||||
+ { .type = KDBUS_ITEM_NEGOTIATE },
|
||||
+ { .type = KDBUS_ITEM_NAME, .mandatory = true },
|
||||
+ };
|
||||
+ struct kdbus_args args = {
|
||||
+ .allowed_flags = KDBUS_FLAG_NEGOTIATE,
|
||||
+ .argv = argv,
|
||||
+ .argc = ARRAY_SIZE(argv),
|
||||
+ };
|
||||
+
|
||||
+ if (!kdbus_conn_is_ordinary(conn))
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ ret = kdbus_args_parse(&args, argp, &cmd);
|
||||
+ if (ret != 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = kdbus_name_release(conn->ep->bus->name_registry, conn,
|
||||
+ argv[1].item->str);
|
||||
+ return kdbus_args_clear(&args, ret);
|
||||
+}
|
||||
+
|
||||
+static int kdbus_list_write(struct kdbus_conn *conn,
|
||||
+ struct kdbus_conn *c,
|
||||
+ struct kdbus_pool_slice *slice,
|
||||
+ size_t *pos,
|
||||
+ struct kdbus_name_entry *e,
|
||||
+ bool write)
|
||||
+{
|
||||
+ struct kvec kvec[4];
|
||||
+ size_t cnt = 0;
|
||||
+ int ret;
|
||||
+
|
||||
+ /* info header */
|
||||
+ struct kdbus_info info = {
|
||||
+ .size = 0,
|
||||
+ .id = c->id,
|
||||
+ .flags = c->flags,
|
||||
+ };
|
||||
+
|
||||
+ /* fake the header of a kdbus_name item */
|
||||
+ struct {
|
||||
+ u64 size;
|
||||
+ u64 type;
|
||||
+ u64 flags;
|
||||
+ } h = {};
|
||||
+
|
||||
+ if (e && !kdbus_conn_policy_see_name_unlocked(conn, current_cred(),
|
||||
+ e->name))
|
||||
+ return 0;
|
||||
+
|
||||
+ kdbus_kvec_set(&kvec[cnt++], &info, sizeof(info), &info.size);
|
||||
+
|
||||
+ /* append name */
|
||||
+ if (e) {
|
||||
+ size_t slen = strlen(e->name) + 1;
|
||||
+
|
||||
+ h.size = offsetof(struct kdbus_item, name.name) + slen;
|
||||
+ h.type = KDBUS_ITEM_OWNED_NAME;
|
||||
+ h.flags = e->flags;
|
||||
+
|
||||
+ kdbus_kvec_set(&kvec[cnt++], &h, sizeof(h), &info.size);
|
||||
+ kdbus_kvec_set(&kvec[cnt++], e->name, slen, &info.size);
|
||||
+ cnt += !!kdbus_kvec_pad(&kvec[cnt], &info.size);
|
||||
+ }
|
||||
+
|
||||
+ if (write) {
|
||||
+ ret = kdbus_pool_slice_copy_kvec(slice, *pos, kvec,
|
||||
+ cnt, info.size);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ *pos += info.size;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int kdbus_list_all(struct kdbus_conn *conn, u64 flags,
|
||||
+ struct kdbus_pool_slice *slice,
|
||||
+ size_t *pos, bool write)
|
||||
+{
|
||||
+ struct kdbus_conn *c;
|
||||
+ size_t p = *pos;
|
||||
+ int ret, i;
|
||||
+
|
||||
+ hash_for_each(conn->ep->bus->conn_hash, i, c, hentry) {
|
||||
+ bool added = false;
|
||||
+
|
||||
+ /* skip monitors */
|
||||
+ if (kdbus_conn_is_monitor(c))
|
||||
+ continue;
|
||||
+
|
||||
+ /* skip activators */
|
||||
+ if (!(flags & KDBUS_LIST_ACTIVATORS) &&
|
||||
+ kdbus_conn_is_activator(c))
|
||||
+ continue;
|
||||
+
|
||||
+ /* all names the connection owns */
|
||||
+ if (flags & (KDBUS_LIST_NAMES | KDBUS_LIST_ACTIVATORS)) {
|
||||
+ struct kdbus_name_entry *e;
|
||||
+
|
||||
+ list_for_each_entry(e, &c->names_list, conn_entry) {
|
||||
+ struct kdbus_conn *a = e->activator;
|
||||
+
|
||||
+ if ((flags & KDBUS_LIST_ACTIVATORS) &&
|
||||
+ a && a != c) {
|
||||
+ ret = kdbus_list_write(conn, a, slice,
|
||||
+ &p, e, write);
|
||||
+ if (ret < 0) {
|
||||
+ mutex_unlock(&c->lock);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ added = true;
|
||||
+ }
|
||||
+
|
||||
+ if (flags & KDBUS_LIST_NAMES ||
|
||||
+ kdbus_conn_is_activator(c)) {
|
||||
+ ret = kdbus_list_write(conn, c, slice,
|
||||
+ &p, e, write);
|
||||
+ if (ret < 0) {
|
||||
+ mutex_unlock(&c->lock);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ added = true;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* queue of names the connection is currently waiting for */
|
||||
+ if (flags & KDBUS_LIST_QUEUED) {
|
||||
+ struct kdbus_name_pending *q;
|
||||
+
|
||||
+ list_for_each_entry(q, &c->names_queue_list,
|
||||
+ conn_entry) {
|
||||
+ ret = kdbus_list_write(conn, c, slice, &p,
|
||||
+ q->name, write);
|
||||
+ if (ret < 0) {
|
||||
+ mutex_unlock(&c->lock);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ added = true;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* nothing added so far, just add the unique ID */
|
||||
+ if (!added && flags & KDBUS_LIST_UNIQUE) {
|
||||
+ ret = kdbus_list_write(conn, c, slice, &p, NULL, write);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ *pos = p;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_cmd_list() - handle KDBUS_CMD_LIST
|
||||
+ * @conn: connection to operate on
|
||||
+ * @argp: command payload
|
||||
+ *
|
||||
+ * Return: 0 on success, negative error code on failure.
|
||||
+ */
|
||||
+int kdbus_cmd_list(struct kdbus_conn *conn, void __user *argp)
|
||||
+{
|
||||
+ struct kdbus_name_registry *reg = conn->ep->bus->name_registry;
|
||||
+ struct kdbus_pool_slice *slice = NULL;
|
||||
+ struct kdbus_cmd_list *cmd;
|
||||
+ size_t pos, size;
|
||||
+ int ret;
|
||||
+
|
||||
+ struct kdbus_arg argv[] = {
|
||||
+ { .type = KDBUS_ITEM_NEGOTIATE },
|
||||
+ };
|
||||
+ struct kdbus_args args = {
|
||||
+ .allowed_flags = KDBUS_FLAG_NEGOTIATE |
|
||||
+ KDBUS_LIST_UNIQUE |
|
||||
+ KDBUS_LIST_NAMES |
|
||||
+ KDBUS_LIST_ACTIVATORS |
|
||||
+ KDBUS_LIST_QUEUED,
|
||||
+ .argv = argv,
|
||||
+ .argc = ARRAY_SIZE(argv),
|
||||
+ };
|
||||
+
|
||||
+ ret = kdbus_args_parse(&args, argp, &cmd);
|
||||
+ if (ret != 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* lock order: domain -> bus -> ep -> names -> conn */
|
||||
+ down_read(®->rwlock);
|
||||
+ down_read(&conn->ep->bus->conn_rwlock);
|
||||
+ down_read(&conn->ep->policy_db.entries_rwlock);
|
||||
+
|
||||
+ /* size of records */
|
||||
+ size = 0;
|
||||
+ ret = kdbus_list_all(conn, cmd->flags, NULL, &size, false);
|
||||
+ if (ret < 0)
|
||||
+ goto exit_unlock;
|
||||
+
|
||||
+ if (size == 0) {
|
||||
+ kdbus_pool_publish_empty(conn->pool, &cmd->offset,
|
||||
+ &cmd->list_size);
|
||||
+ } else {
|
||||
+ slice = kdbus_pool_slice_alloc(conn->pool, size, false);
|
||||
+ if (IS_ERR(slice)) {
|
||||
+ ret = PTR_ERR(slice);
|
||||
+ slice = NULL;
|
||||
+ goto exit_unlock;
|
||||
+ }
|
||||
+
|
||||
+ /* copy the records */
|
||||
+ pos = 0;
|
||||
+ ret = kdbus_list_all(conn, cmd->flags, slice, &pos, true);
|
||||
+ if (ret < 0)
|
||||
+ goto exit_unlock;
|
||||
+
|
||||
+ WARN_ON(pos != size);
|
||||
+ kdbus_pool_slice_publish(slice, &cmd->offset, &cmd->list_size);
|
||||
+ }
|
||||
+
|
||||
+ if (kdbus_member_set_user(&cmd->offset, argp, typeof(*cmd), offset) ||
|
||||
+ kdbus_member_set_user(&cmd->list_size, argp,
|
||||
+ typeof(*cmd), list_size))
|
||||
+ ret = -EFAULT;
|
||||
+
|
||||
+exit_unlock:
|
||||
+ up_read(&conn->ep->policy_db.entries_rwlock);
|
||||
+ up_read(&conn->ep->bus->conn_rwlock);
|
||||
+ up_read(®->rwlock);
|
||||
+ kdbus_pool_slice_release(slice);
|
||||
+ return kdbus_args_clear(&args, ret);
|
||||
+}
|
||||
diff --git a/ipc/kdbus/names.h b/ipc/kdbus/names.h
|
||||
new file mode 100644
|
||||
index 000000000000..3dd2589293e0
|
||||
--- /dev/null
|
||||
+++ b/ipc/kdbus/names.h
|
||||
@@ -0,0 +1,74 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2013-2015 Kay Sievers
|
||||
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
|
||||
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
|
||||
+ * Copyright (C) 2013-2015 Linux Foundation
|
||||
+ * Copyright (C) 2014-2015 Djalal Harouni <tixxdz@opendz.org>
|
||||
+ *
|
||||
+ * kdbus is free software; you can redistribute it and/or modify it under
|
||||
+ * the terms of the GNU Lesser General Public License as published by the
|
||||
+ * Free Software Foundation; either version 2.1 of the License, or (at
|
||||
+ * your option) any later version.
|
||||
+ */
|
||||
+
|
||||
+#ifndef __KDBUS_NAMES_H
|
||||
+#define __KDBUS_NAMES_H
|
||||
+
|
||||
+#include <linux/hashtable.h>
|
||||
+#include <linux/rwsem.h>
|
||||
+
|
||||
+/**
|
||||
+ * struct kdbus_name_registry - names registered for a bus
|
||||
+ * @entries_hash: Map of entries
|
||||
+ * @lock: Registry data lock
|
||||
+ * @name_seq_last: Last used sequence number to assign to a name entry
|
||||
+ */
|
||||
+struct kdbus_name_registry {
|
||||
+ DECLARE_HASHTABLE(entries_hash, 8);
|
||||
+ struct rw_semaphore rwlock;
|
||||
+ u64 name_seq_last;
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct kdbus_name_entry - well-know name entry
|
||||
+ * @name_id: Sequence number of name entry to be able to uniquely
|
||||
+ * identify a name over its registration lifetime
|
||||
+ * @flags: KDBUS_NAME_* flags
|
||||
+ * @conn: Connection owning the name
|
||||
+ * @activator: Connection of the activator queuing incoming messages
|
||||
+ * @queue: List of queued connections
|
||||
+ * @conn_entry: Entry in connection
|
||||
+ * @hentry: Entry in registry map
|
||||
+ * @name: The well-known name
|
||||
+ */
|
||||
+struct kdbus_name_entry {
|
||||
+ u64 name_id;
|
||||
+ u64 flags;
|
||||
+ struct kdbus_conn *conn;
|
||||
+ struct kdbus_conn *activator;
|
||||
+ struct list_head queue;
|
||||
+ struct list_head conn_entry;
|
||||
+ struct hlist_node hentry;
|
||||
+ char name[];
|
||||
+};
|
||||
+
|
||||
+bool kdbus_name_is_valid(const char *p, bool allow_wildcard);
|
||||
+
|
||||
+struct kdbus_name_registry *kdbus_name_registry_new(void);
|
||||
+void kdbus_name_registry_free(struct kdbus_name_registry *reg);
|
||||
+
|
||||
+struct kdbus_name_entry *
|
||||
+kdbus_name_lookup_unlocked(struct kdbus_name_registry *reg, const char *name);
|
||||
+
|
||||
+int kdbus_name_acquire(struct kdbus_name_registry *reg,
|
||||
+ struct kdbus_conn *conn, const char *name,
|
||||
+ u64 flags, u64 *return_flags);
|
||||
+void kdbus_name_release_all(struct kdbus_name_registry *reg,
|
||||
+ struct kdbus_conn *conn);
|
||||
+
|
||||
+int kdbus_cmd_name_acquire(struct kdbus_conn *conn, void __user *argp);
|
||||
+int kdbus_cmd_name_release(struct kdbus_conn *conn, void __user *argp);
|
||||
+int kdbus_cmd_list(struct kdbus_conn *conn, void __user *argp);
|
||||
+
|
||||
+#endif
|
1602
kdbus-add-node-and-filesystem-implementation.patch
Normal file
1602
kdbus-add-node-and-filesystem-implementation.patch
Normal file
File diff suppressed because it is too large
Load Diff
585
kdbus-add-policy-database-implementation.patch
Normal file
585
kdbus-add-policy-database-implementation.patch
Normal file
@ -0,0 +1,585 @@
|
||||
From: Daniel Mack <daniel@zonque.org>
|
||||
Date: Thu, 11 Sep 2014 19:00:43 +0200
|
||||
Subject: [PATCH] kdbus: add policy database implementation
|
||||
|
||||
This patch adds the policy database implementation.
|
||||
|
||||
A policy database restricts the possibilities of connections to own,
|
||||
see and talk to well-known names. It can be associated with a bus
|
||||
(through a policy holder connection) or a custom endpoint.
|
||||
|
||||
By default, buses have an empty policy database that is augmented on
|
||||
demand when a policy holder connection is instantiated.
|
||||
|
||||
Policies are set through KDBUS_CMD_HELLO (when creating a policy
|
||||
holder connection), KDBUS_CMD_CONN_UPDATE (when updating a policy
|
||||
holder connection), KDBUS_CMD_EP_MAKE (creating a custom endpoint)
|
||||
or KDBUS_CMD_EP_UPDATE (updating a custom endpoint). In all cases,
|
||||
the name and policy access information is stored in items of type
|
||||
KDBUS_ITEM_NAME and KDBUS_ITEM_POLICY_ACCESS.
|
||||
|
||||
See kdbus.policy(7) for more details.
|
||||
|
||||
Signed-off-by: Daniel Mack <daniel@zonque.org>
|
||||
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Signed-off-by: Djalal Harouni <tixxdz@opendz.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
ipc/kdbus/policy.c | 489 +++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
ipc/kdbus/policy.h | 51 ++++++
|
||||
2 files changed, 540 insertions(+)
|
||||
create mode 100644 ipc/kdbus/policy.c
|
||||
create mode 100644 ipc/kdbus/policy.h
|
||||
|
||||
diff --git a/ipc/kdbus/policy.c b/ipc/kdbus/policy.c
|
||||
new file mode 100644
|
||||
index 000000000000..dd7fffaafa84
|
||||
--- /dev/null
|
||||
+++ b/ipc/kdbus/policy.c
|
||||
@@ -0,0 +1,489 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2013-2015 Kay Sievers
|
||||
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
|
||||
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
|
||||
+ * Copyright (C) 2013-2015 Linux Foundation
|
||||
+ * Copyright (C) 2014-2015 Djalal Harouni
|
||||
+ *
|
||||
+ * kdbus is free software; you can redistribute it and/or modify it under
|
||||
+ * the terms of the GNU Lesser General Public License as published by the
|
||||
+ * Free Software Foundation; either version 2.1 of the License, or (at
|
||||
+ * your option) any later version.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/dcache.h>
|
||||
+#include <linux/fs.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/mutex.h>
|
||||
+#include <linux/sched.h>
|
||||
+#include <linux/sizes.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/uaccess.h>
|
||||
+
|
||||
+#include "bus.h"
|
||||
+#include "connection.h"
|
||||
+#include "domain.h"
|
||||
+#include "item.h"
|
||||
+#include "names.h"
|
||||
+#include "policy.h"
|
||||
+
|
||||
+#define KDBUS_POLICY_HASH_SIZE 64
|
||||
+
|
||||
+/**
|
||||
+ * struct kdbus_policy_db_entry_access - a database entry access item
|
||||
+ * @type: One of KDBUS_POLICY_ACCESS_* types
|
||||
+ * @access: Access to grant. One of KDBUS_POLICY_*
|
||||
+ * @uid: For KDBUS_POLICY_ACCESS_USER, the global uid
|
||||
+ * @gid: For KDBUS_POLICY_ACCESS_GROUP, the global gid
|
||||
+ * @list: List entry item for the entry's list
|
||||
+ *
|
||||
+ * This is the internal version of struct kdbus_policy_db_access.
|
||||
+ */
|
||||
+struct kdbus_policy_db_entry_access {
|
||||
+ u8 type; /* USER, GROUP, WORLD */
|
||||
+ u8 access; /* OWN, TALK, SEE */
|
||||
+ union {
|
||||
+ kuid_t uid; /* global uid */
|
||||
+ kgid_t gid; /* global gid */
|
||||
+ };
|
||||
+ struct list_head list;
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct kdbus_policy_db_entry - a policy database entry
|
||||
+ * @name: The name to match the policy entry against
|
||||
+ * @hentry: The hash entry for the database's entries_hash
|
||||
+ * @access_list: List head for keeping tracks of the entry's
|
||||
+ * access items.
|
||||
+ * @owner: The owner of this entry. Can be a kdbus_conn or
|
||||
+ * a kdbus_ep object.
|
||||
+ * @wildcard: The name is a wildcard, such as ending on '.*'
|
||||
+ */
|
||||
+struct kdbus_policy_db_entry {
|
||||
+ char *name;
|
||||
+ struct hlist_node hentry;
|
||||
+ struct list_head access_list;
|
||||
+ const void *owner;
|
||||
+ bool wildcard:1;
|
||||
+};
|
||||
+
|
||||
+static void kdbus_policy_entry_free(struct kdbus_policy_db_entry *e)
|
||||
+{
|
||||
+ struct kdbus_policy_db_entry_access *a, *tmp;
|
||||
+
|
||||
+ list_for_each_entry_safe(a, tmp, &e->access_list, list) {
|
||||
+ list_del(&a->list);
|
||||
+ kfree(a);
|
||||
+ }
|
||||
+
|
||||
+ kfree(e->name);
|
||||
+ kfree(e);
|
||||
+}
|
||||
+
|
||||
+static unsigned int kdbus_strnhash(const char *str, size_t len)
|
||||
+{
|
||||
+ unsigned long hash = init_name_hash();
|
||||
+
|
||||
+ while (len--)
|
||||
+ hash = partial_name_hash(*str++, hash);
|
||||
+
|
||||
+ return end_name_hash(hash);
|
||||
+}
|
||||
+
|
||||
+static const struct kdbus_policy_db_entry *
|
||||
+kdbus_policy_lookup(struct kdbus_policy_db *db, const char *name, u32 hash)
|
||||
+{
|
||||
+ struct kdbus_policy_db_entry *e;
|
||||
+ const char *dot;
|
||||
+ size_t len;
|
||||
+
|
||||
+ /* find exact match */
|
||||
+ hash_for_each_possible(db->entries_hash, e, hentry, hash)
|
||||
+ if (strcmp(e->name, name) == 0 && !e->wildcard)
|
||||
+ return e;
|
||||
+
|
||||
+ /* find wildcard match */
|
||||
+
|
||||
+ dot = strrchr(name, '.');
|
||||
+ if (!dot)
|
||||
+ return NULL;
|
||||
+
|
||||
+ len = dot - name;
|
||||
+ hash = kdbus_strnhash(name, len);
|
||||
+
|
||||
+ hash_for_each_possible(db->entries_hash, e, hentry, hash)
|
||||
+ if (e->wildcard && !strncmp(e->name, name, len) &&
|
||||
+ !e->name[len])
|
||||
+ return e;
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_policy_db_clear - release all memory from a policy db
|
||||
+ * @db: The policy database
|
||||
+ */
|
||||
+void kdbus_policy_db_clear(struct kdbus_policy_db *db)
|
||||
+{
|
||||
+ struct kdbus_policy_db_entry *e;
|
||||
+ struct hlist_node *tmp;
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ /* purge entries */
|
||||
+ down_write(&db->entries_rwlock);
|
||||
+ hash_for_each_safe(db->entries_hash, i, tmp, e, hentry) {
|
||||
+ hash_del(&e->hentry);
|
||||
+ kdbus_policy_entry_free(e);
|
||||
+ }
|
||||
+ up_write(&db->entries_rwlock);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_policy_db_init() - initialize a new policy database
|
||||
+ * @db: The location of the database
|
||||
+ *
|
||||
+ * This initializes a new policy-db. The underlying memory must have been
|
||||
+ * cleared to zero by the caller.
|
||||
+ */
|
||||
+void kdbus_policy_db_init(struct kdbus_policy_db *db)
|
||||
+{
|
||||
+ hash_init(db->entries_hash);
|
||||
+ init_rwsem(&db->entries_rwlock);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_policy_query_unlocked() - Query the policy database
|
||||
+ * @db: Policy database
|
||||
+ * @cred: Credentials to test against
|
||||
+ * @name: Name to query
|
||||
+ * @hash: Hash value of @name
|
||||
+ *
|
||||
+ * Same as kdbus_policy_query() but requires the caller to lock the policy
|
||||
+ * database against concurrent writes.
|
||||
+ *
|
||||
+ * Return: The highest KDBUS_POLICY_* access type found, or -EPERM if none.
|
||||
+ */
|
||||
+int kdbus_policy_query_unlocked(struct kdbus_policy_db *db,
|
||||
+ const struct cred *cred, const char *name,
|
||||
+ unsigned int hash)
|
||||
+{
|
||||
+ struct kdbus_policy_db_entry_access *a;
|
||||
+ const struct kdbus_policy_db_entry *e;
|
||||
+ int i, highest = -EPERM;
|
||||
+
|
||||
+ e = kdbus_policy_lookup(db, name, hash);
|
||||
+ if (!e)
|
||||
+ return -EPERM;
|
||||
+
|
||||
+ list_for_each_entry(a, &e->access_list, list) {
|
||||
+ if ((int)a->access <= highest)
|
||||
+ continue;
|
||||
+
|
||||
+ switch (a->type) {
|
||||
+ case KDBUS_POLICY_ACCESS_USER:
|
||||
+ if (uid_eq(cred->euid, a->uid))
|
||||
+ highest = a->access;
|
||||
+ break;
|
||||
+ case KDBUS_POLICY_ACCESS_GROUP:
|
||||
+ if (gid_eq(cred->egid, a->gid)) {
|
||||
+ highest = a->access;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < cred->group_info->ngroups; i++) {
|
||||
+ kgid_t gid = GROUP_AT(cred->group_info, i);
|
||||
+
|
||||
+ if (gid_eq(gid, a->gid)) {
|
||||
+ highest = a->access;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ break;
|
||||
+ case KDBUS_POLICY_ACCESS_WORLD:
|
||||
+ highest = a->access;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ /* OWN is the highest possible policy */
|
||||
+ if (highest >= KDBUS_POLICY_OWN)
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return highest;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_policy_query() - Query the policy database
|
||||
+ * @db: Policy database
|
||||
+ * @cred: Credentials to test against
|
||||
+ * @name: Name to query
|
||||
+ * @hash: Hash value of @name
|
||||
+ *
|
||||
+ * Query the policy database @db for the access rights of @cred to the name
|
||||
+ * @name. The access rights of @cred are returned, or -EPERM if no access is
|
||||
+ * granted.
|
||||
+ *
|
||||
+ * This call effectively searches for the highest access-right granted to
|
||||
+ * @cred. The caller should really cache those as policy lookups are rather
|
||||
+ * expensive.
|
||||
+ *
|
||||
+ * Return: The highest KDBUS_POLICY_* access type found, or -EPERM if none.
|
||||
+ */
|
||||
+int kdbus_policy_query(struct kdbus_policy_db *db, const struct cred *cred,
|
||||
+ const char *name, unsigned int hash)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ down_read(&db->entries_rwlock);
|
||||
+ ret = kdbus_policy_query_unlocked(db, cred, name, hash);
|
||||
+ up_read(&db->entries_rwlock);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void __kdbus_policy_remove_owner(struct kdbus_policy_db *db,
|
||||
+ const void *owner)
|
||||
+{
|
||||
+ struct kdbus_policy_db_entry *e;
|
||||
+ struct hlist_node *tmp;
|
||||
+ int i;
|
||||
+
|
||||
+ hash_for_each_safe(db->entries_hash, i, tmp, e, hentry)
|
||||
+ if (e->owner == owner) {
|
||||
+ hash_del(&e->hentry);
|
||||
+ kdbus_policy_entry_free(e);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_policy_remove_owner() - remove all entries related to a connection
|
||||
+ * @db: The policy database
|
||||
+ * @owner: The connection which items to remove
|
||||
+ */
|
||||
+void kdbus_policy_remove_owner(struct kdbus_policy_db *db,
|
||||
+ const void *owner)
|
||||
+{
|
||||
+ down_write(&db->entries_rwlock);
|
||||
+ __kdbus_policy_remove_owner(db, owner);
|
||||
+ up_write(&db->entries_rwlock);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Convert user provided policy access to internal kdbus policy
|
||||
+ * access
|
||||
+ */
|
||||
+static struct kdbus_policy_db_entry_access *
|
||||
+kdbus_policy_make_access(const struct kdbus_policy_access *uaccess)
|
||||
+{
|
||||
+ int ret;
|
||||
+ struct kdbus_policy_db_entry_access *a;
|
||||
+
|
||||
+ a = kzalloc(sizeof(*a), GFP_KERNEL);
|
||||
+ if (!a)
|
||||
+ return ERR_PTR(-ENOMEM);
|
||||
+
|
||||
+ ret = -EINVAL;
|
||||
+ switch (uaccess->access) {
|
||||
+ case KDBUS_POLICY_SEE:
|
||||
+ case KDBUS_POLICY_TALK:
|
||||
+ case KDBUS_POLICY_OWN:
|
||||
+ a->access = uaccess->access;
|
||||
+ break;
|
||||
+ default:
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ switch (uaccess->type) {
|
||||
+ case KDBUS_POLICY_ACCESS_USER:
|
||||
+ a->uid = make_kuid(current_user_ns(), uaccess->id);
|
||||
+ if (!uid_valid(a->uid))
|
||||
+ goto err;
|
||||
+
|
||||
+ break;
|
||||
+ case KDBUS_POLICY_ACCESS_GROUP:
|
||||
+ a->gid = make_kgid(current_user_ns(), uaccess->id);
|
||||
+ if (!gid_valid(a->gid))
|
||||
+ goto err;
|
||||
+
|
||||
+ break;
|
||||
+ case KDBUS_POLICY_ACCESS_WORLD:
|
||||
+ break;
|
||||
+ default:
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ a->type = uaccess->type;
|
||||
+
|
||||
+ return a;
|
||||
+
|
||||
+err:
|
||||
+ kfree(a);
|
||||
+ return ERR_PTR(ret);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_policy_set() - set a connection's policy rules
|
||||
+ * @db: The policy database
|
||||
+ * @items: A list of kdbus_item elements that contain both
|
||||
+ * names and access rules to set.
|
||||
+ * @items_size: The total size of the items.
|
||||
+ * @max_policies: The maximum number of policy entries to allow.
|
||||
+ * Pass 0 for no limit.
|
||||
+ * @allow_wildcards: Boolean value whether wildcard entries (such
|
||||
+ * ending on '.*') should be allowed.
|
||||
+ * @owner: The owner of the new policy items.
|
||||
+ *
|
||||
+ * This function sets a new set of policies for a given owner. The names and
|
||||
+ * access rules are gathered by walking the list of items passed in as
|
||||
+ * argument. An item of type KDBUS_ITEM_NAME is expected before any number of
|
||||
+ * KDBUS_ITEM_POLICY_ACCESS items. If there are more repetitions of this
|
||||
+ * pattern than denoted in @max_policies, -EINVAL is returned.
|
||||
+ *
|
||||
+ * In order to allow atomic replacement of rules, the function first removes
|
||||
+ * all entries that have been created for the given owner previously.
|
||||
+ *
|
||||
+ * Callers to this function must make sur that the owner is a custom
|
||||
+ * endpoint, or if the endpoint is a default endpoint, then it must be
|
||||
+ * either a policy holder or an activator.
|
||||
+ *
|
||||
+ * Return: 0 on success, negative errno on failure.
|
||||
+ */
|
||||
+int kdbus_policy_set(struct kdbus_policy_db *db,
|
||||
+ const struct kdbus_item *items,
|
||||
+ size_t items_size,
|
||||
+ size_t max_policies,
|
||||
+ bool allow_wildcards,
|
||||
+ const void *owner)
|
||||
+{
|
||||
+ struct kdbus_policy_db_entry_access *a;
|
||||
+ struct kdbus_policy_db_entry *e, *p;
|
||||
+ const struct kdbus_item *item;
|
||||
+ struct hlist_node *tmp;
|
||||
+ HLIST_HEAD(entries);
|
||||
+ HLIST_HEAD(restore);
|
||||
+ size_t count = 0;
|
||||
+ int i, ret = 0;
|
||||
+ u32 hash;
|
||||
+
|
||||
+ /* Walk the list of items and look for new policies */
|
||||
+ e = NULL;
|
||||
+ KDBUS_ITEMS_FOREACH(item, items, items_size) {
|
||||
+ switch (item->type) {
|
||||
+ case KDBUS_ITEM_NAME: {
|
||||
+ size_t len;
|
||||
+
|
||||
+ if (max_policies && ++count > max_policies) {
|
||||
+ ret = -E2BIG;
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ if (!kdbus_name_is_valid(item->str, true)) {
|
||||
+ ret = -EINVAL;
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ e = kzalloc(sizeof(*e), GFP_KERNEL);
|
||||
+ if (!e) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ INIT_LIST_HEAD(&e->access_list);
|
||||
+ e->owner = owner;
|
||||
+ hlist_add_head(&e->hentry, &entries);
|
||||
+
|
||||
+ e->name = kstrdup(item->str, GFP_KERNEL);
|
||||
+ if (!e->name) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * If a supplied name ends with an '.*', cut off that
|
||||
+ * part, only store anything before it, and mark the
|
||||
+ * entry as wildcard.
|
||||
+ */
|
||||
+ len = strlen(e->name);
|
||||
+ if (len > 2 &&
|
||||
+ e->name[len - 3] == '.' &&
|
||||
+ e->name[len - 2] == '*') {
|
||||
+ if (!allow_wildcards) {
|
||||
+ ret = -EINVAL;
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ e->name[len - 3] = '\0';
|
||||
+ e->wildcard = true;
|
||||
+ }
|
||||
+
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ case KDBUS_ITEM_POLICY_ACCESS:
|
||||
+ if (!e) {
|
||||
+ ret = -EINVAL;
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ a = kdbus_policy_make_access(&item->policy_access);
|
||||
+ if (IS_ERR(a)) {
|
||||
+ ret = PTR_ERR(a);
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ list_add_tail(&a->list, &e->access_list);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ down_write(&db->entries_rwlock);
|
||||
+
|
||||
+ /* remember previous entries to restore in case of failure */
|
||||
+ hash_for_each_safe(db->entries_hash, i, tmp, e, hentry)
|
||||
+ if (e->owner == owner) {
|
||||
+ hash_del(&e->hentry);
|
||||
+ hlist_add_head(&e->hentry, &restore);
|
||||
+ }
|
||||
+
|
||||
+ hlist_for_each_entry_safe(e, tmp, &entries, hentry) {
|
||||
+ /* prevent duplicates */
|
||||
+ hash = kdbus_strhash(e->name);
|
||||
+ hash_for_each_possible(db->entries_hash, p, hentry, hash)
|
||||
+ if (strcmp(e->name, p->name) == 0 &&
|
||||
+ e->wildcard == p->wildcard) {
|
||||
+ ret = -EEXIST;
|
||||
+ goto restore;
|
||||
+ }
|
||||
+
|
||||
+ hlist_del(&e->hentry);
|
||||
+ hash_add(db->entries_hash, &e->hentry, hash);
|
||||
+ }
|
||||
+
|
||||
+restore:
|
||||
+ /* if we failed, flush all entries we added so far */
|
||||
+ if (ret < 0)
|
||||
+ __kdbus_policy_remove_owner(db, owner);
|
||||
+
|
||||
+ /* if we failed, restore entries, otherwise release them */
|
||||
+ hlist_for_each_entry_safe(e, tmp, &restore, hentry) {
|
||||
+ hlist_del(&e->hentry);
|
||||
+ if (ret < 0) {
|
||||
+ hash = kdbus_strhash(e->name);
|
||||
+ hash_add(db->entries_hash, &e->hentry, hash);
|
||||
+ } else {
|
||||
+ kdbus_policy_entry_free(e);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ up_write(&db->entries_rwlock);
|
||||
+
|
||||
+exit:
|
||||
+ hlist_for_each_entry_safe(e, tmp, &entries, hentry) {
|
||||
+ hlist_del(&e->hentry);
|
||||
+ kdbus_policy_entry_free(e);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
diff --git a/ipc/kdbus/policy.h b/ipc/kdbus/policy.h
|
||||
new file mode 100644
|
||||
index 000000000000..15dd7bc12068
|
||||
--- /dev/null
|
||||
+++ b/ipc/kdbus/policy.h
|
||||
@@ -0,0 +1,51 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2013-2015 Kay Sievers
|
||||
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
|
||||
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
|
||||
+ * Copyright (C) 2013-2015 Linux Foundation
|
||||
+ *
|
||||
+ * kdbus is free software; you can redistribute it and/or modify it under
|
||||
+ * the terms of the GNU Lesser General Public License as published by the
|
||||
+ * Free Software Foundation; either version 2.1 of the License, or (at
|
||||
+ * your option) any later version.
|
||||
+ */
|
||||
+
|
||||
+#ifndef __KDBUS_POLICY_H
|
||||
+#define __KDBUS_POLICY_H
|
||||
+
|
||||
+#include <linux/hashtable.h>
|
||||
+#include <linux/rwsem.h>
|
||||
+
|
||||
+struct kdbus_conn;
|
||||
+struct kdbus_item;
|
||||
+
|
||||
+/**
|
||||
+ * struct kdbus_policy_db - policy database
|
||||
+ * @entries_hash: Hashtable of entries
|
||||
+ * @entries_rwlock: Mutex to protect the database's access entries
|
||||
+ */
|
||||
+struct kdbus_policy_db {
|
||||
+ DECLARE_HASHTABLE(entries_hash, 6);
|
||||
+ struct rw_semaphore entries_rwlock;
|
||||
+};
|
||||
+
|
||||
+void kdbus_policy_db_init(struct kdbus_policy_db *db);
|
||||
+void kdbus_policy_db_clear(struct kdbus_policy_db *db);
|
||||
+
|
||||
+int kdbus_policy_query_unlocked(struct kdbus_policy_db *db,
|
||||
+ const struct cred *cred, const char *name,
|
||||
+ unsigned int hash);
|
||||
+int kdbus_policy_query(struct kdbus_policy_db *db, const struct cred *cred,
|
||||
+ const char *name, unsigned int hash);
|
||||
+
|
||||
+void kdbus_policy_remove_owner(struct kdbus_policy_db *db,
|
||||
+ const void *owner);
|
||||
+int kdbus_policy_set(struct kdbus_policy_db *db,
|
||||
+ const struct kdbus_item *items,
|
||||
+ size_t items_size,
|
||||
+ size_t max_policies,
|
||||
+ bool allow_wildcards,
|
||||
+ const void *owner);
|
||||
+
|
||||
+#endif
|
11448
kdbus-add-selftests.patch
Normal file
11448
kdbus-add-selftests.patch
Normal file
File diff suppressed because it is too large
Load Diff
1040
kdbus-add-uapi-header-file.patch
Normal file
1040
kdbus-add-uapi-header-file.patch
Normal file
File diff suppressed because it is too large
Load Diff
1538
kdbus-add-walk-through-user-space-example.patch
Normal file
1538
kdbus-add-walk-through-user-space-example.patch
Normal file
File diff suppressed because it is too large
Load Diff
56
kdbus-avoid-the-use-of-struct-timespec.patch
Normal file
56
kdbus-avoid-the-use-of-struct-timespec.patch
Normal file
@ -0,0 +1,56 @@
|
||||
From: Arnd Bergmann <arnd@arndb.de>
|
||||
Date: Fri, 10 Apr 2015 13:43:37 +0200
|
||||
Subject: [PATCH] kdbus: avoid the use of struct timespec
|
||||
|
||||
I did a routine check for new users of 'timespec', which we are trying to remove
|
||||
from the kernel in order to survive y2038. kdbus came up and looks particularly
|
||||
trivial to clean up.
|
||||
|
||||
This changes the three ktime_get_ts() variants used in kdbus to ktime_get_ns(),
|
||||
which aside from removing timespec also simplifies the code and makes it
|
||||
slightly more efficient by avoiding a two-way conversion.
|
||||
|
||||
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
ipc/kdbus/metadata.c | 9 ++-------
|
||||
ipc/kdbus/reply.c | 4 +---
|
||||
2 files changed, 3 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/ipc/kdbus/metadata.c b/ipc/kdbus/metadata.c
|
||||
index 06e0a54a276a..3adc6c2c2e76 100644
|
||||
--- a/ipc/kdbus/metadata.c
|
||||
+++ b/ipc/kdbus/metadata.c
|
||||
@@ -678,13 +678,8 @@ struct kdbus_meta_conn *kdbus_meta_conn_unref(struct kdbus_meta_conn *mc)
|
||||
static void kdbus_meta_conn_collect_timestamp(struct kdbus_meta_conn *mc,
|
||||
struct kdbus_kmsg *kmsg)
|
||||
{
|
||||
- struct timespec ts;
|
||||
-
|
||||
- ktime_get_ts(&ts);
|
||||
- mc->ts.monotonic_ns = timespec_to_ns(&ts);
|
||||
-
|
||||
- ktime_get_real_ts(&ts);
|
||||
- mc->ts.realtime_ns = timespec_to_ns(&ts);
|
||||
+ mc->ts.monotonic_ns = ktime_get_ns();
|
||||
+ mc->ts.realtime_ns = ktime_get_real_ns();
|
||||
|
||||
if (kmsg)
|
||||
mc->ts.seqnum = kmsg->seq;
|
||||
diff --git a/ipc/kdbus/reply.c b/ipc/kdbus/reply.c
|
||||
index 6b3bd81bbb4d..008dca801627 100644
|
||||
--- a/ipc/kdbus/reply.c
|
||||
+++ b/ipc/kdbus/reply.c
|
||||
@@ -204,11 +204,9 @@ void kdbus_reply_list_scan_work(struct work_struct *work)
|
||||
container_of(work, struct kdbus_conn, work.work);
|
||||
struct kdbus_reply *reply, *reply_tmp;
|
||||
u64 deadline = ~0ULL;
|
||||
- struct timespec64 ts;
|
||||
u64 now;
|
||||
|
||||
- ktime_get_ts64(&ts);
|
||||
- now = timespec64_to_ns(&ts);
|
||||
+ now = ktime_get_ns();
|
||||
|
||||
mutex_lock(&conn->lock);
|
||||
if (!kdbus_conn_active(conn)) {
|
36
kdbus-connection-fix-handling-of-failed-fget.patch
Normal file
36
kdbus-connection-fix-handling-of-failed-fget.patch
Normal file
@ -0,0 +1,36 @@
|
||||
From: Daniel Mack <daniel@zonque.org>
|
||||
Date: Tue, 17 Mar 2015 19:48:24 +0100
|
||||
Subject: [PATCH] kdbus: connection: fix handling of failed fget()
|
||||
|
||||
The patch 5fc8dd5c84fc: "kdbus: add connection, queue handling and
|
||||
message validation code" from Sep 11, 2014, leads to the following
|
||||
static checker warning:
|
||||
|
||||
ipc/kdbus/connection.c:2000 kdbus_cmd_send()
|
||||
warn: 'cancel_fd' isn't an ERR_PTR
|
||||
|
||||
Fix this by checking for NULL pointers returned from fget().
|
||||
|
||||
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
|
||||
Signed-off-by: Daniel Mack <daniel@zonque.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
ipc/kdbus/connection.c | 5 ++---
|
||||
1 file changed, 2 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/ipc/kdbus/connection.c b/ipc/kdbus/connection.c
|
||||
index e554f1a71aa1..ab476fa9ccca 100644
|
||||
--- a/ipc/kdbus/connection.c
|
||||
+++ b/ipc/kdbus/connection.c
|
||||
@@ -1997,9 +1997,8 @@ int kdbus_cmd_send(struct kdbus_conn *conn, struct file *f, void __user *argp)
|
||||
|
||||
if (argv[1].item) {
|
||||
cancel_fd = fget(argv[1].item->fds[0]);
|
||||
- if (IS_ERR(cancel_fd)) {
|
||||
- ret = PTR_ERR(cancel_fd);
|
||||
- cancel_fd = NULL;
|
||||
+ if (!cancel_fd) {
|
||||
+ ret = -EBADF;
|
||||
goto exit;
|
||||
}
|
||||
|
167
kdbus-copy-small-ioctl-payloads-to-stack.patch
Normal file
167
kdbus-copy-small-ioctl-payloads-to-stack.patch
Normal file
@ -0,0 +1,167 @@
|
||||
From: David Herrmann <dh.herrmann@gmail.com>
|
||||
Date: Mon, 20 Apr 2015 16:20:59 +0200
|
||||
Subject: [PATCH] kdbus: copy small ioctl payloads to stack
|
||||
|
||||
Right now, we use memdup_user() on all ioctl payloads. However, most of
|
||||
the time an ioctl payload is pretty small. 512 bytes on stack seem
|
||||
reasonable (similar to what poll() does) to speed up small ioctl payloads.
|
||||
Add a command-buffer to kdbus_args and use it instead of kmalloc() for
|
||||
reasonably small payloads.
|
||||
|
||||
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Acked-by: Daniel Mack <daniel@zonque.org>
|
||||
---
|
||||
ipc/kdbus/handle.c | 30 ++++++++++++++++++++++++++----
|
||||
ipc/kdbus/handle.h | 5 +++++
|
||||
ipc/kdbus/util.c | 45 ---------------------------------------------
|
||||
ipc/kdbus/util.h | 1 -
|
||||
4 files changed, 31 insertions(+), 50 deletions(-)
|
||||
|
||||
diff --git a/ipc/kdbus/handle.c b/ipc/kdbus/handle.c
|
||||
index 6230c7ef4347..07527990a051 100644
|
||||
--- a/ipc/kdbus/handle.c
|
||||
+++ b/ipc/kdbus/handle.c
|
||||
@@ -146,11 +146,32 @@ static int kdbus_args_negotiate(struct kdbus_args *args)
|
||||
int __kdbus_args_parse(struct kdbus_args *args, void __user *argp,
|
||||
size_t type_size, size_t items_offset, void **out)
|
||||
{
|
||||
+ u64 user_size;
|
||||
int ret, i;
|
||||
|
||||
- args->cmd = kdbus_memdup_user(argp, type_size, KDBUS_CMD_MAX_SIZE);
|
||||
- if (IS_ERR(args->cmd))
|
||||
- return PTR_ERR(args->cmd);
|
||||
+ ret = kdbus_copy_from_user(&user_size, argp, sizeof(user_size));
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (user_size < type_size)
|
||||
+ return -EINVAL;
|
||||
+ if (user_size > KDBUS_CMD_MAX_SIZE)
|
||||
+ return -EMSGSIZE;
|
||||
+
|
||||
+ if (user_size <= sizeof(args->cmd_buf)) {
|
||||
+ if (copy_from_user(args->cmd_buf, argp, user_size))
|
||||
+ return -EFAULT;
|
||||
+ args->cmd = (void*)args->cmd_buf;
|
||||
+ } else {
|
||||
+ args->cmd = memdup_user(argp, user_size);
|
||||
+ if (IS_ERR(args->cmd))
|
||||
+ return PTR_ERR(args->cmd);
|
||||
+ }
|
||||
+
|
||||
+ if (args->cmd->size != user_size) {
|
||||
+ ret = -EINVAL;
|
||||
+ goto error;
|
||||
+ }
|
||||
|
||||
args->cmd->return_flags = 0;
|
||||
args->user = argp;
|
||||
@@ -207,7 +228,8 @@ int kdbus_args_clear(struct kdbus_args *args, int ret)
|
||||
if (put_user(args->cmd->return_flags,
|
||||
&args->user->return_flags))
|
||||
ret = -EFAULT;
|
||||
- kfree(args->cmd);
|
||||
+ if (args->cmd != (void*)args->cmd_buf)
|
||||
+ kfree(args->cmd);
|
||||
args->cmd = NULL;
|
||||
}
|
||||
|
||||
diff --git a/ipc/kdbus/handle.h b/ipc/kdbus/handle.h
|
||||
index 93a372d554a2..13c59d975728 100644
|
||||
--- a/ipc/kdbus/handle.h
|
||||
+++ b/ipc/kdbus/handle.h
|
||||
@@ -45,6 +45,7 @@ struct kdbus_arg {
|
||||
* @argv: array of items this command supports
|
||||
* @user: set by parser to user-space location of current command
|
||||
* @cmd: set by parser to kernel copy of command payload
|
||||
+ * @cmd_buf: 512 bytes inline buf to avoid kmalloc() on small cmds
|
||||
* @items: points to item array in @cmd
|
||||
* @items_size: size of @items in bytes
|
||||
*
|
||||
@@ -52,6 +53,9 @@ struct kdbus_arg {
|
||||
* The ioctl handler has to pre-fill the flags and allowed items before passing
|
||||
* the object to kdbus_args_parse(). The parser will copy the command payload
|
||||
* into kernel-space and verify the correctness of the data.
|
||||
+ *
|
||||
+ * We use a 512 bytes buffer for small command payloads, to be allocated on
|
||||
+ * stack on syscall entrance.
|
||||
*/
|
||||
struct kdbus_args {
|
||||
u64 allowed_flags;
|
||||
@@ -60,6 +64,7 @@ struct kdbus_args {
|
||||
|
||||
struct kdbus_cmd __user *user;
|
||||
struct kdbus_cmd *cmd;
|
||||
+ u8 cmd_buf[512];
|
||||
|
||||
struct kdbus_item *items;
|
||||
size_t items_size;
|
||||
diff --git a/ipc/kdbus/util.c b/ipc/kdbus/util.c
|
||||
index eaa806a27997..72b188330896 100644
|
||||
--- a/ipc/kdbus/util.c
|
||||
+++ b/ipc/kdbus/util.c
|
||||
@@ -50,51 +50,6 @@ int kdbus_copy_from_user(void *dest, void __user *user_ptr, size_t size)
|
||||
}
|
||||
|
||||
/**
|
||||
- * kdbus_memdup_user() - copy dynamically sized object from user-space
|
||||
- * @user_ptr: user-provided source buffer
|
||||
- * @sz_min: minimum object size
|
||||
- * @sz_max: maximum object size
|
||||
- *
|
||||
- * This copies a dynamically sized object from user-space into kernel-space. We
|
||||
- * require the object to have a 64bit size field at offset 0. We read it out
|
||||
- * first, allocate a suitably sized buffer and then copy all data.
|
||||
- *
|
||||
- * The @sz_min and @sz_max parameters define possible min and max object sizes
|
||||
- * so user-space cannot trigger un-bound kernel-space allocations.
|
||||
- *
|
||||
- * The same alignment-restrictions as described in kdbus_copy_from_user() apply.
|
||||
- *
|
||||
- * Return: pointer to dynamically allocated copy, or ERR_PTR() on failure.
|
||||
- */
|
||||
-void *kdbus_memdup_user(void __user *user_ptr, size_t sz_min, size_t sz_max)
|
||||
-{
|
||||
- void *ptr;
|
||||
- u64 size;
|
||||
- int ret;
|
||||
-
|
||||
- ret = kdbus_copy_from_user(&size, user_ptr, sizeof(size));
|
||||
- if (ret < 0)
|
||||
- return ERR_PTR(ret);
|
||||
-
|
||||
- if (size < sz_min)
|
||||
- return ERR_PTR(-EINVAL);
|
||||
-
|
||||
- if (size > sz_max)
|
||||
- return ERR_PTR(-EMSGSIZE);
|
||||
-
|
||||
- ptr = memdup_user(user_ptr, size);
|
||||
- if (IS_ERR(ptr))
|
||||
- return ptr;
|
||||
-
|
||||
- if (*(u64 *)ptr != size) {
|
||||
- kfree(ptr);
|
||||
- return ERR_PTR(-EINVAL);
|
||||
- }
|
||||
-
|
||||
- return ptr;
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
* kdbus_verify_uid_prefix() - verify UID prefix of a user-supplied name
|
||||
* @name: user-supplied name to verify
|
||||
* @user_ns: user-namespace to act in
|
||||
diff --git a/ipc/kdbus/util.h b/ipc/kdbus/util.h
|
||||
index 740b19880985..9fedf8ab41cd 100644
|
||||
--- a/ipc/kdbus/util.h
|
||||
+++ b/ipc/kdbus/util.h
|
||||
@@ -64,7 +64,6 @@ int kdbus_verify_uid_prefix(const char *name, struct user_namespace *user_ns,
|
||||
int kdbus_sanitize_attach_flags(u64 flags, u64 *attach_flags);
|
||||
|
||||
int kdbus_copy_from_user(void *dest, void __user *user_ptr, size_t size);
|
||||
-void *kdbus_memdup_user(void __user *user_ptr, size_t sz_min, size_t sz_max);
|
||||
|
||||
struct kvec;
|
||||
|
1071
kdbus-drop-kdbus_meta_attach_mask-modparam.patch
Normal file
1071
kdbus-drop-kdbus_meta_attach_mask-modparam.patch
Normal file
File diff suppressed because it is too large
Load Diff
27
kdbus-drop-obsolete-WARN_ON.patch
Normal file
27
kdbus-drop-obsolete-WARN_ON.patch
Normal file
@ -0,0 +1,27 @@
|
||||
From: David Herrmann <dh.herrmann@gmail.com>
|
||||
Date: Wed, 22 Apr 2015 19:31:50 +0200
|
||||
Subject: [PATCH] kdbus: drop obsolete WARN_ON
|
||||
|
||||
entry->user is never set to an error-code. Drop the obsolete WARN_ON which
|
||||
is a leftover from before the quota rework.
|
||||
|
||||
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
|
||||
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Acked-by: Daniel Mack <daniel@zonque.org>
|
||||
---
|
||||
ipc/kdbus/queue.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ipc/kdbus/queue.c b/ipc/kdbus/queue.c
|
||||
index a449464a3975..25bb3ad66b98 100644
|
||||
--- a/ipc/kdbus/queue.c
|
||||
+++ b/ipc/kdbus/queue.c
|
||||
@@ -637,7 +637,7 @@ int kdbus_queue_entry_move(struct kdbus_queue_entry *e,
|
||||
lockdep_assert_held(&src->lock);
|
||||
lockdep_assert_held(&dst->lock);
|
||||
|
||||
- if (WARN_ON(IS_ERR(e->user)) || WARN_ON(list_empty(&e->entry)))
|
||||
+ if (WARN_ON(list_empty(&e->entry)))
|
||||
return -EINVAL;
|
||||
if (src == dst)
|
||||
return 0;
|
24
kdbus-drop-useless-goto.patch
Normal file
24
kdbus-drop-useless-goto.patch
Normal file
@ -0,0 +1,24 @@
|
||||
From: Marc-Antoine Perennou <Marc-Antoine@Perennou.com>
|
||||
Date: Fri, 5 Jun 2015 14:37:34 +0200
|
||||
Subject: [PATCH] kdbus: drop useless goto
|
||||
|
||||
Signed-off-by: Marc-Antoine Perennou <Marc-Antoine@Perennou.com>
|
||||
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
ipc/kdbus/names.c | 2 --
|
||||
1 file changed, 2 deletions(-)
|
||||
|
||||
diff --git a/ipc/kdbus/names.c b/ipc/kdbus/names.c
|
||||
index 5f5d84ea0e8e..d77ee08afeda 100644
|
||||
--- a/ipc/kdbus/names.c
|
||||
+++ b/ipc/kdbus/names.c
|
||||
@@ -514,8 +514,6 @@ int kdbus_cmd_name_acquire(struct kdbus_conn *conn, void __user *argp)
|
||||
|
||||
ret = kdbus_name_acquire(conn->ep->bus->name_registry, conn, item_name,
|
||||
cmd->flags, &cmd->return_flags);
|
||||
- if (ret < 0)
|
||||
- goto exit_dec;
|
||||
|
||||
exit_dec:
|
||||
atomic_dec(&conn->name_count);
|
36
kdbus-fix-header-guard-name.patch
Normal file
36
kdbus-fix-header-guard-name.patch
Normal file
@ -0,0 +1,36 @@
|
||||
From: Lucas De Marchi <lucas.demarchi@intel.com>
|
||||
Date: Tue, 17 Mar 2015 09:21:42 -0300
|
||||
Subject: [PATCH] kdbus: fix header guard name
|
||||
|
||||
UAPI headers have a _UAPI_ as prefix, which is removed during
|
||||
headers_install. If it's put as a suffix it will not be removed and will
|
||||
be the only header with UAPI in the header guard macro.
|
||||
|
||||
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
|
||||
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
include/uapi/linux/kdbus.h | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/include/uapi/linux/kdbus.h b/include/uapi/linux/kdbus.h
|
||||
index fc1d77dd7c93..2fe0a1c5056c 100644
|
||||
--- a/include/uapi/linux/kdbus.h
|
||||
+++ b/include/uapi/linux/kdbus.h
|
||||
@@ -5,8 +5,8 @@
|
||||
* your option) any later version.
|
||||
*/
|
||||
|
||||
-#ifndef _KDBUS_UAPI_H_
|
||||
-#define _KDBUS_UAPI_H_
|
||||
+#ifndef _UAPI_KDBUS_H_
|
||||
+#define _UAPI_KDBUS_H_
|
||||
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/types.h>
|
||||
@@ -976,4 +976,4 @@ enum kdbus_ioctl_type {
|
||||
struct kdbus_cmd_match),
|
||||
};
|
||||
|
||||
-#endif /* _KDBUS_UAPI_H_ */
|
||||
+#endif /* _UAPI_KDBUS_H_ */
|
27
kdbus-fix-minor-typo-in-the-walk-through-example.patch
Normal file
27
kdbus-fix-minor-typo-in-the-walk-through-example.patch
Normal file
@ -0,0 +1,27 @@
|
||||
From: Nicolas Iooss <nicolas.iooss_linux@m4x.org>
|
||||
Date: Sun, 15 Mar 2015 13:13:08 +0800
|
||||
Subject: [PATCH] kdbus: fix minor typo in the walk-through example
|
||||
|
||||
s/receveiver/receiver/
|
||||
|
||||
Signed-off-by: Nicolas Iooss <nicolas.iooss_linux@m4x.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
samples/kdbus/kdbus-workers.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/samples/kdbus/kdbus-workers.c b/samples/kdbus/kdbus-workers.c
|
||||
index d1d8f7a7697b..d331e0186899 100644
|
||||
--- a/samples/kdbus/kdbus-workers.c
|
||||
+++ b/samples/kdbus/kdbus-workers.c
|
||||
@@ -787,8 +787,8 @@ static int child_run(struct child *c)
|
||||
* The 2nd item contains a vector to memory we want to send. It
|
||||
* can be content of any type. In our case, we're sending a one-byte
|
||||
* string only. The memory referenced by this item will be copied into
|
||||
- * the pool of the receveiver connection, and does not need to be
|
||||
- * valid after the command is employed.
|
||||
+ * the pool of the receiver connection, and does not need to be valid
|
||||
+ * after the command is employed.
|
||||
*/
|
||||
item = KDBUS_ITEM_NEXT(item);
|
||||
item->type = KDBUS_ITEM_PAYLOAD_VEC;
|
47
kdbus-fix-operator-precedence-issues-in-item-macros.patch
Normal file
47
kdbus-fix-operator-precedence-issues-in-item-macros.patch
Normal file
@ -0,0 +1,47 @@
|
||||
From: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Date: Tue, 9 Jun 2015 23:59:59 +0300
|
||||
Subject: [PATCH] kdbus: fix operator precedence issues in item macros
|
||||
|
||||
`_i' argument in KDBUS_ITEM_NEXT and KDBUS_ITEMS_END macros is not
|
||||
enclosed into parentheses when the cast operator is applied, which
|
||||
leads to improper type conversion if `_i' is supplied as a complex
|
||||
expression, e.g.
|
||||
|
||||
KDBUS_ITEM_NEXT(condition ? a : b)
|
||||
|
||||
KDBUS_ITEMS_SIZE macro has similar issue, missing parentheses around
|
||||
`_h' when using indirection operator.
|
||||
|
||||
Use parentheses properly to guarantee right precedence.
|
||||
|
||||
Signed-off-by: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
ipc/kdbus/item.h | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/ipc/kdbus/item.h b/ipc/kdbus/item.h
|
||||
index eeefd8beac3b..32909e2e7954 100644
|
||||
--- a/ipc/kdbus/item.h
|
||||
+++ b/ipc/kdbus/item.h
|
||||
@@ -21,8 +21,8 @@
|
||||
#include "util.h"
|
||||
|
||||
/* generic access and iterators over a stream of items */
|
||||
-#define KDBUS_ITEM_NEXT(_i) (typeof(_i))(((u8 *)_i) + KDBUS_ALIGN8((_i)->size))
|
||||
-#define KDBUS_ITEMS_SIZE(_h, _is) ((_h)->size - offsetof(typeof(*_h), _is))
|
||||
+#define KDBUS_ITEM_NEXT(_i) (typeof(_i))((u8 *)(_i) + KDBUS_ALIGN8((_i)->size))
|
||||
+#define KDBUS_ITEMS_SIZE(_h, _is) ((_h)->size - offsetof(typeof(*(_h)), _is))
|
||||
#define KDBUS_ITEM_HEADER_SIZE offsetof(struct kdbus_item, data)
|
||||
#define KDBUS_ITEM_SIZE(_s) KDBUS_ALIGN8(KDBUS_ITEM_HEADER_SIZE + (_s))
|
||||
#define KDBUS_ITEM_PAYLOAD_SIZE(_i) ((_i)->size - KDBUS_ITEM_HEADER_SIZE)
|
||||
@@ -40,7 +40,7 @@
|
||||
(u8 *)(_i) >= (u8 *)(_is))
|
||||
|
||||
#define KDBUS_ITEMS_END(_i, _is, _s) \
|
||||
- ((u8 *)_i == ((u8 *)(_is) + KDBUS_ALIGN8(_s)))
|
||||
+ ((u8 *)(_i) == ((u8 *)(_is) + KDBUS_ALIGN8(_s)))
|
||||
|
||||
/**
|
||||
* struct kdbus_item_header - Describes the fix part of an item
|
25
kdbus-fix-typo.patch
Normal file
25
kdbus-fix-typo.patch
Normal file
@ -0,0 +1,25 @@
|
||||
From: David Herrmann <dh.herrmann@gmail.com>
|
||||
Date: Tue, 26 May 2015 09:29:52 +0200
|
||||
Subject: [PATCH] kdbus: fix typo
|
||||
|
||||
Fix "there" -> "their" typo.
|
||||
|
||||
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Acked-by: Daniel Mack <daniel@zonque.org>
|
||||
---
|
||||
ipc/kdbus/connection.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ipc/kdbus/connection.c b/ipc/kdbus/connection.c
|
||||
index ab476fa9ccca..fb2c6c67c4c1 100644
|
||||
--- a/ipc/kdbus/connection.c
|
||||
+++ b/ipc/kdbus/connection.c
|
||||
@@ -753,7 +753,7 @@ void kdbus_conn_quota_dec(struct kdbus_conn *c, struct kdbus_user *u,
|
||||
*
|
||||
* kdbus is reliable. That means, we try hard to never lose messages. However,
|
||||
* memory is limited, so we cannot rely on transmissions to never fail.
|
||||
- * Therefore, we use quota-limits to let callers know if there unicast message
|
||||
+ * Therefore, we use quota-limits to let callers know if their unicast message
|
||||
* cannot be transmitted to a peer. This works fine for unicasts, but for
|
||||
* broadcasts we cannot make the caller handle the transmission failure.
|
||||
* Instead, we must let the destination know that it couldn't receive a
|
185
kdbus-fix-up-documentation-of-ioctl-handlers.patch
Normal file
185
kdbus-fix-up-documentation-of-ioctl-handlers.patch
Normal file
@ -0,0 +1,185 @@
|
||||
From: David Herrmann <dh.herrmann@gmail.com>
|
||||
Date: Thu, 23 Apr 2015 10:23:38 +0200
|
||||
Subject: [PATCH] kdbus: fix up documentation of ioctl handlers
|
||||
|
||||
We support feature negotiation on ioctls. As this is not necessarily fully
|
||||
generic, we indicate this by returning >0 from kdbus_args_parse().
|
||||
Therefore, all ioctl handlers that forward the return value of
|
||||
kdbus_args_parse() might also return >0 on negotiation. Which is totally
|
||||
fine and handled in kdbus_handle_ioctl(). However, the documentation of
|
||||
the ioctl handlers doesn't reflect that behavior. Fix those up!
|
||||
|
||||
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
|
||||
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
---
|
||||
ipc/kdbus/bus.c | 4 ++--
|
||||
ipc/kdbus/connection.c | 14 +++++++-------
|
||||
ipc/kdbus/endpoint.c | 4 ++--
|
||||
ipc/kdbus/match.c | 4 ++--
|
||||
ipc/kdbus/names.c | 6 +++---
|
||||
5 files changed, 16 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/ipc/kdbus/bus.c b/ipc/kdbus/bus.c
|
||||
index d5475961b896..bbdf0f2f391e 100644
|
||||
--- a/ipc/kdbus/bus.c
|
||||
+++ b/ipc/kdbus/bus.c
|
||||
@@ -365,7 +365,7 @@ void kdbus_bus_eavesdrop(struct kdbus_bus *bus,
|
||||
* @domain: domain to operate on
|
||||
* @argp: command payload
|
||||
*
|
||||
- * Return: Newly created bus on success, ERR_PTR on failure.
|
||||
+ * Return: NULL or newly created bus on success, ERR_PTR on failure.
|
||||
*/
|
||||
struct kdbus_bus *kdbus_cmd_bus_make(struct kdbus_domain *domain,
|
||||
void __user *argp)
|
||||
@@ -459,7 +459,7 @@ exit:
|
||||
* @conn: connection to operate on
|
||||
* @argp: command payload
|
||||
*
|
||||
- * Return: 0 on success, negative error code on failure.
|
||||
+ * Return: >=0 on success, negative error code on failure.
|
||||
*/
|
||||
int kdbus_cmd_bus_creator_info(struct kdbus_conn *conn, void __user *argp)
|
||||
{
|
||||
diff --git a/ipc/kdbus/connection.c b/ipc/kdbus/connection.c
|
||||
index cbfbf3847c24..8ee62fc0bd46 100644
|
||||
--- a/ipc/kdbus/connection.c
|
||||
+++ b/ipc/kdbus/connection.c
|
||||
@@ -1589,7 +1589,7 @@ bool kdbus_conn_policy_see_notification(struct kdbus_conn *conn,
|
||||
* @privileged: Whether the caller is privileged
|
||||
* @argp: Command payload
|
||||
*
|
||||
- * Return: Newly created connection on success, ERR_PTR on failure.
|
||||
+ * Return: NULL or newly created connection on success, ERR_PTR on failure.
|
||||
*/
|
||||
struct kdbus_conn *kdbus_cmd_hello(struct kdbus_ep *ep, bool privileged,
|
||||
void __user *argp)
|
||||
@@ -1676,7 +1676,7 @@ exit:
|
||||
*
|
||||
* The caller must not hold any active reference to @conn or this will deadlock.
|
||||
*
|
||||
- * Return: 0 on success, negative error code on failure.
|
||||
+ * Return: >=0 on success, negative error code on failure.
|
||||
*/
|
||||
int kdbus_cmd_byebye_unlocked(struct kdbus_conn *conn, void __user *argp)
|
||||
{
|
||||
@@ -1708,7 +1708,7 @@ int kdbus_cmd_byebye_unlocked(struct kdbus_conn *conn, void __user *argp)
|
||||
* @conn: connection to operate on
|
||||
* @argp: command payload
|
||||
*
|
||||
- * Return: 0 on success, negative error code on failure.
|
||||
+ * Return: >=0 on success, negative error code on failure.
|
||||
*/
|
||||
int kdbus_cmd_conn_info(struct kdbus_conn *conn, void __user *argp)
|
||||
{
|
||||
@@ -1838,7 +1838,7 @@ exit:
|
||||
* @conn: connection to operate on
|
||||
* @argp: command payload
|
||||
*
|
||||
- * Return: 0 on success, negative error code on failure.
|
||||
+ * Return: >=0 on success, negative error code on failure.
|
||||
*/
|
||||
int kdbus_cmd_update(struct kdbus_conn *conn, void __user *argp)
|
||||
{
|
||||
@@ -1935,7 +1935,7 @@ exit:
|
||||
* @f: file this command was called on
|
||||
* @argp: command payload
|
||||
*
|
||||
- * Return: 0 on success, negative error code on failure.
|
||||
+ * Return: >=0 on success, negative error code on failure.
|
||||
*/
|
||||
int kdbus_cmd_send(struct kdbus_conn *conn, struct file *f, void __user *argp)
|
||||
{
|
||||
@@ -2031,7 +2031,7 @@ exit:
|
||||
* @conn: connection to operate on
|
||||
* @argp: command payload
|
||||
*
|
||||
- * Return: 0 on success, negative error code on failure.
|
||||
+ * Return: >=0 on success, negative error code on failure.
|
||||
*/
|
||||
int kdbus_cmd_recv(struct kdbus_conn *conn, void __user *argp)
|
||||
{
|
||||
@@ -2154,7 +2154,7 @@ exit:
|
||||
* @conn: connection to operate on
|
||||
* @argp: command payload
|
||||
*
|
||||
- * Return: 0 on success, negative error code on failure.
|
||||
+ * Return: >=0 on success, negative error code on failure.
|
||||
*/
|
||||
int kdbus_cmd_free(struct kdbus_conn *conn, void __user *argp)
|
||||
{
|
||||
diff --git a/ipc/kdbus/endpoint.c b/ipc/kdbus/endpoint.c
|
||||
index 174d274b113e..9a95a5ea84d7 100644
|
||||
--- a/ipc/kdbus/endpoint.c
|
||||
+++ b/ipc/kdbus/endpoint.c
|
||||
@@ -188,7 +188,7 @@ struct kdbus_ep *kdbus_ep_unref(struct kdbus_ep *ep)
|
||||
* @bus: bus to operate on
|
||||
* @argp: command payload
|
||||
*
|
||||
- * Return: Newly created endpoint on success, ERR_PTR on failure.
|
||||
+ * Return: NULL or newly created endpoint on success, ERR_PTR on failure.
|
||||
*/
|
||||
struct kdbus_ep *kdbus_cmd_ep_make(struct kdbus_bus *bus, void __user *argp)
|
||||
{
|
||||
@@ -247,7 +247,7 @@ exit:
|
||||
* @ep: endpoint to operate on
|
||||
* @argp: command payload
|
||||
*
|
||||
- * Return: Newly created endpoint on success, ERR_PTR on failure.
|
||||
+ * Return: >=0 on success, negative error code on failure.
|
||||
*/
|
||||
int kdbus_cmd_ep_update(struct kdbus_ep *ep, void __user *argp)
|
||||
{
|
||||
diff --git a/ipc/kdbus/match.c b/ipc/kdbus/match.c
|
||||
index 30cec1ca819f..cc083b4211de 100644
|
||||
--- a/ipc/kdbus/match.c
|
||||
+++ b/ipc/kdbus/match.c
|
||||
@@ -368,7 +368,7 @@ static int kdbus_match_db_remove_unlocked(struct kdbus_match_db *mdb,
|
||||
* are used to match messages from userspace, while the others apply to
|
||||
* kernel-generated notifications.
|
||||
*
|
||||
- * Return: 0 on success, negative error code on failure.
|
||||
+ * Return: >=0 on success, negative error code on failure.
|
||||
*/
|
||||
int kdbus_cmd_match_add(struct kdbus_conn *conn, void __user *argp)
|
||||
{
|
||||
@@ -528,7 +528,7 @@ exit:
|
||||
* @conn: connection to operate on
|
||||
* @argp: command payload
|
||||
*
|
||||
- * Return: 0 on success, negative error code on failure.
|
||||
+ * Return: >=0 on success, negative error code on failure.
|
||||
*/
|
||||
int kdbus_cmd_match_remove(struct kdbus_conn *conn, void __user *argp)
|
||||
{
|
||||
diff --git a/ipc/kdbus/names.c b/ipc/kdbus/names.c
|
||||
index 657008e1bb37..5f5d84ea0e8e 100644
|
||||
--- a/ipc/kdbus/names.c
|
||||
+++ b/ipc/kdbus/names.c
|
||||
@@ -469,7 +469,7 @@ void kdbus_name_release_all(struct kdbus_name_registry *reg,
|
||||
* @conn: connection to operate on
|
||||
* @argp: command payload
|
||||
*
|
||||
- * Return: 0 on success, negative error code on failure.
|
||||
+ * Return: >=0 on success, negative error code on failure.
|
||||
*/
|
||||
int kdbus_cmd_name_acquire(struct kdbus_conn *conn, void __user *argp)
|
||||
{
|
||||
@@ -528,7 +528,7 @@ exit:
|
||||
* @conn: connection to operate on
|
||||
* @argp: command payload
|
||||
*
|
||||
- * Return: 0 on success, negative error code on failure.
|
||||
+ * Return: >=0 on success, negative error code on failure.
|
||||
*/
|
||||
int kdbus_cmd_name_release(struct kdbus_conn *conn, void __user *argp)
|
||||
{
|
||||
@@ -699,7 +699,7 @@ static int kdbus_list_all(struct kdbus_conn *conn, u64 flags,
|
||||
* @conn: connection to operate on
|
||||
* @argp: command payload
|
||||
*
|
||||
- * Return: 0 on success, negative error code on failure.
|
||||
+ * Return: >=0 on success, negative error code on failure.
|
||||
*/
|
||||
int kdbus_cmd_list(struct kdbus_conn *conn, void __user *argp)
|
||||
{
|
88
kdbus-forward-ID-notifications-to-everyone.patch
Normal file
88
kdbus-forward-ID-notifications-to-everyone.patch
Normal file
@ -0,0 +1,88 @@
|
||||
From: David Herrmann <dh.herrmann@gmail.com>
|
||||
Date: Tue, 26 May 2015 09:30:14 +0200
|
||||
Subject: [PATCH] kdbus: forward ID notifications to everyone
|
||||
|
||||
Even if you cannot SEE another peer (eg., if you're behind a private
|
||||
endpoint), the other peer might be able to TALK to you. Therefore, you
|
||||
might get messages from them. This works mostly fine, with one major
|
||||
exception, that you cannot track the remote peer. You will not receive ID
|
||||
notifications for it, thus, you don't get notified when they disconnect.
|
||||
This is unforunate and breaks sandboxes kdbus peers.
|
||||
|
||||
Fix this by forwarding ID notifications to everyone. Note that those
|
||||
notifications don't carry _any_ useful information, besides the peer ID.
|
||||
Therefore, even if you should not able to SEE a peer, you will now still
|
||||
get ID notifications. This does not reveal any additional information on
|
||||
the remote peer, besides its lifetime. Hence, it should be fine.
|
||||
|
||||
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Acked-by: Daniel Mack <daniel@zonque.org>
|
||||
---
|
||||
ipc/kdbus/connection.c | 8 +++-----
|
||||
tools/testing/selftests/kdbus/test-endpoint.c | 13 ++++++++++++-
|
||||
2 files changed, 15 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/ipc/kdbus/connection.c b/ipc/kdbus/connection.c
|
||||
index fb2c6c67c4c1..272b991f36f4 100644
|
||||
--- a/ipc/kdbus/connection.c
|
||||
+++ b/ipc/kdbus/connection.c
|
||||
@@ -1588,10 +1588,8 @@ bool kdbus_conn_policy_see_notification(struct kdbus_conn *conn,
|
||||
* to a peer if, and only if, that peer can see the name this
|
||||
* notification is for.
|
||||
*
|
||||
- * KDBUS_ITEM_ID_{ADD,REMOVE}: As new peers cannot have names, and all
|
||||
- * names are dropped before a peer is removed, those notifications
|
||||
- * cannot be seen on custom endpoints. Thus, we only pass them
|
||||
- * through on default endpoints.
|
||||
+ * KDBUS_ITEM_ID_{ADD,REMOVE}: Notifications for ID changes are
|
||||
+ * broadcast to everyone, to allow tracking peers.
|
||||
*/
|
||||
|
||||
switch (kmsg->notify_type) {
|
||||
@@ -1603,7 +1601,7 @@ bool kdbus_conn_policy_see_notification(struct kdbus_conn *conn,
|
||||
|
||||
case KDBUS_ITEM_ID_ADD:
|
||||
case KDBUS_ITEM_ID_REMOVE:
|
||||
- return !conn->ep->user;
|
||||
+ return true;
|
||||
|
||||
default:
|
||||
WARN(1, "Invalid type for notification broadcast: %llu\n",
|
||||
diff --git a/tools/testing/selftests/kdbus/test-endpoint.c b/tools/testing/selftests/kdbus/test-endpoint.c
|
||||
index dcc6ab91c4e6..34a7be49c482 100644
|
||||
--- a/tools/testing/selftests/kdbus/test-endpoint.c
|
||||
+++ b/tools/testing/selftests/kdbus/test-endpoint.c
|
||||
@@ -255,6 +255,13 @@ int kdbus_test_custom_endpoint(struct kdbus_test_env *env)
|
||||
ep_conn = kdbus_hello(ep, 0, NULL, 0);
|
||||
ASSERT_RETURN(ep_conn);
|
||||
|
||||
+ /* Check that the reader got the IdAdd notification */
|
||||
+ ret = kdbus_msg_recv(reader, &msg, NULL);
|
||||
+ ASSERT_RETURN(ret == 0);
|
||||
+ ASSERT_RETURN(msg->items[0].type == KDBUS_ITEM_ID_ADD);
|
||||
+ ASSERT_RETURN(msg->items[0].id_change.id == ep_conn->id);
|
||||
+ kdbus_msg_free(msg);
|
||||
+
|
||||
/*
|
||||
* Add a name add match on the endpoint connection, acquire name from
|
||||
* the unfiltered connection, and make sure the filtered connection
|
||||
@@ -283,7 +290,7 @@ int kdbus_test_custom_endpoint(struct kdbus_test_env *env)
|
||||
ret = kdbus_conn_info(ep_conn, 0x0fffffffffffffffULL, NULL, 0, NULL);
|
||||
ASSERT_RETURN(ret == -ENXIO);
|
||||
|
||||
- /* Check that the reader did not receive anything */
|
||||
+ /* Check that the reader did not receive the name notification */
|
||||
ret = kdbus_msg_recv(reader, NULL, NULL);
|
||||
ASSERT_RETURN(ret == -EAGAIN);
|
||||
|
||||
@@ -295,6 +302,10 @@ int kdbus_test_custom_endpoint(struct kdbus_test_env *env)
|
||||
ret = kdbus_name_release(env->conn, name);
|
||||
ASSERT_RETURN(ret == 0);
|
||||
|
||||
+ /* Check that the reader did not receive the name notification */
|
||||
+ ret = kdbus_msg_recv(reader, NULL, NULL);
|
||||
+ ASSERT_RETURN(ret == -EAGAIN);
|
||||
+
|
||||
ret = update_endpoint(ep_fd, name);
|
||||
ASSERT_RETURN(ret == 0);
|
||||
|
27
kdbus-kdbus_conn_connect-use-bus-instead-of-conn-ep-.patch
Normal file
27
kdbus-kdbus_conn_connect-use-bus-instead-of-conn-ep-.patch
Normal file
@ -0,0 +1,27 @@
|
||||
From: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Date: Tue, 2 Jun 2015 18:48:50 +0300
|
||||
Subject: [PATCH] kdbus: kdbus_conn_connect(): use `bus' instead of
|
||||
`conn->ep->bus'
|
||||
|
||||
Local `bus' is already set to `conn->ep->bus'. Use it.
|
||||
|
||||
Signed-off-by: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
ipc/kdbus/connection.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ipc/kdbus/connection.c b/ipc/kdbus/connection.c
|
||||
index 1bd7bb968f9f..707be050b408 100644
|
||||
--- a/ipc/kdbus/connection.c
|
||||
+++ b/ipc/kdbus/connection.c
|
||||
@@ -432,7 +432,7 @@ static int kdbus_conn_connect(struct kdbus_conn *conn, const char *name)
|
||||
* directly, and won't cause any notifications.
|
||||
*/
|
||||
if (!kdbus_conn_is_monitor(conn)) {
|
||||
- ret = kdbus_notify_id_change(conn->ep->bus, KDBUS_ITEM_ID_ADD,
|
||||
+ ret = kdbus_notify_id_change(bus, KDBUS_ITEM_ID_ADD,
|
||||
conn->id, conn->flags);
|
||||
if (ret < 0)
|
||||
goto exit_disconnect;
|
31
kdbus-kdbus_item_validate-remove-duplicated-code.patch
Normal file
31
kdbus-kdbus_item_validate-remove-duplicated-code.patch
Normal file
@ -0,0 +1,31 @@
|
||||
From: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Date: Tue, 2 Jun 2015 18:48:49 +0300
|
||||
Subject: [PATCH] kdbus: kdbus_item_validate(): remove duplicated code
|
||||
|
||||
KDBUS_ITEM_PAYLOAD_VEC and KDBUS_ITEM_PAYLOAD_OFF cases use literally
|
||||
the same code, so merge them.
|
||||
|
||||
Signed-off-by: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
ipc/kdbus/item.c | 6 ------
|
||||
1 file changed, 6 deletions(-)
|
||||
|
||||
diff --git a/ipc/kdbus/item.c b/ipc/kdbus/item.c
|
||||
index 745ad5495096..1ee72c2ad7c3 100644
|
||||
--- a/ipc/kdbus/item.c
|
||||
+++ b/ipc/kdbus/item.c
|
||||
@@ -96,12 +96,6 @@ int kdbus_item_validate(const struct kdbus_item *item)
|
||||
break;
|
||||
|
||||
case KDBUS_ITEM_PAYLOAD_VEC:
|
||||
- if (payload_size != sizeof(struct kdbus_vec))
|
||||
- return -EINVAL;
|
||||
- if (item->vec.size == 0 || item->vec.size > SIZE_MAX)
|
||||
- return -EINVAL;
|
||||
- break;
|
||||
-
|
||||
case KDBUS_ITEM_PAYLOAD_OFF:
|
||||
if (payload_size != sizeof(struct kdbus_vec))
|
||||
return -EINVAL;
|
42
kdbus-kdbus_reply_find-return-on-found-entry.patch
Normal file
42
kdbus-kdbus_reply_find-return-on-found-entry.patch
Normal file
@ -0,0 +1,42 @@
|
||||
From: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Date: Wed, 17 Jun 2015 20:14:56 +0300
|
||||
Subject: [PATCH] kdbus: kdbus_reply_find(): return on found entry
|
||||
|
||||
Return found entry immediately instead of assigning it to additional
|
||||
variable and breaking the loop. It's simpler to read, the same way is
|
||||
used in kdbus_conn_has_name(), for example.
|
||||
|
||||
Signed-off-by: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Reviewed-by: Djalal Harouni <tixxdz@opendz.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
ipc/kdbus/reply.c | 10 ++++------
|
||||
1 file changed, 4 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/ipc/kdbus/reply.c b/ipc/kdbus/reply.c
|
||||
index 89d355b44f63..9d823ebee71f 100644
|
||||
--- a/ipc/kdbus/reply.c
|
||||
+++ b/ipc/kdbus/reply.c
|
||||
@@ -171,17 +171,15 @@ struct kdbus_reply *kdbus_reply_find(struct kdbus_conn *replying,
|
||||
struct kdbus_conn *reply_dst,
|
||||
u64 cookie)
|
||||
{
|
||||
- struct kdbus_reply *r, *reply = NULL;
|
||||
+ struct kdbus_reply *r;
|
||||
|
||||
list_for_each_entry(r, &reply_dst->reply_list, entry) {
|
||||
if (r->cookie == cookie &&
|
||||
- (!replying || r->reply_src == replying)) {
|
||||
- reply = r;
|
||||
- break;
|
||||
- }
|
||||
+ (!replying || r->reply_src == replying))
|
||||
+ return r;
|
||||
}
|
||||
|
||||
- return reply;
|
||||
+ return NULL;
|
||||
}
|
||||
|
||||
/**
|
61
kdbus-make-metadata-on-broadcasts-reliable.patch
Normal file
61
kdbus-make-metadata-on-broadcasts-reliable.patch
Normal file
@ -0,0 +1,61 @@
|
||||
From: David Herrmann <dh.herrmann@gmail.com>
|
||||
Date: Tue, 26 May 2015 10:01:37 +0200
|
||||
Subject: [PATCH] kdbus: make metadata on broadcasts reliable
|
||||
|
||||
If we cannot collect metadata, this is a serious error. Don't try to
|
||||
continue sending a message, but immediately bail out and tell the receiver
|
||||
that we dropped it. Otherwise, the receiver cannot rely on metadata to be
|
||||
present and might assume it's a faked connection.
|
||||
|
||||
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Acked-by: Daniel Mack <daniel@zonque.org>
|
||||
---
|
||||
ipc/kdbus/bus.c | 28 ++++++++++++++--------------
|
||||
1 file changed, 14 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/ipc/kdbus/bus.c b/ipc/kdbus/bus.c
|
||||
index 9a0ecbc9df2f..d5475961b896 100644
|
||||
--- a/ipc/kdbus/bus.c
|
||||
+++ b/ipc/kdbus/bus.c
|
||||
@@ -293,12 +293,12 @@ void kdbus_bus_broadcast(struct kdbus_bus *bus,
|
||||
if (!kdbus_conn_policy_talk(conn_dst, NULL, conn_src))
|
||||
continue;
|
||||
|
||||
- /*
|
||||
- * Keep sending messages even if we cannot acquire the
|
||||
- * requested metadata. It's up to the receiver to drop
|
||||
- * messages that lack expected metadata.
|
||||
- */
|
||||
- kdbus_kmsg_collect_metadata(kmsg, conn_src, conn_dst);
|
||||
+ ret = kdbus_kmsg_collect_metadata(kmsg, conn_src,
|
||||
+ conn_dst);
|
||||
+ if (ret < 0) {
|
||||
+ kdbus_conn_lost_message(conn_dst);
|
||||
+ continue;
|
||||
+ }
|
||||
} else {
|
||||
/*
|
||||
* Check if there is a policy db that prevents the
|
||||
@@ -344,14 +344,14 @@ void kdbus_bus_eavesdrop(struct kdbus_bus *bus,
|
||||
|
||||
down_read(&bus->conn_rwlock);
|
||||
list_for_each_entry(conn_dst, &bus->monitors_list, monitor_entry) {
|
||||
- /*
|
||||
- * Collect metadata requested by the destination connection.
|
||||
- * Ignore errors, as receivers need to check metadata
|
||||
- * availability, anyway. So it's still better to send messages
|
||||
- * that lack data, than to skip it entirely.
|
||||
- */
|
||||
- if (conn_src)
|
||||
- kdbus_kmsg_collect_metadata(kmsg, conn_src, conn_dst);
|
||||
+ if (conn_src) {
|
||||
+ ret = kdbus_kmsg_collect_metadata(kmsg, conn_src,
|
||||
+ conn_dst);
|
||||
+ if (ret < 0) {
|
||||
+ kdbus_conn_lost_message(conn_dst);
|
||||
+ continue;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
ret = kdbus_conn_entry_insert(conn_src, conn_dst, kmsg, NULL);
|
||||
if (ret < 0)
|
67
kdbus-no-need-to-ref-current-mm.patch
Normal file
67
kdbus-no-need-to-ref-current-mm.patch
Normal file
@ -0,0 +1,67 @@
|
||||
From: David Herrmann <dh.herrmann@gmail.com>
|
||||
Date: Mon, 20 Apr 2015 11:13:54 +0200
|
||||
Subject: [PATCH] kdbus: no need to ref current->mm
|
||||
|
||||
If we access current->mm temporarily, there is no need to ref it. It can
|
||||
only be changed by us, so no-one can race with us.
|
||||
|
||||
Avoid ref'ing and unref'ing it just to access some of its fields, similar
|
||||
to what syscalls in mm/ do.
|
||||
|
||||
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
---
|
||||
ipc/kdbus/metadata.c | 21 +++------------------
|
||||
1 file changed, 3 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/ipc/kdbus/metadata.c b/ipc/kdbus/metadata.c
|
||||
index a85eac34a5c4..c36b9cc67637 100644
|
||||
--- a/ipc/kdbus/metadata.c
|
||||
+++ b/ipc/kdbus/metadata.c
|
||||
@@ -282,15 +282,10 @@ static void kdbus_meta_proc_collect_pid_comm(struct kdbus_meta_proc *mp)
|
||||
|
||||
static void kdbus_meta_proc_collect_exe(struct kdbus_meta_proc *mp)
|
||||
{
|
||||
- struct mm_struct *mm;
|
||||
struct file *exe_file;
|
||||
|
||||
- mm = get_task_mm(current);
|
||||
- if (!mm)
|
||||
- return;
|
||||
-
|
||||
rcu_read_lock();
|
||||
- exe_file = rcu_dereference(mm->exe_file);
|
||||
+ exe_file = rcu_dereference(current->mm->exe_file);
|
||||
if (exe_file) {
|
||||
mp->exe_path = exe_file->f_path;
|
||||
path_get(&mp->exe_path);
|
||||
@@ -298,28 +293,18 @@ static void kdbus_meta_proc_collect_exe(struct kdbus_meta_proc *mp)
|
||||
mp->valid |= KDBUS_ATTACH_EXE;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
-
|
||||
- mmput(mm);
|
||||
}
|
||||
|
||||
static int kdbus_meta_proc_collect_cmdline(struct kdbus_meta_proc *mp)
|
||||
{
|
||||
- struct mm_struct *mm;
|
||||
+ struct mm_struct *mm = current->mm;
|
||||
char *cmdline;
|
||||
|
||||
- mm = get_task_mm(current);
|
||||
- if (!mm)
|
||||
- return 0;
|
||||
-
|
||||
- if (!mm->arg_end) {
|
||||
- mmput(mm);
|
||||
+ if (!mm->arg_end)
|
||||
return 0;
|
||||
- }
|
||||
|
||||
cmdline = strndup_user((const char __user *)mm->arg_start,
|
||||
mm->arg_end - mm->arg_start);
|
||||
- mmput(mm);
|
||||
-
|
||||
if (IS_ERR(cmdline))
|
||||
return PTR_ERR(cmdline);
|
||||
|
50
kdbus-optimize-auxgroup-collector.patch
Normal file
50
kdbus-optimize-auxgroup-collector.patch
Normal file
@ -0,0 +1,50 @@
|
||||
From: David Herrmann <dh.herrmann@gmail.com>
|
||||
Date: Mon, 20 Apr 2015 10:53:35 +0200
|
||||
Subject: [PATCH] kdbus: optimize auxgroup collector
|
||||
|
||||
current->creds can only be changed by 'current'. That is, as long as we
|
||||
only access our own credentials, we can be sure it does not change. Hence,
|
||||
there is no need to ref cred->group_info if all we do is copy its content.
|
||||
|
||||
This avoids touching shared cachelines when collecting auxgroups.
|
||||
|
||||
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Acked-by: Daniel Mack <daniel@zonque.org>
|
||||
---
|
||||
ipc/kdbus/metadata.c | 10 ++++------
|
||||
1 file changed, 4 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/ipc/kdbus/metadata.c b/ipc/kdbus/metadata.c
|
||||
index eeebfef11552..174436f0aa01 100644
|
||||
--- a/ipc/kdbus/metadata.c
|
||||
+++ b/ipc/kdbus/metadata.c
|
||||
@@ -245,25 +245,23 @@ static void kdbus_meta_proc_collect_pids(struct kdbus_meta_proc *mp)
|
||||
|
||||
static int kdbus_meta_proc_collect_auxgroups(struct kdbus_meta_proc *mp)
|
||||
{
|
||||
- struct group_info *info;
|
||||
+ const struct group_info *info;
|
||||
size_t i;
|
||||
|
||||
- info = get_current_groups();
|
||||
+ /* no need to lock/ref, current creds cannot change */
|
||||
+ info = current_cred()->group_info;
|
||||
|
||||
if (info->ngroups > 0) {
|
||||
mp->auxgrps = kmalloc_array(info->ngroups, sizeof(kgid_t),
|
||||
GFP_KERNEL);
|
||||
- if (!mp->auxgrps) {
|
||||
- put_group_info(info);
|
||||
+ if (!mp->auxgrps)
|
||||
return -ENOMEM;
|
||||
- }
|
||||
|
||||
for (i = 0; i < info->ngroups; i++)
|
||||
mp->auxgrps[i] = GROUP_AT(info, i);
|
||||
}
|
||||
|
||||
mp->n_auxgrps = info->ngroups;
|
||||
- put_group_info(info);
|
||||
mp->valid |= KDBUS_ATTACH_AUXGROUPS;
|
||||
|
||||
return 0;
|
46
kdbus-optimize-error-path-in-kdbus_reply_new.patch
Normal file
46
kdbus-optimize-error-path-in-kdbus_reply_new.patch
Normal file
@ -0,0 +1,46 @@
|
||||
From: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Date: Wed, 17 Jun 2015 20:14:57 +0300
|
||||
Subject: [PATCH] kdbus: optimize error path in kdbus_reply_new()
|
||||
|
||||
Move cleanup code to separate location as it never executes on normal
|
||||
flow. This removes extra if-block and the need to initialize `ret'.
|
||||
|
||||
Signed-off-by: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Reviewed-by: Djalal Harouni <tixxdz@opendz.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
ipc/kdbus/reply.c | 12 +++++-------
|
||||
1 file changed, 5 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/ipc/kdbus/reply.c b/ipc/kdbus/reply.c
|
||||
index 9d823ebee71f..e6791d86ec92 100644
|
||||
--- a/ipc/kdbus/reply.c
|
||||
+++ b/ipc/kdbus/reply.c
|
||||
@@ -37,7 +37,7 @@ struct kdbus_reply *kdbus_reply_new(struct kdbus_conn *reply_src,
|
||||
bool sync)
|
||||
{
|
||||
struct kdbus_reply *r;
|
||||
- int ret = 0;
|
||||
+ int ret;
|
||||
|
||||
if (atomic_inc_return(&reply_dst->request_count) >
|
||||
KDBUS_CONN_MAX_REQUESTS_PENDING) {
|
||||
@@ -64,13 +64,11 @@ struct kdbus_reply *kdbus_reply_new(struct kdbus_conn *reply_src,
|
||||
r->waiting = true;
|
||||
}
|
||||
|
||||
-exit_dec_request_count:
|
||||
- if (ret < 0) {
|
||||
- atomic_dec(&reply_dst->request_count);
|
||||
- return ERR_PTR(ret);
|
||||
- }
|
||||
-
|
||||
return r;
|
||||
+
|
||||
+exit_dec_request_count:
|
||||
+ atomic_dec(&reply_dst->request_count);
|
||||
+ return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
static void __kdbus_reply_free(struct kref *kref)
|
48
kdbus-optimize-if-statements-in-kdbus_conn_disconnec.patch
Normal file
48
kdbus-optimize-if-statements-in-kdbus_conn_disconnec.patch
Normal file
@ -0,0 +1,48 @@
|
||||
From: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Date: Wed, 17 Jun 2015 20:14:58 +0300
|
||||
Subject: [PATCH] kdbus: optimize if statements in kdbus_conn_disconnect()
|
||||
|
||||
if (r->sync) branch and code after it both call kdbus_reply_unlink().
|
||||
Rewrite them as if-else to eliminate code duplication and make algorithm
|
||||
more obvious.
|
||||
|
||||
Convert outer if statement to use continue in order to reduce
|
||||
indentation and make things easier to read.
|
||||
|
||||
Signed-off-by: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Reviewed-by: Djalal Harouni <tixxdz@opendz.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
ipc/kdbus/connection.c | 15 +++++++--------
|
||||
1 file changed, 7 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/ipc/kdbus/connection.c b/ipc/kdbus/connection.c
|
||||
index 707be050b408..9993753d11de 100644
|
||||
--- a/ipc/kdbus/connection.c
|
||||
+++ b/ipc/kdbus/connection.c
|
||||
@@ -559,17 +559,16 @@ int kdbus_conn_disconnect(struct kdbus_conn *conn, bool ensure_queue_empty)
|
||||
hash_for_each(bus->conn_hash, i, c, hentry) {
|
||||
mutex_lock(&c->lock);
|
||||
list_for_each_entry_safe(r, r_tmp, &c->reply_list, entry) {
|
||||
- if (r->reply_src == conn) {
|
||||
- if (r->sync) {
|
||||
- kdbus_sync_reply_wakeup(r, -EPIPE);
|
||||
- kdbus_reply_unlink(r);
|
||||
- continue;
|
||||
- }
|
||||
+ if (r->reply_src != conn)
|
||||
+ continue;
|
||||
|
||||
+ if (r->sync)
|
||||
+ kdbus_sync_reply_wakeup(r, -EPIPE);
|
||||
+ else
|
||||
/* send a 'connection dead' notification */
|
||||
kdbus_notify_reply_dead(bus, c->id, r->cookie);
|
||||
- kdbus_reply_unlink(r);
|
||||
- }
|
||||
+
|
||||
+ kdbus_reply_unlink(r);
|
||||
}
|
||||
mutex_unlock(&c->lock);
|
||||
}
|
72
kdbus-pool-use-__vfs_read.patch
Normal file
72
kdbus-pool-use-__vfs_read.patch
Normal file
@ -0,0 +1,72 @@
|
||||
From: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Date: Tue, 21 Apr 2015 02:12:18 +0300
|
||||
Subject: [PATCH] kdbus: pool: use __vfs_read()
|
||||
|
||||
After commit 5d5d56897530 ("make new_sync_{read,write}() static")
|
||||
->read() cannot be called directly.
|
||||
|
||||
kdbus_pool_slice_copy() leads to oops, which can be reproduced by
|
||||
launching tools/testing/selftests/kdbus/kdbus-test -t message-quota:
|
||||
|
||||
[ 1167.146793] BUG: unable to handle kernel NULL pointer dereference at (null)
|
||||
[ 1167.147554] IP: [< (null)>] (null)
|
||||
[ 1167.148670] PGD 3a9dd067 PUD 3a841067 PMD 0
|
||||
[ 1167.149611] Oops: 0010 [#1] SMP
|
||||
[ 1167.150088] Modules linked in: nfsv3 nfs kdbus lockd grace sunrpc
|
||||
[ 1167.150771] CPU: 0 PID: 518 Comm: kdbus-test Not tainted 4.0.0-next-20150420-kdbus #62
|
||||
[ 1167.150771] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
|
||||
[ 1167.150771] task: ffff88003daed120 ti: ffff88003a800000 task.ti: ffff88003a800000
|
||||
[ 1167.150771] RIP: 0010:[<0000000000000000>] [< (null)>] (null)
|
||||
[ 1167.150771] RSP: 0018:ffff88003a803bc0 EFLAGS: 00010286
|
||||
[ 1167.150771] RAX: ffff8800377fb000 RBX: 00000000000201e8 RCX: ffff88003a803c00
|
||||
[ 1167.150771] RDX: 0000000000000b40 RSI: ffff8800377fb4c0 RDI: ffff88003d815700
|
||||
[ 1167.150771] RBP: ffff88003a803c48 R08: ffffffff8139e380 R09: ffff880039d80490
|
||||
[ 1167.150771] R10: ffff88003a803a90 R11: 00000000000004c0 R12: 00000000002a24c0
|
||||
[ 1167.150771] R13: 0000000000000b40 R14: ffff88003d815700 R15: ffffffff8139e460
|
||||
[ 1167.150771] FS: 00007f41dccd4740(0000) GS:ffff88003fc00000(0000) knlGS:0000000000000000
|
||||
[ 1167.150771] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
|
||||
[ 1167.150771] CR2: 0000000000000000 CR3: 000000003ccdf000 CR4: 00000000000007b0
|
||||
[ 1167.150771] Stack:
|
||||
[ 1167.150771] ffffffffa0065497 ffff88003a803c10 00007ffffffff000 ffff88003aaa67c0
|
||||
[ 1167.150771] 00000000000004c0 ffff88003aaa6870 ffff88003ca83300 ffffffffa006537d
|
||||
[ 1167.150771] 00000000000201e8 ffffea0000ddfec0 ffff88003a803c20 0000000000000018
|
||||
[ 1167.150771] Call Trace:
|
||||
[ 1167.150771] [<ffffffffa0065497>] ? kdbus_pool_slice_copy+0x127/0x200 [kdbus]
|
||||
[ 1167.150771] [<ffffffffa006537d>] ? kdbus_pool_slice_copy+0xd/0x200 [kdbus]
|
||||
[ 1167.150771] [<ffffffffa006670a>] kdbus_queue_entry_move+0xaa/0x180 [kdbus]
|
||||
[ 1167.150771] [<ffffffffa0059e64>] kdbus_conn_move_messages+0x1e4/0x2c0 [kdbus]
|
||||
[ 1167.150771] [<ffffffffa006234e>] kdbus_name_acquire+0x31e/0x390 [kdbus]
|
||||
[ 1167.150771] [<ffffffffa00625c5>] kdbus_cmd_name_acquire+0x125/0x130 [kdbus]
|
||||
[ 1167.150771] [<ffffffffa005db5d>] kdbus_handle_ioctl+0x4ed/0x610 [kdbus]
|
||||
[ 1167.150771] [<ffffffff811040e0>] do_vfs_ioctl+0x2e0/0x4e0
|
||||
[ 1167.150771] [<ffffffff81389750>] ? preempt_schedule_common+0x1f/0x3f
|
||||
[ 1167.150771] [<ffffffff8110431c>] SyS_ioctl+0x3c/0x80
|
||||
[ 1167.150771] [<ffffffff8138c36e>] system_call_fastpath+0x12/0x71
|
||||
[ 1167.150771] Code: Bad RIP value.
|
||||
[ 1167.150771] RIP [< (null)>] (null)
|
||||
[ 1167.150771] RSP <ffff88003a803bc0>
|
||||
[ 1167.150771] CR2: 0000000000000000
|
||||
[ 1167.168756] ---[ end trace a676bcfa75db5a96 ]---
|
||||
|
||||
Use __vfs_read() instead.
|
||||
|
||||
Signed-off-by: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
ipc/kdbus/pool.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ipc/kdbus/pool.c b/ipc/kdbus/pool.c
|
||||
index 139bb77056b3..45dcdea505f4 100644
|
||||
--- a/ipc/kdbus/pool.c
|
||||
+++ b/ipc/kdbus/pool.c
|
||||
@@ -675,7 +675,7 @@ int kdbus_pool_slice_copy(const struct kdbus_pool_slice *slice_dst,
|
||||
}
|
||||
|
||||
kaddr = (char __force __user *)kmap(page) + page_off;
|
||||
- n_read = f_src->f_op->read(f_src, kaddr, copy_len, &off_src);
|
||||
+ n_read = __vfs_read(f_src, kaddr, copy_len, &off_src);
|
||||
kunmap(page);
|
||||
mark_page_accessed(page);
|
||||
flush_dcache_page(page);
|
195
kdbus-provide-helper-to-collect-metadata.patch
Normal file
195
kdbus-provide-helper-to-collect-metadata.patch
Normal file
@ -0,0 +1,195 @@
|
||||
From: David Herrmann <dh.herrmann@gmail.com>
|
||||
Date: Tue, 26 May 2015 09:59:02 +0200
|
||||
Subject: [PATCH] kdbus: provide helper to collect metadata
|
||||
|
||||
Provide a new helper kdbus_kmsg_collect_metadata() which implements the
|
||||
common task of collecting proc- and conn-metadata on a kmsg.
|
||||
|
||||
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Acked-by: Daniel Mack <daniel@zonque.org>
|
||||
---
|
||||
ipc/kdbus/bus.c | 24 +++---------------------
|
||||
ipc/kdbus/connection.c | 35 ++++-------------------------------
|
||||
ipc/kdbus/message.c | 24 ++++++++++++++++++++++++
|
||||
ipc/kdbus/message.h | 2 ++
|
||||
4 files changed, 33 insertions(+), 52 deletions(-)
|
||||
|
||||
diff --git a/ipc/kdbus/bus.c b/ipc/kdbus/bus.c
|
||||
index 9d0679eb59f6..9a0ecbc9df2f 100644
|
||||
--- a/ipc/kdbus/bus.c
|
||||
+++ b/ipc/kdbus/bus.c
|
||||
@@ -285,8 +285,6 @@ void kdbus_bus_broadcast(struct kdbus_bus *bus,
|
||||
continue;
|
||||
|
||||
if (conn_src) {
|
||||
- u64 attach_flags;
|
||||
-
|
||||
/*
|
||||
* Anyone can send broadcasts, as they have no
|
||||
* destination. But a receiver needs TALK access to
|
||||
@@ -295,19 +293,12 @@ void kdbus_bus_broadcast(struct kdbus_bus *bus,
|
||||
if (!kdbus_conn_policy_talk(conn_dst, NULL, conn_src))
|
||||
continue;
|
||||
|
||||
- attach_flags = kdbus_meta_calc_attach_flags(conn_src,
|
||||
- conn_dst);
|
||||
-
|
||||
/*
|
||||
* Keep sending messages even if we cannot acquire the
|
||||
* requested metadata. It's up to the receiver to drop
|
||||
* messages that lack expected metadata.
|
||||
*/
|
||||
- if (!conn_src->faked_meta)
|
||||
- kdbus_meta_proc_collect(kmsg->proc_meta,
|
||||
- attach_flags);
|
||||
- kdbus_meta_conn_collect(kmsg->conn_meta, kmsg, conn_src,
|
||||
- attach_flags);
|
||||
+ kdbus_kmsg_collect_metadata(kmsg, conn_src, conn_dst);
|
||||
} else {
|
||||
/*
|
||||
* Check if there is a policy db that prevents the
|
||||
@@ -359,17 +350,8 @@ void kdbus_bus_eavesdrop(struct kdbus_bus *bus,
|
||||
* availability, anyway. So it's still better to send messages
|
||||
* that lack data, than to skip it entirely.
|
||||
*/
|
||||
- if (conn_src) {
|
||||
- u64 attach_flags;
|
||||
-
|
||||
- attach_flags = kdbus_meta_calc_attach_flags(conn_src,
|
||||
- conn_dst);
|
||||
- if (!conn_src->faked_meta)
|
||||
- kdbus_meta_proc_collect(kmsg->proc_meta,
|
||||
- attach_flags);
|
||||
- kdbus_meta_conn_collect(kmsg->conn_meta, kmsg, conn_src,
|
||||
- attach_flags);
|
||||
- }
|
||||
+ if (conn_src)
|
||||
+ kdbus_kmsg_collect_metadata(kmsg, conn_src, conn_dst);
|
||||
|
||||
ret = kdbus_conn_entry_insert(conn_src, conn_dst, kmsg, NULL);
|
||||
if (ret < 0)
|
||||
diff --git a/ipc/kdbus/connection.c b/ipc/kdbus/connection.c
|
||||
index 272b991f36f4..cbfbf3847c24 100644
|
||||
--- a/ipc/kdbus/connection.c
|
||||
+++ b/ipc/kdbus/connection.c
|
||||
@@ -1098,7 +1098,6 @@ static int kdbus_conn_reply(struct kdbus_conn *src, struct kdbus_kmsg *kmsg)
|
||||
struct kdbus_reply *reply, *wake = NULL;
|
||||
struct kdbus_conn *dst = NULL;
|
||||
struct kdbus_bus *bus = src->ep->bus;
|
||||
- u64 attach;
|
||||
int ret;
|
||||
|
||||
if (WARN_ON(kmsg->msg.dst_id == KDBUS_DST_ID_BROADCAST) ||
|
||||
@@ -1131,15 +1130,7 @@ static int kdbus_conn_reply(struct kdbus_conn *src, struct kdbus_kmsg *kmsg)
|
||||
|
||||
/* attach metadata */
|
||||
|
||||
- attach = kdbus_meta_calc_attach_flags(src, dst);
|
||||
-
|
||||
- if (!src->faked_meta) {
|
||||
- ret = kdbus_meta_proc_collect(kmsg->proc_meta, attach);
|
||||
- if (ret < 0)
|
||||
- goto exit;
|
||||
- }
|
||||
-
|
||||
- ret = kdbus_meta_conn_collect(kmsg->conn_meta, kmsg, src, attach);
|
||||
+ ret = kdbus_kmsg_collect_metadata(kmsg, src, dst);
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
|
||||
@@ -1167,7 +1158,6 @@ static struct kdbus_reply *kdbus_conn_call(struct kdbus_conn *src,
|
||||
struct kdbus_reply *wait = NULL;
|
||||
struct kdbus_conn *dst = NULL;
|
||||
struct kdbus_bus *bus = src->ep->bus;
|
||||
- u64 attach;
|
||||
int ret;
|
||||
|
||||
if (WARN_ON(kmsg->msg.dst_id == KDBUS_DST_ID_BROADCAST) ||
|
||||
@@ -1218,15 +1208,7 @@ static struct kdbus_reply *kdbus_conn_call(struct kdbus_conn *src,
|
||||
|
||||
/* attach metadata */
|
||||
|
||||
- attach = kdbus_meta_calc_attach_flags(src, dst);
|
||||
-
|
||||
- if (!src->faked_meta) {
|
||||
- ret = kdbus_meta_proc_collect(kmsg->proc_meta, attach);
|
||||
- if (ret < 0)
|
||||
- goto exit;
|
||||
- }
|
||||
-
|
||||
- ret = kdbus_meta_conn_collect(kmsg->conn_meta, kmsg, src, attach);
|
||||
+ ret = kdbus_kmsg_collect_metadata(kmsg, src, dst);
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
|
||||
@@ -1257,7 +1239,6 @@ static int kdbus_conn_unicast(struct kdbus_conn *src, struct kdbus_kmsg *kmsg)
|
||||
struct kdbus_conn *dst = NULL;
|
||||
struct kdbus_bus *bus = src->ep->bus;
|
||||
bool is_signal = (kmsg->msg.flags & KDBUS_MSG_SIGNAL);
|
||||
- u64 attach;
|
||||
int ret = 0;
|
||||
|
||||
if (WARN_ON(kmsg->msg.dst_id == KDBUS_DST_ID_BROADCAST) ||
|
||||
@@ -1296,16 +1277,8 @@ static int kdbus_conn_unicast(struct kdbus_conn *src, struct kdbus_kmsg *kmsg)
|
||||
|
||||
/* attach metadata */
|
||||
|
||||
- attach = kdbus_meta_calc_attach_flags(src, dst);
|
||||
-
|
||||
- if (!src->faked_meta) {
|
||||
- ret = kdbus_meta_proc_collect(kmsg->proc_meta, attach);
|
||||
- if (ret < 0 && !is_signal)
|
||||
- goto exit;
|
||||
- }
|
||||
-
|
||||
- ret = kdbus_meta_conn_collect(kmsg->conn_meta, kmsg, src, attach);
|
||||
- if (ret < 0 && !is_signal)
|
||||
+ ret = kdbus_kmsg_collect_metadata(kmsg, src, dst);
|
||||
+ if (ret < 0)
|
||||
goto exit;
|
||||
|
||||
/* send message */
|
||||
diff --git a/ipc/kdbus/message.c b/ipc/kdbus/message.c
|
||||
index 80960756a329..066e816dfdea 100644
|
||||
--- a/ipc/kdbus/message.c
|
||||
+++ b/ipc/kdbus/message.c
|
||||
@@ -614,3 +614,27 @@ exit_free:
|
||||
kdbus_kmsg_free(m);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
+
|
||||
+/**
|
||||
+ * kdbus_kmsg_collect_metadata() - collect metadata
|
||||
+ * @kmsg: message to collect metadata on
|
||||
+ * @src: source connection of message
|
||||
+ * @dst: destination connection of message
|
||||
+ *
|
||||
+ * Return: 0 on success, negative error code on failure.
|
||||
+ */
|
||||
+int kdbus_kmsg_collect_metadata(struct kdbus_kmsg *kmsg, struct kdbus_conn *src,
|
||||
+ struct kdbus_conn *dst)
|
||||
+{
|
||||
+ u64 attach;
|
||||
+ int ret;
|
||||
+
|
||||
+ attach = kdbus_meta_calc_attach_flags(src, dst);
|
||||
+ if (!src->faked_meta) {
|
||||
+ ret = kdbus_meta_proc_collect(kmsg->proc_meta, attach);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return kdbus_meta_conn_collect(kmsg->conn_meta, kmsg, src, attach);
|
||||
+}
|
||||
diff --git a/ipc/kdbus/message.h b/ipc/kdbus/message.h
|
||||
index af4775850235..cdaa65c4e6ae 100644
|
||||
--- a/ipc/kdbus/message.h
|
||||
+++ b/ipc/kdbus/message.h
|
||||
@@ -129,5 +129,7 @@ struct kdbus_kmsg *kdbus_kmsg_new(struct kdbus_bus *bus, size_t extra_size);
|
||||
struct kdbus_kmsg *kdbus_kmsg_new_from_cmd(struct kdbus_conn *conn,
|
||||
struct kdbus_cmd_send *cmd_send);
|
||||
void kdbus_kmsg_free(struct kdbus_kmsg *kmsg);
|
||||
+int kdbus_kmsg_collect_metadata(struct kdbus_kmsg *kmsg, struct kdbus_conn *src,
|
||||
+ struct kdbus_conn *dst);
|
||||
|
||||
#endif
|
276
kdbus-reduce-scope-of-handle-locking.patch
Normal file
276
kdbus-reduce-scope-of-handle-locking.patch
Normal file
@ -0,0 +1,276 @@
|
||||
From: David Herrmann <dh.herrmann@gmail.com>
|
||||
Date: Sat, 18 Apr 2015 12:39:51 +0200
|
||||
Subject: [PATCH] kdbus: reduce scope of handle locking
|
||||
|
||||
A kdbus handle is used to create objects in the kdbus hierarchy. During
|
||||
open(), we do not have enough information to know how to setup the object.
|
||||
Therefore, we provide setup ioctls, which allow user-space to pass in
|
||||
parameters and options how the to-be-created object should behave. Once
|
||||
setup is done, we allow user-space to use ioctls to operate on that newly
|
||||
created object.
|
||||
|
||||
It is important to notice:
|
||||
1) Only one setup ioctl can ever be called on a handle. You cannot call
|
||||
multiple, different setup ioctls on the same handle.
|
||||
2) A setup ioctl can only be called once, if it succeeded. If it failed,
|
||||
it must not modify the handle in any way. If it succeeded, no further
|
||||
setup ioctl can be issued.
|
||||
3) After a setup ioctl is done, the handle is constant and must not be
|
||||
modified in any way.
|
||||
|
||||
So far, we used a write-lock around all setup ioctls, and a read-lock
|
||||
around everything else. The handle setup-indicator (the type field) can
|
||||
only be set under the write-lock. Whenever you access the handle under a
|
||||
read-lock, you must verify it was set before, otherwise, you must bail out
|
||||
as the handle was not initialized, yet.
|
||||
|
||||
This has the downside that we need a read-lock on all operations on the
|
||||
handle. For performance reasons, we should avoid that. This patch turns
|
||||
the rwlock into a mutex and removes the read-side lock from all paths. It
|
||||
relies on the 3 behaviors described above.
|
||||
|
||||
With this patch, the mutex is only taken around setup ioctls. Furthermore,
|
||||
the setup-indicator (the type field) is only ever set if the mutex is
|
||||
held. The mutex guarantees that multiple setup ioctls cannot race, and
|
||||
also, that only one setup ioctl will ever succeed. If a setup ioctl is
|
||||
called after setup was already finished, we do not touch the handle at all
|
||||
and immediately fail.
|
||||
|
||||
Furthermore, all other operations (non-setup operations) can only be
|
||||
called once setup is done. Therefore, we must synchronize them with any
|
||||
racing setup, otherwise, they might access the handle which is currently
|
||||
modified by setup.
|
||||
We protect from this race by setting the setup-indicator (the type field)
|
||||
_last_, and issue a write-barrier before setting it. Once it is set, we
|
||||
never modify the handle ever again; it is constant from now on until
|
||||
file-release.
|
||||
Hence, on the read-side we simply read the type field and issue a
|
||||
read-barrier afterwards. _Iff_ the type field was not set, yet, we must
|
||||
not access the handle in any way, but bail out immediately. Setup was not
|
||||
done, yet. But if the type field was set, the read-barrier pairs with the
|
||||
write-barrier during setup. All member fields of the handle object are
|
||||
guaranteed to be accessible by us, as the type-field is always the last
|
||||
field that is written.
|
||||
|
||||
With this in place, we reduce the locking-overhead of all non-setup ioctls
|
||||
to a read-barrier, instead of a read-side lock. And in combination with
|
||||
the follow-up that removes the active-refs from kdbus_handle_poll(), we're
|
||||
now lock-free in ->poll and ->mmap callbacks.
|
||||
|
||||
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Acked-by: Daniel Mack <daniel@zonque.org>
|
||||
---
|
||||
ipc/kdbus/handle.c | 110 ++++++++++++++++++++++++++++++++++++++++-------------
|
||||
1 file changed, 83 insertions(+), 27 deletions(-)
|
||||
|
||||
diff --git a/ipc/kdbus/handle.c b/ipc/kdbus/handle.c
|
||||
index 3f5d8085a297..a3e01383a6f6 100644
|
||||
--- a/ipc/kdbus/handle.c
|
||||
+++ b/ipc/kdbus/handle.c
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/kdev_t.h>
|
||||
#include <linux/module.h>
|
||||
+#include <linux/mutex.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/rwsem.h>
|
||||
#include <linux/sched.h>
|
||||
@@ -229,7 +230,7 @@ enum kdbus_handle_type {
|
||||
|
||||
/**
|
||||
* struct kdbus_handle - handle to the kdbus system
|
||||
- * @rwlock: handle lock
|
||||
+ * @lock: handle lock
|
||||
* @type: type of this handle (KDBUS_HANDLE_*)
|
||||
* @bus_owner: bus this handle owns
|
||||
* @ep_owner: endpoint this handle owns
|
||||
@@ -237,7 +238,7 @@ enum kdbus_handle_type {
|
||||
* @privileged: Flag to mark a handle as privileged
|
||||
*/
|
||||
struct kdbus_handle {
|
||||
- struct rw_semaphore rwlock;
|
||||
+ struct mutex lock;
|
||||
|
||||
enum kdbus_handle_type type;
|
||||
union {
|
||||
@@ -265,7 +266,7 @@ static int kdbus_handle_open(struct inode *inode, struct file *file)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
- init_rwsem(&handle->rwlock);
|
||||
+ mutex_init(&handle->lock);
|
||||
handle->type = KDBUS_HANDLE_NONE;
|
||||
|
||||
if (node->type == KDBUS_NODE_ENDPOINT) {
|
||||
@@ -355,8 +356,8 @@ static long kdbus_handle_ioctl_control(struct file *file, unsigned int cmd,
|
||||
break;
|
||||
}
|
||||
|
||||
- handle->type = KDBUS_HANDLE_BUS_OWNER;
|
||||
handle->bus_owner = bus;
|
||||
+ ret = KDBUS_HANDLE_BUS_OWNER;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -396,8 +397,8 @@ static long kdbus_handle_ioctl_ep(struct file *file, unsigned int cmd,
|
||||
break;
|
||||
}
|
||||
|
||||
- handle->type = KDBUS_HANDLE_EP_OWNER;
|
||||
handle->ep_owner = ep;
|
||||
+ ret = KDBUS_HANDLE_EP_OWNER;
|
||||
break;
|
||||
|
||||
case KDBUS_CMD_HELLO:
|
||||
@@ -407,8 +408,8 @@ static long kdbus_handle_ioctl_ep(struct file *file, unsigned int cmd,
|
||||
break;
|
||||
}
|
||||
|
||||
- handle->type = KDBUS_HANDLE_CONNECTED;
|
||||
handle->conn = conn;
|
||||
+ ret = KDBUS_HANDLE_CONNECTED;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -522,19 +523,41 @@ static long kdbus_handle_ioctl(struct file *file, unsigned int cmd,
|
||||
case KDBUS_CMD_BUS_MAKE:
|
||||
case KDBUS_CMD_ENDPOINT_MAKE:
|
||||
case KDBUS_CMD_HELLO:
|
||||
- /* bail out early if already typed */
|
||||
- if (handle->type != KDBUS_HANDLE_NONE)
|
||||
- break;
|
||||
-
|
||||
- down_write(&handle->rwlock);
|
||||
+ mutex_lock(&handle->lock);
|
||||
if (handle->type == KDBUS_HANDLE_NONE) {
|
||||
if (node->type == KDBUS_NODE_CONTROL)
|
||||
ret = kdbus_handle_ioctl_control(file, cmd,
|
||||
argp);
|
||||
else if (node->type == KDBUS_NODE_ENDPOINT)
|
||||
ret = kdbus_handle_ioctl_ep(file, cmd, argp);
|
||||
+
|
||||
+ if (ret > 0) {
|
||||
+ /*
|
||||
+ * The data given via open() is not sufficient
|
||||
+ * to setup a kdbus handle. Hence, we require
|
||||
+ * the user to perform a setup ioctl. This setup
|
||||
+ * can only be performed once and defines the
|
||||
+ * type of the handle. The different setup
|
||||
+ * ioctls are locked against each other so they
|
||||
+ * cannot race. Once the handle type is set,
|
||||
+ * the type-dependent ioctls are enabled. To
|
||||
+ * improve performance, we don't lock those via
|
||||
+ * handle->lock. Instead, we issue a
|
||||
+ * write-barrier before performing the
|
||||
+ * type-change, which pairs with smp_rmb() in
|
||||
+ * all handlers that access the type field. This
|
||||
+ * guarantees the handle is fully setup, if
|
||||
+ * handle->type is set. If handle->type is
|
||||
+ * unset, you must not make any assumptions
|
||||
+ * without taking handle->lock.
|
||||
+ * Note that handle->type is only set once. It
|
||||
+ * will never change afterwards.
|
||||
+ */
|
||||
+ smp_wmb();
|
||||
+ handle->type = ret;
|
||||
+ }
|
||||
}
|
||||
- up_write(&handle->rwlock);
|
||||
+ mutex_unlock(&handle->lock);
|
||||
break;
|
||||
|
||||
case KDBUS_CMD_ENDPOINT_UPDATE:
|
||||
@@ -549,14 +572,30 @@ static long kdbus_handle_ioctl(struct file *file, unsigned int cmd,
|
||||
case KDBUS_CMD_MATCH_REMOVE:
|
||||
case KDBUS_CMD_SEND:
|
||||
case KDBUS_CMD_RECV:
|
||||
- case KDBUS_CMD_FREE:
|
||||
- down_read(&handle->rwlock);
|
||||
- if (handle->type == KDBUS_HANDLE_EP_OWNER)
|
||||
+ case KDBUS_CMD_FREE: {
|
||||
+ enum kdbus_handle_type type;
|
||||
+
|
||||
+ /*
|
||||
+ * This read-barrier pairs with smp_wmb() of the handle setup.
|
||||
+ * it guarantees the handle is fully written, in case the
|
||||
+ * type has been set. It allows us to access the handle without
|
||||
+ * taking handle->lock, given the guarantee that the type is
|
||||
+ * only ever set once, and stays constant afterwards.
|
||||
+ * Furthermore, the handle object itself is not modified in any
|
||||
+ * way after the type is set. That is, the type-field is the
|
||||
+ * last field that is written on any handle. If it has not been
|
||||
+ * set, we must not access the handle here.
|
||||
+ */
|
||||
+ type = handle->type;
|
||||
+ smp_rmb();
|
||||
+
|
||||
+ if (type == KDBUS_HANDLE_EP_OWNER)
|
||||
ret = kdbus_handle_ioctl_ep_owner(file, cmd, argp);
|
||||
- else if (handle->type == KDBUS_HANDLE_CONNECTED)
|
||||
+ else if (type == KDBUS_HANDLE_CONNECTED)
|
||||
ret = kdbus_handle_ioctl_connected(file, cmd, argp);
|
||||
- up_read(&handle->rwlock);
|
||||
+
|
||||
break;
|
||||
+ }
|
||||
default:
|
||||
ret = -ENOTTY;
|
||||
break;
|
||||
@@ -569,16 +608,23 @@ static unsigned int kdbus_handle_poll(struct file *file,
|
||||
struct poll_table_struct *wait)
|
||||
{
|
||||
struct kdbus_handle *handle = file->private_data;
|
||||
+ enum kdbus_handle_type type;
|
||||
unsigned int mask = POLLOUT | POLLWRNORM;
|
||||
int ret;
|
||||
|
||||
+ /*
|
||||
+ * This pairs with smp_wmb() during handle setup. It guarantees that
|
||||
+ * _iff_ the handle type is set, handle->conn is valid. Furthermore,
|
||||
+ * _iff_ the type is set, the handle object is constant and never
|
||||
+ * changed again. If it's not set, we must not access the handle but
|
||||
+ * bail out. We also must assume no setup has taken place, yet.
|
||||
+ */
|
||||
+ type = handle->type;
|
||||
+ smp_rmb();
|
||||
+
|
||||
/* Only a connected endpoint can read/write data */
|
||||
- down_read(&handle->rwlock);
|
||||
- if (handle->type != KDBUS_HANDLE_CONNECTED) {
|
||||
- up_read(&handle->rwlock);
|
||||
+ if (type != KDBUS_HANDLE_CONNECTED)
|
||||
return POLLERR | POLLHUP;
|
||||
- }
|
||||
- up_read(&handle->rwlock);
|
||||
|
||||
ret = kdbus_conn_acquire(handle->conn);
|
||||
if (ret < 0)
|
||||
@@ -598,13 +644,23 @@ static unsigned int kdbus_handle_poll(struct file *file,
|
||||
static int kdbus_handle_mmap(struct file *file, struct vm_area_struct *vma)
|
||||
{
|
||||
struct kdbus_handle *handle = file->private_data;
|
||||
+ enum kdbus_handle_type type;
|
||||
int ret = -EBADFD;
|
||||
|
||||
- if (down_read_trylock(&handle->rwlock)) {
|
||||
- if (handle->type == KDBUS_HANDLE_CONNECTED)
|
||||
- ret = kdbus_pool_mmap(handle->conn->pool, vma);
|
||||
- up_read(&handle->rwlock);
|
||||
- }
|
||||
+ /*
|
||||
+ * This pairs with smp_wmb() during handle setup. It guarantees that
|
||||
+ * _iff_ the handle type is set, handle->conn is valid. Furthermore,
|
||||
+ * _iff_ the type is set, the handle object is constant and never
|
||||
+ * changed again. If it's not set, we must not access the handle but
|
||||
+ * bail out. We also must assume no setup has taken place, yet.
|
||||
+ */
|
||||
+ type = handle->type;
|
||||
+ smp_rmb();
|
||||
+
|
||||
+ /* Only connected handles have a pool we can map */
|
||||
+ if (type == KDBUS_HANDLE_CONNECTED)
|
||||
+ ret = kdbus_pool_mmap(handle->conn->pool, vma);
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
40
kdbus-remove-redundant-code-from-kdbus_conn_entry_ma.patch
Normal file
40
kdbus-remove-redundant-code-from-kdbus_conn_entry_ma.patch
Normal file
@ -0,0 +1,40 @@
|
||||
From: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Date: Tue, 2 Jun 2015 18:48:48 +0300
|
||||
Subject: [PATCH] kdbus: remove redundant code from kdbus_conn_entry_make()
|
||||
|
||||
We don't need to check `entry' for error, as in either case it is
|
||||
returned as is. Return result of kdbus_queue_entry_new() directly.
|
||||
|
||||
Signed-off-by: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
ipc/kdbus/connection.c | 8 +-------
|
||||
1 file changed, 1 insertion(+), 7 deletions(-)
|
||||
|
||||
diff --git a/ipc/kdbus/connection.c b/ipc/kdbus/connection.c
|
||||
index 8ee62fc0bd46..1bd7bb968f9f 100644
|
||||
--- a/ipc/kdbus/connection.c
|
||||
+++ b/ipc/kdbus/connection.c
|
||||
@@ -775,8 +775,6 @@ kdbus_conn_entry_make(struct kdbus_conn *conn_dst,
|
||||
const struct kdbus_kmsg *kmsg,
|
||||
struct kdbus_user *user)
|
||||
{
|
||||
- struct kdbus_queue_entry *entry;
|
||||
-
|
||||
/* The remote connection was disconnected */
|
||||
if (!kdbus_conn_active(conn_dst))
|
||||
return ERR_PTR(-ECONNRESET);
|
||||
@@ -793,11 +791,7 @@ kdbus_conn_entry_make(struct kdbus_conn *conn_dst,
|
||||
kmsg->res && kmsg->res->fds_count > 0)
|
||||
return ERR_PTR(-ECOMM);
|
||||
|
||||
- entry = kdbus_queue_entry_new(conn_dst, kmsg, user);
|
||||
- if (IS_ERR(entry))
|
||||
- return entry;
|
||||
-
|
||||
- return entry;
|
||||
+ return kdbus_queue_entry_new(conn_dst, kmsg, user);
|
||||
}
|
||||
|
||||
/*
|
25
kdbus-remove-unused-linux-version.h-include.patch
Normal file
25
kdbus-remove-unused-linux-version.h-include.patch
Normal file
@ -0,0 +1,25 @@
|
||||
From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
|
||||
Date: Thu, 16 Apr 2015 21:07:18 +0800
|
||||
Subject: [PATCH] kdbus: remove unused linux/version.h include
|
||||
|
||||
Remove <linux/version.h> include, it's not needed.
|
||||
|
||||
Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
|
||||
Acked-by: Daniel Mack <daniel@zonque.org>
|
||||
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
---
|
||||
ipc/kdbus/metadata.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/ipc/kdbus/metadata.c b/ipc/kdbus/metadata.c
|
||||
index 3adc6c2c2e76..eeebfef11552 100644
|
||||
--- a/ipc/kdbus/metadata.c
|
||||
+++ b/ipc/kdbus/metadata.c
|
||||
@@ -29,7 +29,6 @@
|
||||
#include <linux/uidgid.h>
|
||||
#include <linux/uio.h>
|
||||
#include <linux/user_namespace.h>
|
||||
-#include <linux/version.h>
|
||||
|
||||
#include "bus.h"
|
||||
#include "connection.h"
|
23
kdbus-samples-kdbus-add-lrt.patch
Normal file
23
kdbus-samples-kdbus-add-lrt.patch
Normal file
@ -0,0 +1,23 @@
|
||||
From: David Herrmann <dh.herrmann@gmail.com>
|
||||
Date: Thu, 12 Mar 2015 17:27:31 +0100
|
||||
Subject: [PATCH] kdbus: samples/kdbus: add -lrt
|
||||
|
||||
On older systems -lrt is needed for clock_gettime(). Add it to
|
||||
HOSTLOADLIBES of kdbus-workers so it builds fine on those systems.
|
||||
|
||||
Reported-by: Sasha Levin <sasha.levin@oracle.com>
|
||||
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
samples/kdbus/Makefile | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/samples/kdbus/Makefile b/samples/kdbus/Makefile
|
||||
index d009025369f4..eee9b9aed632 100644
|
||||
--- a/samples/kdbus/Makefile
|
||||
+++ b/samples/kdbus/Makefile
|
||||
@@ -8,3 +8,4 @@ always := $(hostprogs-y)
|
||||
HOSTCFLAGS_kdbus-workers.o += \
|
||||
-I$(objtree)/usr/include/ \
|
||||
-I$(objtree)/include/uapi/
|
||||
+HOSTLOADLIBES_kdbus-workers := -lrt
|
24
kdbus-selftests-add-build-dependencies-on-headers.patch
Normal file
24
kdbus-selftests-add-build-dependencies-on-headers.patch
Normal file
@ -0,0 +1,24 @@
|
||||
From: David Herrmann <dh.herrmann@gmail.com>
|
||||
Date: Wed, 3 Jun 2015 17:53:29 +0200
|
||||
Subject: [PATCH] kdbus/selftests: add build-dependencies on headers
|
||||
|
||||
Make sure the selftests are re-built if one of the local headers changes.
|
||||
|
||||
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
---
|
||||
tools/testing/selftests/kdbus/Makefile | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tools/testing/selftests/kdbus/Makefile b/tools/testing/selftests/kdbus/Makefile
|
||||
index 076f9f40566d..7ad587b3c767 100644
|
||||
--- a/tools/testing/selftests/kdbus/Makefile
|
||||
+++ b/tools/testing/selftests/kdbus/Makefile
|
||||
@@ -34,7 +34,7 @@ all: kdbus-test
|
||||
|
||||
include ../lib.mk
|
||||
|
||||
-%.o: %.c
|
||||
+%.o: %.c kdbus-enum.h kdbus-test.h kdbus-util.h
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
kdbus-test: $(OBJS)
|
63
kdbus-skip-acquiring-an-active-reference-in-poll.patch
Normal file
63
kdbus-skip-acquiring-an-active-reference-in-poll.patch
Normal file
@ -0,0 +1,63 @@
|
||||
From: David Herrmann <dh.herrmann@gmail.com>
|
||||
Date: Sat, 18 Apr 2015 13:04:42 +0200
|
||||
Subject: [PATCH] kdbus: skip acquiring an active reference in poll()
|
||||
|
||||
During poll(), we currently acquire an active reference to the connection
|
||||
in question to verify it's still active. If it's not active, anymore, we
|
||||
return POLLHUP.
|
||||
|
||||
This works fine, but requires an atomic_inc() to acquire the active
|
||||
reference. However, all we need is a guarantee that the connection is
|
||||
active right now, and a guarantee we're called again once this changes.
|
||||
This is as simple as adding the waitqueue first, then checking the
|
||||
active-state afterwards. kdbus_conn_disconnect() guarantees to wake us up
|
||||
_after_ deactivating the connection, thus providing the required barrier
|
||||
implicitly (in case someone is actually polling / waiting on the
|
||||
connection).
|
||||
|
||||
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Acked-by: Daniel Mack <daniel@zonque.org>
|
||||
---
|
||||
ipc/kdbus/handle.c | 16 +++++++++-------
|
||||
1 file changed, 9 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/ipc/kdbus/handle.c b/ipc/kdbus/handle.c
|
||||
index a3e01383a6f6..6230c7ef4347 100644
|
||||
--- a/ipc/kdbus/handle.c
|
||||
+++ b/ipc/kdbus/handle.c
|
||||
@@ -610,7 +610,6 @@ static unsigned int kdbus_handle_poll(struct file *file,
|
||||
struct kdbus_handle *handle = file->private_data;
|
||||
enum kdbus_handle_type type;
|
||||
unsigned int mask = POLLOUT | POLLWRNORM;
|
||||
- int ret;
|
||||
|
||||
/*
|
||||
* This pairs with smp_wmb() during handle setup. It guarantees that
|
||||
@@ -626,18 +625,21 @@ static unsigned int kdbus_handle_poll(struct file *file,
|
||||
if (type != KDBUS_HANDLE_CONNECTED)
|
||||
return POLLERR | POLLHUP;
|
||||
|
||||
- ret = kdbus_conn_acquire(handle->conn);
|
||||
- if (ret < 0)
|
||||
- return POLLERR | POLLHUP;
|
||||
-
|
||||
poll_wait(file, &handle->conn->wait, wait);
|
||||
|
||||
+ /*
|
||||
+ * Verify the connection hasn't been deactivated _after_ adding the
|
||||
+ * wait-queue. This guarantees, that if the connection is deactivated
|
||||
+ * after we checked it, the waitqueue is signaled and we're called
|
||||
+ * again.
|
||||
+ */
|
||||
+ if (!kdbus_conn_active(handle->conn))
|
||||
+ return POLLERR | POLLHUP;
|
||||
+
|
||||
if (!list_empty(&handle->conn->queue.msg_list) ||
|
||||
atomic_read(&handle->conn->lost_count) > 0)
|
||||
mask |= POLLIN | POLLRDNORM;
|
||||
|
||||
- kdbus_conn_release(handle->conn);
|
||||
-
|
||||
return mask;
|
||||
}
|
||||
|
55
kdbus-skip-mandatory-items-on-negotiation.patch
Normal file
55
kdbus-skip-mandatory-items-on-negotiation.patch
Normal file
@ -0,0 +1,55 @@
|
||||
From: David Herrmann <dh.herrmann@gmail.com>
|
||||
Date: Thu, 21 May 2015 20:03:29 +0200
|
||||
Subject: [PATCH] kdbus: skip mandatory items on negotiation
|
||||
|
||||
The kdbus negotiation is used to figure out what items and flags an ioctl
|
||||
supports. It is highly impractical to pass in mandatory items when all we
|
||||
do is negotiation. Therefore, allow user-space to skip mandatory items if
|
||||
KDBUS_FLAG_NEGOTIATE is passed.
|
||||
|
||||
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Acked-by: Daniel Mack <daniel@zonque.org>
|
||||
---
|
||||
ipc/kdbus/handle.c | 15 ++++++++++-----
|
||||
1 file changed, 10 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/ipc/kdbus/handle.c b/ipc/kdbus/handle.c
|
||||
index f72dbe513b4a..3f5d8085a297 100644
|
||||
--- a/ipc/kdbus/handle.c
|
||||
+++ b/ipc/kdbus/handle.c
|
||||
@@ -71,10 +71,6 @@ static int kdbus_args_verify(struct kdbus_args *args)
|
||||
if (!KDBUS_ITEMS_END(item, args->items, args->items_size))
|
||||
return -EINVAL;
|
||||
|
||||
- for (i = 0; i < args->argc; ++i)
|
||||
- if (args->argv[i].mandatory && !args->argv[i].item)
|
||||
- return -EINVAL;
|
||||
-
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -149,7 +145,7 @@ static int kdbus_args_negotiate(struct kdbus_args *args)
|
||||
int __kdbus_args_parse(struct kdbus_args *args, void __user *argp,
|
||||
size_t type_size, size_t items_offset, void **out)
|
||||
{
|
||||
- int ret;
|
||||
+ int ret, i;
|
||||
|
||||
args->cmd = kdbus_memdup_user(argp, type_size, KDBUS_CMD_MAX_SIZE);
|
||||
if (IS_ERR(args->cmd))
|
||||
@@ -173,6 +169,15 @@ int __kdbus_args_parse(struct kdbus_args *args, void __user *argp,
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
|
||||
+ /* mandatory items must be given (but not on negotiation) */
|
||||
+ if (!(args->cmd->flags & KDBUS_FLAG_NEGOTIATE)) {
|
||||
+ for (i = 0; i < args->argc; ++i)
|
||||
+ if (args->argv[i].mandatory && !args->argv[i].item) {
|
||||
+ ret = -EINVAL;
|
||||
+ goto error;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
*out = args->cmd;
|
||||
return !!(args->cmd->flags & KDBUS_FLAG_NEGOTIATE);
|
||||
|
212
kdbus-translate-capabilities-between-namespaces.patch
Normal file
212
kdbus-translate-capabilities-between-namespaces.patch
Normal file
@ -0,0 +1,212 @@
|
||||
From: David Herrmann <dh.herrmann@gmail.com>
|
||||
Date: Wed, 22 Apr 2015 13:14:24 +0200
|
||||
Subject: [PATCH] kdbus: translate capabilities between namespaces
|
||||
|
||||
Right now, we always drop capability-items if we cross user-namespaces.
|
||||
However, the kernel _does_ support capability translation, as defined in
|
||||
./security/commoncap.c cap_capable().
|
||||
|
||||
This patch adds capability translation support just like cap_capable()
|
||||
does. This way, a message sent from a task into a child user-namespace of
|
||||
its own, will retain the capability-item and thus keep the parent
|
||||
privileged inside of the user-namespace of its children.
|
||||
|
||||
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
---
|
||||
ipc/kdbus/metadata.c | 126 ++++++++++++++++++++++++++++++++++-----------------
|
||||
1 file changed, 84 insertions(+), 42 deletions(-)
|
||||
|
||||
diff --git a/ipc/kdbus/metadata.c b/ipc/kdbus/metadata.c
|
||||
index b908b6314a00..7949c8d3ed64 100644
|
||||
--- a/ipc/kdbus/metadata.c
|
||||
+++ b/ipc/kdbus/metadata.c
|
||||
@@ -63,8 +63,7 @@
|
||||
* @root_path: Root-FS path
|
||||
* @cmdline: Command-line
|
||||
* @cgroup: Full cgroup path
|
||||
- * @caps: Capabilities
|
||||
- * @caps_namespace: User-namespace of @caps
|
||||
+ * @cred: Credentials
|
||||
* @seclabel: Seclabel
|
||||
* @audit_loginuid: Audit login-UID
|
||||
* @audit_sessionid: Audit session-ID
|
||||
@@ -104,14 +103,7 @@ struct kdbus_meta_proc {
|
||||
char *cgroup;
|
||||
|
||||
/* KDBUS_ITEM_CAPS */
|
||||
- struct caps {
|
||||
- /* binary compatible to kdbus_caps */
|
||||
- u32 last_cap;
|
||||
- struct {
|
||||
- u32 caps[_KERNEL_CAPABILITY_U32S];
|
||||
- } set[4];
|
||||
- } caps;
|
||||
- struct user_namespace *caps_namespace;
|
||||
+ const struct cred *cred;
|
||||
|
||||
/* KDBUS_ITEM_SECLABEL */
|
||||
char *seclabel;
|
||||
@@ -149,6 +141,14 @@ struct kdbus_meta_conn {
|
||||
char *conn_description;
|
||||
};
|
||||
|
||||
+/* fixed size equivalent of "kdbus_caps" */
|
||||
+struct kdbus_meta_caps {
|
||||
+ u32 last_cap;
|
||||
+ struct {
|
||||
+ u32 caps[_KERNEL_CAPABILITY_U32S];
|
||||
+ } set[4];
|
||||
+};
|
||||
+
|
||||
/**
|
||||
* kdbus_meta_proc_new() - Create process metadata object
|
||||
*
|
||||
@@ -175,7 +175,8 @@ static void kdbus_meta_proc_free(struct kref *kref)
|
||||
|
||||
path_put(&mp->exe_path);
|
||||
path_put(&mp->root_path);
|
||||
- put_user_ns(mp->caps_namespace);
|
||||
+ if (mp->cred)
|
||||
+ put_cred(mp->cred);
|
||||
put_pid(mp->ppid);
|
||||
put_pid(mp->tgid);
|
||||
put_pid(mp->pid);
|
||||
@@ -354,25 +355,7 @@ static int kdbus_meta_proc_collect_cgroup(struct kdbus_meta_proc *mp)
|
||||
|
||||
static void kdbus_meta_proc_collect_caps(struct kdbus_meta_proc *mp)
|
||||
{
|
||||
- const struct cred *c = current_cred();
|
||||
- int i;
|
||||
-
|
||||
- /* ABI: "last_cap" equals /proc/sys/kernel/cap_last_cap */
|
||||
- mp->caps.last_cap = CAP_LAST_CAP;
|
||||
- mp->caps_namespace = get_user_ns(current_user_ns());
|
||||
-
|
||||
- CAP_FOR_EACH_U32(i) {
|
||||
- mp->caps.set[0].caps[i] = c->cap_inheritable.cap[i];
|
||||
- mp->caps.set[1].caps[i] = c->cap_permitted.cap[i];
|
||||
- mp->caps.set[2].caps[i] = c->cap_effective.cap[i];
|
||||
- mp->caps.set[3].caps[i] = c->cap_bset.cap[i];
|
||||
- }
|
||||
-
|
||||
- /* clear unused bits */
|
||||
- for (i = 0; i < 4; i++)
|
||||
- mp->caps.set[i].caps[CAP_TO_INDEX(CAP_LAST_CAP)] &=
|
||||
- CAP_LAST_U32_VALID_MASK;
|
||||
-
|
||||
+ mp->cred = get_current_cred();
|
||||
mp->valid |= KDBUS_ATTACH_CAPS;
|
||||
}
|
||||
|
||||
@@ -880,7 +863,7 @@ int kdbus_meta_export_prepare(struct kdbus_meta_proc *mp,
|
||||
size += KDBUS_ITEM_SIZE(strlen(mp->cgroup) + 1);
|
||||
|
||||
if (mp && (*mask & KDBUS_ATTACH_CAPS))
|
||||
- size += KDBUS_ITEM_SIZE(sizeof(mp->caps));
|
||||
+ size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_meta_caps));
|
||||
|
||||
if (mp && (*mask & KDBUS_ATTACH_SECLABEL))
|
||||
size += KDBUS_ITEM_SIZE(strlen(mp->seclabel) + 1);
|
||||
@@ -917,6 +900,69 @@ static int kdbus_meta_push_kvec(struct kvec *kvec,
|
||||
return 2 + !!kdbus_kvec_pad(kvec++, size);
|
||||
}
|
||||
|
||||
+static void kdbus_meta_export_caps(struct kdbus_meta_caps *out,
|
||||
+ struct kdbus_meta_proc *mp)
|
||||
+{
|
||||
+ struct user_namespace *iter;
|
||||
+ const struct cred *cred = mp->cred;
|
||||
+ bool parent = false, owner = false;
|
||||
+ int i;
|
||||
+
|
||||
+ /*
|
||||
+ * This translates the effective capabilities of 'cred' into the current
|
||||
+ * user-namespace. If the current user-namespace is a child-namespace of
|
||||
+ * the user-namespace of 'cred', the mask can be copied verbatim. If
|
||||
+ * not, the mask is cleared.
|
||||
+ * There's one exception: If 'cred' is the owner of any user-namespace
|
||||
+ * in the path between the current user-namespace and the user-namespace
|
||||
+ * of 'cred', then it has all effective capabilities set. This means,
|
||||
+ * the user who created a user-namespace always has all effective
|
||||
+ * capabilities in any child namespaces. Note that this is based on the
|
||||
+ * uid of the namespace creator, not the task hierarchy.
|
||||
+ */
|
||||
+ for (iter = current_user_ns(); iter; iter = iter->parent) {
|
||||
+ if (iter == cred->user_ns) {
|
||||
+ parent = true;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (iter == &init_user_ns)
|
||||
+ break;
|
||||
+
|
||||
+ if ((iter->parent == cred->user_ns) &&
|
||||
+ uid_eq(iter->owner, cred->euid)) {
|
||||
+ owner = true;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ out->last_cap = CAP_LAST_CAP;
|
||||
+
|
||||
+ CAP_FOR_EACH_U32(i) {
|
||||
+ if (parent) {
|
||||
+ out->set[0].caps[i] = cred->cap_inheritable.cap[i];
|
||||
+ out->set[1].caps[i] = cred->cap_permitted.cap[i];
|
||||
+ out->set[2].caps[i] = cred->cap_effective.cap[i];
|
||||
+ out->set[3].caps[i] = cred->cap_bset.cap[i];
|
||||
+ } else if (owner) {
|
||||
+ out->set[0].caps[i] = 0U;
|
||||
+ out->set[1].caps[i] = ~0U;
|
||||
+ out->set[2].caps[i] = ~0U;
|
||||
+ out->set[3].caps[i] = ~0U;
|
||||
+ } else {
|
||||
+ out->set[0].caps[i] = 0U;
|
||||
+ out->set[1].caps[i] = 0U;
|
||||
+ out->set[2].caps[i] = 0U;
|
||||
+ out->set[3].caps[i] = 0U;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* clear unused bits */
|
||||
+ for (i = 0; i < 4; i++)
|
||||
+ out->set[i].caps[CAP_TO_INDEX(CAP_LAST_CAP)] &=
|
||||
+ CAP_LAST_U32_VALID_MASK;
|
||||
+}
|
||||
+
|
||||
/* This is equivalent to from_kuid_munged(), but maps INVALID_UID to itself */
|
||||
static uid_t kdbus_from_kuid_keep(kuid_t uid)
|
||||
{
|
||||
@@ -975,14 +1021,6 @@ int kdbus_meta_export(struct kdbus_meta_proc *mp,
|
||||
|
||||
hdr = &item_hdr[0];
|
||||
|
||||
- /*
|
||||
- * TODO: We currently have no sane way of translating a set of caps
|
||||
- * between different user namespaces. Until that changes, we have
|
||||
- * to drop such items.
|
||||
- */
|
||||
- if (mp && mp->caps_namespace != user_ns)
|
||||
- mask &= ~KDBUS_ATTACH_CAPS;
|
||||
-
|
||||
if (mask == 0) {
|
||||
*real_size = 0;
|
||||
return 0;
|
||||
@@ -1088,10 +1126,14 @@ int kdbus_meta_export(struct kdbus_meta_proc *mp,
|
||||
KDBUS_ITEM_CGROUP, mp->cgroup,
|
||||
strlen(mp->cgroup) + 1, &size);
|
||||
|
||||
- if (mp && (mask & KDBUS_ATTACH_CAPS))
|
||||
+ if (mp && (mask & KDBUS_ATTACH_CAPS)) {
|
||||
+ struct kdbus_meta_caps caps = {};
|
||||
+
|
||||
+ kdbus_meta_export_caps(&caps, mp);
|
||||
cnt += kdbus_meta_push_kvec(kvec + cnt, hdr++,
|
||||
- KDBUS_ITEM_CAPS, &mp->caps,
|
||||
- sizeof(mp->caps), &size);
|
||||
+ KDBUS_ITEM_CAPS, &caps,
|
||||
+ sizeof(caps), &size);
|
||||
+ }
|
||||
|
||||
if (mp && (mask & KDBUS_ATTACH_SECLABEL))
|
||||
cnt += kdbus_meta_push_kvec(kvec + cnt, hdr++,
|
101
kdbus-turn-kdbus_node_idr-into-an-ida.patch
Normal file
101
kdbus-turn-kdbus_node_idr-into-an-ida.patch
Normal file
@ -0,0 +1,101 @@
|
||||
From: David Herrmann <dh.herrmann@gmail.com>
|
||||
Date: Sat, 18 Apr 2015 12:00:33 +0200
|
||||
Subject: [PATCH] kdbus: turn kdbus_node_idr into an ida
|
||||
|
||||
We no longer use the node-idr for lookups. We're only interested in unique
|
||||
ID allocation. Hence, turn the kdbus_node_idr into an ida and drop the now
|
||||
redundant locking. This is also what kernfs does for ino allocations.
|
||||
|
||||
Reported-by: Al Viro <viro@zeniv.linux.org.uk>
|
||||
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Acked-by: Daniel Mack <daniel@zonque.org>
|
||||
---
|
||||
ipc/kdbus/main.c | 1 +
|
||||
ipc/kdbus/node.c | 23 +++++------------------
|
||||
ipc/kdbus/node.h | 2 ++
|
||||
3 files changed, 8 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/ipc/kdbus/main.c b/ipc/kdbus/main.c
|
||||
index 785f529d98b7..f8eac78cace6 100644
|
||||
--- a/ipc/kdbus/main.c
|
||||
+++ b/ipc/kdbus/main.c
|
||||
@@ -116,6 +116,7 @@ static void __exit kdbus_exit(void)
|
||||
{
|
||||
kdbus_fs_exit();
|
||||
kobject_put(kdbus_dir);
|
||||
+ ida_destroy(&kdbus_node_ida);
|
||||
}
|
||||
|
||||
module_init(kdbus_init);
|
||||
diff --git a/ipc/kdbus/node.c b/ipc/kdbus/node.c
|
||||
index 520df00e676a..0d65c65d2bde 100644
|
||||
--- a/ipc/kdbus/node.c
|
||||
+++ b/ipc/kdbus/node.c
|
||||
@@ -178,7 +178,7 @@
|
||||
* accessed by other callers to properly initialize
|
||||
* filesystem nodes.
|
||||
*
|
||||
- * * node->id: This is an unsigned 32bit integer allocated by an IDR. It is
|
||||
+ * * node->id: This is an unsigned 32bit integer allocated by an IDA. It is
|
||||
* always kept as small as possible during allocation and is
|
||||
* globally unique across all nodes allocated by this module. 0
|
||||
* is reserved as "not assigned" and is the default.
|
||||
@@ -233,8 +233,7 @@
|
||||
#define KDBUS_NODE_NEW (KDBUS_NODE_BIAS - 4)
|
||||
|
||||
/* global unique ID mapping for kdbus nodes */
|
||||
-static DEFINE_IDR(kdbus_node_idr);
|
||||
-static DECLARE_RWSEM(kdbus_node_idr_lock);
|
||||
+DEFINE_IDA(kdbus_node_ida);
|
||||
|
||||
/**
|
||||
* kdbus_node_name_hash() - hash a name
|
||||
@@ -337,15 +336,11 @@ int kdbus_node_link(struct kdbus_node *node, struct kdbus_node *parent,
|
||||
node->hash = kdbus_node_name_hash(name);
|
||||
}
|
||||
|
||||
- down_write(&kdbus_node_idr_lock);
|
||||
- ret = idr_alloc(&kdbus_node_idr, node, 1, 0, GFP_KERNEL);
|
||||
- if (ret >= 0)
|
||||
- node->id = ret;
|
||||
- up_write(&kdbus_node_idr_lock);
|
||||
-
|
||||
+ ret = ida_simple_get(&kdbus_node_ida, 1, 0, GFP_KERNEL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
+ node->id = ret;
|
||||
ret = 0;
|
||||
|
||||
if (parent) {
|
||||
@@ -440,16 +435,8 @@ struct kdbus_node *kdbus_node_unref(struct kdbus_node *node)
|
||||
|
||||
if (node->free_cb)
|
||||
node->free_cb(node);
|
||||
-
|
||||
- down_write(&kdbus_node_idr_lock);
|
||||
if (safe.id > 0)
|
||||
- idr_remove(&kdbus_node_idr, safe.id);
|
||||
- /* drop caches after last node to not leak memory on unload */
|
||||
- if (idr_is_empty(&kdbus_node_idr)) {
|
||||
- idr_destroy(&kdbus_node_idr);
|
||||
- idr_init(&kdbus_node_idr);
|
||||
- }
|
||||
- up_write(&kdbus_node_idr_lock);
|
||||
+ ida_simple_remove(&kdbus_node_ida, safe.id);
|
||||
|
||||
kfree(safe.name);
|
||||
|
||||
diff --git a/ipc/kdbus/node.h b/ipc/kdbus/node.h
|
||||
index be125ce4fd58..970e02b08e9f 100644
|
||||
--- a/ipc/kdbus/node.h
|
||||
+++ b/ipc/kdbus/node.h
|
||||
@@ -58,6 +58,8 @@ struct kdbus_node {
|
||||
|
||||
#define kdbus_node_from_rb(_node) rb_entry((_node), struct kdbus_node, rb)
|
||||
|
||||
+extern struct ida kdbus_node_ida;
|
||||
+
|
||||
void kdbus_node_init(struct kdbus_node *node, unsigned int type);
|
||||
|
||||
int kdbus_node_link(struct kdbus_node *node, struct kdbus_node *parent,
|
24
kdbus-uapi-Fix-kernel-doc-for-enum-kdbus_send_flags.patch
Normal file
24
kdbus-uapi-Fix-kernel-doc-for-enum-kdbus_send_flags.patch
Normal file
@ -0,0 +1,24 @@
|
||||
From: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Date: Thu, 9 Apr 2015 13:11:01 +0300
|
||||
Subject: [PATCH] kdbus: uapi: Fix kernel-doc for enum kdbus_send_flags
|
||||
|
||||
Signed-off-by: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Acked-by: Daniel Mack <daniel@zonque.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
include/uapi/linux/kdbus.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/include/uapi/linux/kdbus.h b/include/uapi/linux/kdbus.h
|
||||
index 2fe0a1c5056c..00a6e142c977 100644
|
||||
--- a/include/uapi/linux/kdbus.h
|
||||
+++ b/include/uapi/linux/kdbus.h
|
||||
@@ -544,7 +544,7 @@ struct kdbus_msg_info {
|
||||
* reply to this message. The
|
||||
* KDBUS_CMD_SEND ioctl() will block
|
||||
* until the reply is received, and
|
||||
- * offset_reply in struct kdbus_msg will
|
||||
+ * reply in struct kdbus_cmd_send will
|
||||
* yield the offset in the sender's pool
|
||||
* where the reply can be found.
|
||||
* This flag is only valid if
|
28
kdbus-update-kernel-doc-for-kdbus_sync_reply_wakeup.patch
Normal file
28
kdbus-update-kernel-doc-for-kdbus_sync_reply_wakeup.patch
Normal file
@ -0,0 +1,28 @@
|
||||
From: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Date: Tue, 2 Jun 2015 18:48:47 +0300
|
||||
Subject: [PATCH] kdbus: update kernel-doc for kdbus_sync_reply_wakeup()
|
||||
|
||||
kdbus_sync_reply_wakeup() doesn't remove reply object from connection
|
||||
reply_list. Update function description.
|
||||
|
||||
Signed-off-by: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
ipc/kdbus/reply.c | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
diff --git a/ipc/kdbus/reply.c b/ipc/kdbus/reply.c
|
||||
index 008dca801627..89d355b44f63 100644
|
||||
--- a/ipc/kdbus/reply.c
|
||||
+++ b/ipc/kdbus/reply.c
|
||||
@@ -140,8 +140,7 @@ void kdbus_reply_unlink(struct kdbus_reply *r)
|
||||
* @reply: The reply object
|
||||
* @err: Error code to set on the remote side
|
||||
*
|
||||
- * Remove the synchronous reply object from its connection reply_list, and
|
||||
- * wake up remote peer (method origin) with the appropriate synchronous reply
|
||||
+ * Wake up remote peer (method origin) with the appropriate synchronous reply
|
||||
* code.
|
||||
*/
|
||||
void kdbus_sync_reply_wakeup(struct kdbus_reply *reply, int err)
|
29
kdbus-use-FIELD_SIZEOF-in-kdbus_member_set_user-macr.patch
Normal file
29
kdbus-use-FIELD_SIZEOF-in-kdbus_member_set_user-macr.patch
Normal file
@ -0,0 +1,29 @@
|
||||
From: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Date: Thu, 4 Jun 2015 13:39:30 +0300
|
||||
Subject: [PATCH] kdbus: use FIELD_SIZEOF in kdbus_member_set_user macro
|
||||
|
||||
sizeof(((_t *)0)->_m) -> FIELD_SIZEOF(_t, _m)
|
||||
|
||||
Use conventional macro according to chapter 17 of
|
||||
Documentation/CodingStyle.
|
||||
|
||||
Signed-off-by: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
ipc/kdbus/util.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ipc/kdbus/util.h b/ipc/kdbus/util.h
|
||||
index 9fedf8ab41cd..529716669fe7 100644
|
||||
--- a/ipc/kdbus/util.h
|
||||
+++ b/ipc/kdbus/util.h
|
||||
@@ -40,7 +40,7 @@
|
||||
({ \
|
||||
u64 __user *_sz = \
|
||||
(void __user *)((u8 __user *)(_b) + offsetof(_t, _m)); \
|
||||
- copy_to_user(_sz, _s, sizeof(((_t *)0)->_m)); \
|
||||
+ copy_to_user(_sz, _s, FIELD_SIZEOF(_t, _m)); \
|
||||
})
|
||||
|
||||
/**
|
31
kdbus-use-parentheses-uniformly-in-KDBUS_ITEMS_FOREA.patch
Normal file
31
kdbus-use-parentheses-uniformly-in-KDBUS_ITEMS_FOREA.patch
Normal file
@ -0,0 +1,31 @@
|
||||
From: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Date: Wed, 10 Jun 2015 00:00:00 +0300
|
||||
Subject: [PATCH] kdbus: use parentheses uniformly in KDBUS_ITEMS_FOREACH macro
|
||||
|
||||
Enclose all arguments into parentheses to stay consistent across the
|
||||
whole macro.
|
||||
|
||||
Signed-off-by: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
ipc/kdbus/item.h | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/ipc/kdbus/item.h b/ipc/kdbus/item.h
|
||||
index 32909e2e7954..bca63b4e6e80 100644
|
||||
--- a/ipc/kdbus/item.h
|
||||
+++ b/ipc/kdbus/item.h
|
||||
@@ -28,10 +28,10 @@
|
||||
#define KDBUS_ITEM_PAYLOAD_SIZE(_i) ((_i)->size - KDBUS_ITEM_HEADER_SIZE)
|
||||
|
||||
#define KDBUS_ITEMS_FOREACH(_i, _is, _s) \
|
||||
- for (_i = _is; \
|
||||
+ for ((_i) = (_is); \
|
||||
((u8 *)(_i) < (u8 *)(_is) + (_s)) && \
|
||||
((u8 *)(_i) >= (u8 *)(_is)); \
|
||||
- _i = KDBUS_ITEM_NEXT(_i))
|
||||
+ (_i) = KDBUS_ITEM_NEXT(_i))
|
||||
|
||||
#define KDBUS_ITEM_VALID(_i, _is, _s) \
|
||||
((_i)->size >= KDBUS_ITEM_HEADER_SIZE && \
|
44
kdbus-use-rcu-to-access-exe-file-in-metadata.patch
Normal file
44
kdbus-use-rcu-to-access-exe-file-in-metadata.patch
Normal file
@ -0,0 +1,44 @@
|
||||
From: Daniel Mack <daniel@zonque.org>
|
||||
Date: Sat, 18 Apr 2015 12:04:36 +0200
|
||||
Subject: [PATCH] kdbus: use rcu to access exe file in metadata
|
||||
|
||||
Commit 90f31d0ea888 ("mm: rcu-protected get_mm_exe_file()") removed
|
||||
mm->mmap_sem from mm->exe_file read side. Follow that change in the
|
||||
kdbus metadata code.
|
||||
|
||||
Signed-off-by: Daniel Mack <daniel@zonque.org>
|
||||
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
---
|
||||
ipc/kdbus/metadata.c | 10 ++++++----
|
||||
1 file changed, 6 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/ipc/kdbus/metadata.c b/ipc/kdbus/metadata.c
|
||||
index 7949c8d3ed64..a85eac34a5c4 100644
|
||||
--- a/ipc/kdbus/metadata.c
|
||||
+++ b/ipc/kdbus/metadata.c
|
||||
@@ -283,19 +283,21 @@ static void kdbus_meta_proc_collect_pid_comm(struct kdbus_meta_proc *mp)
|
||||
static void kdbus_meta_proc_collect_exe(struct kdbus_meta_proc *mp)
|
||||
{
|
||||
struct mm_struct *mm;
|
||||
+ struct file *exe_file;
|
||||
|
||||
mm = get_task_mm(current);
|
||||
if (!mm)
|
||||
return;
|
||||
|
||||
- down_read(&mm->mmap_sem);
|
||||
- if (mm->exe_file) {
|
||||
- mp->exe_path = mm->exe_file->f_path;
|
||||
+ rcu_read_lock();
|
||||
+ exe_file = rcu_dereference(mm->exe_file);
|
||||
+ if (exe_file) {
|
||||
+ mp->exe_path = exe_file->f_path;
|
||||
path_get(&mp->exe_path);
|
||||
get_fs_root(current->fs, &mp->root_path);
|
||||
mp->valid |= KDBUS_ATTACH_EXE;
|
||||
}
|
||||
- up_read(&mm->mmap_sem);
|
||||
+ rcu_read_unlock();
|
||||
|
||||
mmput(mm);
|
||||
}
|
320
kernel.spec
320
kernel.spec
@ -67,7 +67,7 @@ Summary: The Linux kernel
|
||||
# The rc snapshot level
|
||||
%define rcrev 1
|
||||
# The git snapshot level
|
||||
%define gitrev 1
|
||||
%define gitrev 2
|
||||
# Set rpm version accordingly
|
||||
%define rpmversion 4.%{upstream_sublevel}.0
|
||||
%endif
|
||||
@ -596,6 +596,162 @@ Patch502: firmware-Drop-WARN-from-usermodehelper_read_trylock-.patch
|
||||
|
||||
Patch503: drm-i915-turn-off-wc-mmaps.patch
|
||||
|
||||
Patch504: kdbus-add-documentation.patch
|
||||
|
||||
Patch505: kdbus-add-uapi-header-file.patch
|
||||
|
||||
Patch506: kdbus-add-driver-skeleton-ioctl-entry-points-and-uti.patch
|
||||
|
||||
Patch507: kdbus-add-connection-pool-implementation.patch
|
||||
|
||||
Patch508: kdbus-add-connection-queue-handling-and-message-vali.patch
|
||||
|
||||
Patch509: kdbus-add-node-and-filesystem-implementation.patch
|
||||
|
||||
Patch510: kdbus-add-code-to-gather-metadata.patch
|
||||
|
||||
Patch511: kdbus-add-code-for-notifications-and-matches.patch
|
||||
|
||||
Patch512: kdbus-add-code-for-buses-domains-and-endpoints.patch
|
||||
|
||||
Patch513: kdbus-add-name-registry-implementation.patch
|
||||
|
||||
Patch514: kdbus-add-policy-database-implementation.patch
|
||||
|
||||
Patch515: kdbus-add-Makefile-Kconfig-and-MAINTAINERS-entry.patch
|
||||
|
||||
Patch516: kdbus-add-walk-through-user-space-example.patch
|
||||
|
||||
Patch517: kdbus-add-selftests.patch
|
||||
|
||||
Patch518: Documentation-kdbus-fix-location-for-generated-files.patch
|
||||
|
||||
Patch519: kdbus-samples-kdbus-add-lrt.patch
|
||||
|
||||
Patch520: kdbus-fix-minor-typo-in-the-walk-through-example.patch
|
||||
|
||||
Patch521: samples-kdbus-drop-wrong-include.patch
|
||||
|
||||
Patch522: Documentation-kdbus-fix-out-of-tree-builds.patch
|
||||
|
||||
Patch523: Documentation-kdbus-support-quiet-builds.patch
|
||||
|
||||
Patch524: selftests-kdbus-fix-gitignore.patch
|
||||
|
||||
Patch525: Documentation-kdbus-replace-reply_cookie-with-cookie.patch
|
||||
|
||||
Patch526: kdbus-fix-header-guard-name.patch
|
||||
|
||||
Patch527: kdbus-connection-fix-handling-of-failed-fget.patch
|
||||
|
||||
Patch528: kdbus-Fix-CONFIG_KDBUS-help-text.patch
|
||||
|
||||
Patch529: samples-kdbus-build-kdbus-workers-conditionally.patch
|
||||
|
||||
Patch530: selftest-kdbus-enable-cross-compilation.patch
|
||||
|
||||
Patch531: kdbus-uapi-Fix-kernel-doc-for-enum-kdbus_send_flags.patch
|
||||
|
||||
Patch532: Documentation-kdbus-Fix-list-of-KDBUS_CMD_ENDPOINT_U.patch
|
||||
|
||||
Patch533: Documentation-kdbus-Update-list-of-ioctls-which-caus.patch
|
||||
|
||||
Patch534: Documentation-kdbus-Fix-description-of-KDBUS_SEND_SY.patch
|
||||
|
||||
Patch535: Documentation-kdbus-Fix-typos.patch
|
||||
|
||||
Patch536: kdbus-avoid-the-use-of-struct-timespec.patch
|
||||
|
||||
Patch537: kdbus-pool-use-__vfs_read.patch
|
||||
|
||||
Patch538: kdbus-skip-mandatory-items-on-negotiation.patch
|
||||
|
||||
Patch539: kdbus-turn-kdbus_node_idr-into-an-ida.patch
|
||||
|
||||
Patch540: kdbus-reduce-scope-of-handle-locking.patch
|
||||
|
||||
Patch541: kdbus-skip-acquiring-an-active-reference-in-poll.patch
|
||||
|
||||
Patch542: kdbus-remove-unused-linux-version.h-include.patch
|
||||
|
||||
Patch543: kdbus-optimize-auxgroup-collector.patch
|
||||
|
||||
Patch544: kdbus-drop-obsolete-WARN_ON.patch
|
||||
|
||||
Patch545: kdbus-copy-small-ioctl-payloads-to-stack.patch
|
||||
|
||||
Patch546: kdbus-drop-kdbus_meta_attach_mask-modparam.patch
|
||||
|
||||
Patch547: kdbus-fix-typo.patch
|
||||
|
||||
Patch548: kdbus-forward-ID-notifications-to-everyone.patch
|
||||
|
||||
Patch549: kdbus-provide-helper-to-collect-metadata.patch
|
||||
|
||||
Patch550: kdbus-make-metadata-on-broadcasts-reliable.patch
|
||||
|
||||
Patch551: samples-kdbus-stub-out-code-for-glibc-2.7.patch
|
||||
|
||||
Patch552: kdbus-fix-up-documentation-of-ioctl-handlers.patch
|
||||
|
||||
Patch553: kdbus-translate-capabilities-between-namespaces.patch
|
||||
|
||||
Patch554: kdbus-selftests-add-build-dependencies-on-headers.patch
|
||||
|
||||
Patch555: kdbus-use-rcu-to-access-exe-file-in-metadata.patch
|
||||
|
||||
Patch556: kdbus-no-need-to-ref-current-mm.patch
|
||||
|
||||
Patch557: selftests-kdbus-install-kdbus-test.patch
|
||||
|
||||
Patch558: kdbus-update-kernel-doc-for-kdbus_sync_reply_wakeup.patch
|
||||
|
||||
Patch559: kdbus-remove-redundant-code-from-kdbus_conn_entry_ma.patch
|
||||
|
||||
Patch560: kdbus-kdbus_item_validate-remove-duplicated-code.patch
|
||||
|
||||
Patch561: kdbus-kdbus_conn_connect-use-bus-instead-of-conn-ep-.patch
|
||||
|
||||
Patch562: kdbus-use-FIELD_SIZEOF-in-kdbus_member_set_user-macr.patch
|
||||
|
||||
Patch563: selftests-kdbus-handle-cap_get_proc-error-properly.patch
|
||||
|
||||
Patch564: selftests-kdbus-drop-useless-assignment.patch
|
||||
|
||||
Patch565: selftests-kdbus-remove-useless-initializations-from-.patch
|
||||
|
||||
Patch566: selftests-kdbus-drop-duplicated-code-from-__kdbus_ms.patch
|
||||
|
||||
Patch567: selftests-kdbus-fix-error-paths-in-__kdbus_msg_send.patch
|
||||
|
||||
Patch568: kdbus-drop-useless-goto.patch
|
||||
|
||||
Patch569: kdbus-fix-operator-precedence-issues-in-item-macros.patch
|
||||
|
||||
Patch570: kdbus-use-parentheses-uniformly-in-KDBUS_ITEMS_FOREA.patch
|
||||
|
||||
Patch571: Documentation-kdbus-fix-operator-precedence-issue-in.patch
|
||||
|
||||
Patch572: Documentation-kdbus-use-parentheses-uniformly-in-KDB.patch
|
||||
|
||||
Patch573: selftests-kdbus-fix-trivial-style-issues.patch
|
||||
|
||||
Patch574: selftests-kdbus-fix-precedence-issues-in-macros.patch
|
||||
|
||||
Patch575: selftests-kdbus-use-parentheses-in-iteration-macros-.patch
|
||||
|
||||
Patch576: samples-kdbus-add-whitespace.patch
|
||||
|
||||
Patch577: samples-kdbus-fix-operator-precedence-issue-in-KDBUS.patch
|
||||
|
||||
Patch578: samples-kdbus-use-parentheses-uniformly-in-KDBUS_FOR.patch
|
||||
|
||||
Patch579: kdbus-kdbus_reply_find-return-on-found-entry.patch
|
||||
|
||||
Patch580: kdbus-optimize-error-path-in-kdbus_reply_new.patch
|
||||
|
||||
Patch581: kdbus-optimize-if-statements-in-kdbus_conn_disconnec.patch
|
||||
|
||||
|
||||
# END OF PATCH DEFINITIONS
|
||||
|
||||
@ -1266,6 +1422,162 @@ ApplyPatch firmware-Drop-WARN-from-usermodehelper_read_trylock-.patch
|
||||
|
||||
ApplyPatch drm-i915-turn-off-wc-mmaps.patch
|
||||
|
||||
ApplyPatch kdbus-add-documentation.patch
|
||||
|
||||
ApplyPatch kdbus-add-uapi-header-file.patch
|
||||
|
||||
ApplyPatch kdbus-add-driver-skeleton-ioctl-entry-points-and-uti.patch
|
||||
|
||||
ApplyPatch kdbus-add-connection-pool-implementation.patch
|
||||
|
||||
ApplyPatch kdbus-add-connection-queue-handling-and-message-vali.patch
|
||||
|
||||
ApplyPatch kdbus-add-node-and-filesystem-implementation.patch
|
||||
|
||||
ApplyPatch kdbus-add-code-to-gather-metadata.patch
|
||||
|
||||
ApplyPatch kdbus-add-code-for-notifications-and-matches.patch
|
||||
|
||||
ApplyPatch kdbus-add-code-for-buses-domains-and-endpoints.patch
|
||||
|
||||
ApplyPatch kdbus-add-name-registry-implementation.patch
|
||||
|
||||
ApplyPatch kdbus-add-policy-database-implementation.patch
|
||||
|
||||
ApplyPatch kdbus-add-Makefile-Kconfig-and-MAINTAINERS-entry.patch
|
||||
|
||||
ApplyPatch kdbus-add-walk-through-user-space-example.patch
|
||||
|
||||
ApplyPatch kdbus-add-selftests.patch
|
||||
|
||||
ApplyPatch Documentation-kdbus-fix-location-for-generated-files.patch
|
||||
|
||||
ApplyPatch kdbus-samples-kdbus-add-lrt.patch
|
||||
|
||||
ApplyPatch kdbus-fix-minor-typo-in-the-walk-through-example.patch
|
||||
|
||||
ApplyPatch samples-kdbus-drop-wrong-include.patch
|
||||
|
||||
ApplyPatch Documentation-kdbus-fix-out-of-tree-builds.patch
|
||||
|
||||
ApplyPatch Documentation-kdbus-support-quiet-builds.patch
|
||||
|
||||
ApplyPatch selftests-kdbus-fix-gitignore.patch
|
||||
|
||||
ApplyPatch Documentation-kdbus-replace-reply_cookie-with-cookie.patch
|
||||
|
||||
ApplyPatch kdbus-fix-header-guard-name.patch
|
||||
|
||||
ApplyPatch kdbus-connection-fix-handling-of-failed-fget.patch
|
||||
|
||||
ApplyPatch kdbus-Fix-CONFIG_KDBUS-help-text.patch
|
||||
|
||||
ApplyPatch samples-kdbus-build-kdbus-workers-conditionally.patch
|
||||
|
||||
ApplyPatch selftest-kdbus-enable-cross-compilation.patch
|
||||
|
||||
ApplyPatch kdbus-uapi-Fix-kernel-doc-for-enum-kdbus_send_flags.patch
|
||||
|
||||
ApplyPatch Documentation-kdbus-Fix-list-of-KDBUS_CMD_ENDPOINT_U.patch
|
||||
|
||||
ApplyPatch Documentation-kdbus-Update-list-of-ioctls-which-caus.patch
|
||||
|
||||
ApplyPatch Documentation-kdbus-Fix-description-of-KDBUS_SEND_SY.patch
|
||||
|
||||
ApplyPatch Documentation-kdbus-Fix-typos.patch
|
||||
|
||||
ApplyPatch kdbus-avoid-the-use-of-struct-timespec.patch
|
||||
|
||||
ApplyPatch kdbus-pool-use-__vfs_read.patch
|
||||
|
||||
ApplyPatch kdbus-skip-mandatory-items-on-negotiation.patch
|
||||
|
||||
ApplyPatch kdbus-turn-kdbus_node_idr-into-an-ida.patch
|
||||
|
||||
ApplyPatch kdbus-reduce-scope-of-handle-locking.patch
|
||||
|
||||
ApplyPatch kdbus-skip-acquiring-an-active-reference-in-poll.patch
|
||||
|
||||
ApplyPatch kdbus-remove-unused-linux-version.h-include.patch
|
||||
|
||||
ApplyPatch kdbus-optimize-auxgroup-collector.patch
|
||||
|
||||
ApplyPatch kdbus-drop-obsolete-WARN_ON.patch
|
||||
|
||||
ApplyPatch kdbus-copy-small-ioctl-payloads-to-stack.patch
|
||||
|
||||
ApplyPatch kdbus-drop-kdbus_meta_attach_mask-modparam.patch
|
||||
|
||||
ApplyPatch kdbus-fix-typo.patch
|
||||
|
||||
ApplyPatch kdbus-forward-ID-notifications-to-everyone.patch
|
||||
|
||||
ApplyPatch kdbus-provide-helper-to-collect-metadata.patch
|
||||
|
||||
ApplyPatch kdbus-make-metadata-on-broadcasts-reliable.patch
|
||||
|
||||
ApplyPatch samples-kdbus-stub-out-code-for-glibc-2.7.patch
|
||||
|
||||
ApplyPatch kdbus-fix-up-documentation-of-ioctl-handlers.patch
|
||||
|
||||
ApplyPatch kdbus-translate-capabilities-between-namespaces.patch
|
||||
|
||||
ApplyPatch kdbus-selftests-add-build-dependencies-on-headers.patch
|
||||
|
||||
ApplyPatch kdbus-use-rcu-to-access-exe-file-in-metadata.patch
|
||||
|
||||
ApplyPatch kdbus-no-need-to-ref-current-mm.patch
|
||||
|
||||
ApplyPatch selftests-kdbus-install-kdbus-test.patch
|
||||
|
||||
ApplyPatch kdbus-update-kernel-doc-for-kdbus_sync_reply_wakeup.patch
|
||||
|
||||
ApplyPatch kdbus-remove-redundant-code-from-kdbus_conn_entry_ma.patch
|
||||
|
||||
ApplyPatch kdbus-kdbus_item_validate-remove-duplicated-code.patch
|
||||
|
||||
ApplyPatch kdbus-kdbus_conn_connect-use-bus-instead-of-conn-ep-.patch
|
||||
|
||||
ApplyPatch kdbus-use-FIELD_SIZEOF-in-kdbus_member_set_user-macr.patch
|
||||
|
||||
ApplyPatch selftests-kdbus-handle-cap_get_proc-error-properly.patch
|
||||
|
||||
ApplyPatch selftests-kdbus-drop-useless-assignment.patch
|
||||
|
||||
ApplyPatch selftests-kdbus-remove-useless-initializations-from-.patch
|
||||
|
||||
ApplyPatch selftests-kdbus-drop-duplicated-code-from-__kdbus_ms.patch
|
||||
|
||||
ApplyPatch selftests-kdbus-fix-error-paths-in-__kdbus_msg_send.patch
|
||||
|
||||
ApplyPatch kdbus-drop-useless-goto.patch
|
||||
|
||||
ApplyPatch kdbus-fix-operator-precedence-issues-in-item-macros.patch
|
||||
|
||||
ApplyPatch kdbus-use-parentheses-uniformly-in-KDBUS_ITEMS_FOREA.patch
|
||||
|
||||
ApplyPatch Documentation-kdbus-fix-operator-precedence-issue-in.patch
|
||||
|
||||
ApplyPatch Documentation-kdbus-use-parentheses-uniformly-in-KDB.patch
|
||||
|
||||
ApplyPatch selftests-kdbus-fix-trivial-style-issues.patch
|
||||
|
||||
ApplyPatch selftests-kdbus-fix-precedence-issues-in-macros.patch
|
||||
|
||||
ApplyPatch selftests-kdbus-use-parentheses-in-iteration-macros-.patch
|
||||
|
||||
ApplyPatch samples-kdbus-add-whitespace.patch
|
||||
|
||||
ApplyPatch samples-kdbus-fix-operator-precedence-issue-in-KDBUS.patch
|
||||
|
||||
ApplyPatch samples-kdbus-use-parentheses-uniformly-in-KDBUS_FOR.patch
|
||||
|
||||
ApplyPatch kdbus-kdbus_reply_find-return-on-found-entry.patch
|
||||
|
||||
ApplyPatch kdbus-optimize-error-path-in-kdbus_reply_new.patch
|
||||
|
||||
ApplyPatch kdbus-optimize-if-statements-in-kdbus_conn_disconnec.patch
|
||||
|
||||
|
||||
# END OF PATCH APPLICATIONS
|
||||
|
||||
@ -2131,6 +2443,12 @@ fi
|
||||
#
|
||||
#
|
||||
%changelog
|
||||
* Wed Jul 08 2015 Josh Boyer <jwboyer@fedoraproject.org> - 4.2.0-0.rc1.git2.1
|
||||
- Linux v4.2-rc1-33-gd6ac4ffc61ac
|
||||
|
||||
* Tue Jul 07 2015 Josh Boyer <jwboyer@fedoraproject.org>
|
||||
- Add kdbus
|
||||
|
||||
* Tue Jul 07 2015 Josh Boyer <jwboyer@fedoraproject.org> - 4.2.0-0.rc1.git1.1
|
||||
- Linux v4.2-rc1-17-gc7e9ad7da219
|
||||
- Reenable debugging options.
|
||||
|
24
samples-kdbus-add-whitespace.patch
Normal file
24
samples-kdbus-add-whitespace.patch
Normal file
@ -0,0 +1,24 @@
|
||||
From: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Date: Wed, 10 Jun 2015 00:00:06 +0300
|
||||
Subject: [PATCH] samples/kdbus: add whitespace
|
||||
|
||||
Signed-off-by: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
samples/kdbus/kdbus-api.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/samples/kdbus/kdbus-api.h b/samples/kdbus/kdbus-api.h
|
||||
index 5ed5907c5cb4..2de4d6a8c51e 100644
|
||||
--- a/samples/kdbus/kdbus-api.h
|
||||
+++ b/samples/kdbus/kdbus-api.h
|
||||
@@ -13,7 +13,7 @@
|
||||
for (iter = (first); \
|
||||
((uint8_t *)(iter) < (uint8_t *)(first) + (_size)) && \
|
||||
((uint8_t *)(iter) >= (uint8_t *)(first)); \
|
||||
- iter = (void*)(((uint8_t *)iter) + KDBUS_ALIGN8((iter)->size)))
|
||||
+ iter = (void *)(((uint8_t *)iter) + KDBUS_ALIGN8((iter)->size)))
|
||||
|
||||
static inline int kdbus_cmd_bus_make(int control_fd, struct kdbus_cmd *cmd)
|
||||
{
|
47
samples-kdbus-build-kdbus-workers-conditionally.patch
Normal file
47
samples-kdbus-build-kdbus-workers-conditionally.patch
Normal file
@ -0,0 +1,47 @@
|
||||
From: Daniel Mack <daniel@zonque.org>
|
||||
Date: Tue, 31 Mar 2015 15:11:34 +0200
|
||||
Subject: [PATCH] samples: kdbus: build kdbus-workers conditionally
|
||||
|
||||
Give the kdbus sample its own config switch and only build it if it's
|
||||
explicitly switched on.
|
||||
|
||||
Signed-off-by: Daniel Mack <daniel@zonque.org>
|
||||
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Reported-by: Jiri Slaby <jslaby@suse.cz>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
samples/Kconfig | 7 +++++++
|
||||
samples/kdbus/Makefile | 2 +-
|
||||
2 files changed, 8 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/samples/Kconfig b/samples/Kconfig
|
||||
index 224ebb46bed5..a4c6b2f8fa85 100644
|
||||
--- a/samples/Kconfig
|
||||
+++ b/samples/Kconfig
|
||||
@@ -55,6 +55,13 @@ config SAMPLE_KDB
|
||||
Build an example of how to dynamically add the hello
|
||||
command to the kdb shell.
|
||||
|
||||
+config SAMPLE_KDBUS
|
||||
+ bool "Build kdbus API example"
|
||||
+ depends on KDBUS
|
||||
+ help
|
||||
+ Build an example of how the kdbus API can be used from
|
||||
+ userspace.
|
||||
+
|
||||
config SAMPLE_RPMSG_CLIENT
|
||||
tristate "Build rpmsg client sample -- loadable modules only"
|
||||
depends on RPMSG && m
|
||||
diff --git a/samples/kdbus/Makefile b/samples/kdbus/Makefile
|
||||
index e714602b6260..137f84272099 100644
|
||||
--- a/samples/kdbus/Makefile
|
||||
+++ b/samples/kdbus/Makefile
|
||||
@@ -1,7 +1,7 @@
|
||||
# kbuild trick to avoid linker error. Can be omitted if a module is built.
|
||||
obj- := dummy.o
|
||||
|
||||
-hostprogs-y += kdbus-workers
|
||||
+hostprogs-$(CONFIG_SAMPLE_KDBUS) += kdbus-workers
|
||||
|
||||
always := $(hostprogs-y)
|
||||
|
32
samples-kdbus-drop-wrong-include.patch
Normal file
32
samples-kdbus-drop-wrong-include.patch
Normal file
@ -0,0 +1,32 @@
|
||||
From: David Herrmann <dh.herrmann@gmail.com>
|
||||
Date: Mon, 16 Mar 2015 10:17:10 +0100
|
||||
Subject: [PATCH] samples/kdbus: drop wrong include
|
||||
|
||||
There is no reason to use ./include/uapi/ directly from samples. If your
|
||||
system headers are not up-to-date, you _need_ to run "make
|
||||
headers-install" (which will install them to ./usr/ in your kernel tree)
|
||||
before building the examples. Otherwise, you will get warnings and build
|
||||
failures.
|
||||
|
||||
Once ./usr/ is updated with the correct headers, it contains everything we
|
||||
need, so drop -Iinclude/uapi from the kdbus-workers CFLAGS.
|
||||
|
||||
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
samples/kdbus/Makefile | 4 +---
|
||||
1 file changed, 1 insertion(+), 3 deletions(-)
|
||||
|
||||
diff --git a/samples/kdbus/Makefile b/samples/kdbus/Makefile
|
||||
index eee9b9aed632..e714602b6260 100644
|
||||
--- a/samples/kdbus/Makefile
|
||||
+++ b/samples/kdbus/Makefile
|
||||
@@ -5,7 +5,5 @@ hostprogs-y += kdbus-workers
|
||||
|
||||
always := $(hostprogs-y)
|
||||
|
||||
-HOSTCFLAGS_kdbus-workers.o += \
|
||||
- -I$(objtree)/usr/include/ \
|
||||
- -I$(objtree)/include/uapi/
|
||||
+HOSTCFLAGS_kdbus-workers.o += -I$(objtree)/usr/include
|
||||
HOSTLOADLIBES_kdbus-workers := -lrt
|
33
samples-kdbus-fix-operator-precedence-issue-in-KDBUS.patch
Normal file
33
samples-kdbus-fix-operator-precedence-issue-in-KDBUS.patch
Normal file
@ -0,0 +1,33 @@
|
||||
From: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Date: Wed, 10 Jun 2015 00:00:07 +0300
|
||||
Subject: [PATCH] samples/kdbus: fix operator precedence issue in
|
||||
KDBUS_ITEM_NEXT macro
|
||||
|
||||
`item' argument in KDBUS_ITEM_NEXT macro is not enclosed into
|
||||
parentheses when the cast operator is applied, which leads to improper
|
||||
type conversion if `item' is supplied as a complex expression, e.g.
|
||||
|
||||
KDBUS_ITEM_NEXT(condition ? a : b)
|
||||
|
||||
Use parentheses properly to guarantee right precedence.
|
||||
|
||||
Signed-off-by: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
samples/kdbus/kdbus-api.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/samples/kdbus/kdbus-api.h b/samples/kdbus/kdbus-api.h
|
||||
index 2de4d6a8c51e..fab873b89d97 100644
|
||||
--- a/samples/kdbus/kdbus-api.h
|
||||
+++ b/samples/kdbus/kdbus-api.h
|
||||
@@ -8,7 +8,7 @@
|
||||
#define KDBUS_ITEM_HEADER_SIZE offsetof(struct kdbus_item, data)
|
||||
#define KDBUS_ITEM_SIZE(s) KDBUS_ALIGN8((s) + KDBUS_ITEM_HEADER_SIZE)
|
||||
#define KDBUS_ITEM_NEXT(item) \
|
||||
- (typeof(item))(((uint8_t *)item) + KDBUS_ALIGN8((item)->size))
|
||||
+ (typeof(item))((uint8_t *)(item) + KDBUS_ALIGN8((item)->size))
|
||||
#define KDBUS_FOREACH(iter, first, _size) \
|
||||
for (iter = (first); \
|
||||
((uint8_t *)(iter) < (uint8_t *)(first) + (_size)) && \
|
83
samples-kdbus-stub-out-code-for-glibc-2.7.patch
Normal file
83
samples-kdbus-stub-out-code-for-glibc-2.7.patch
Normal file
@ -0,0 +1,83 @@
|
||||
From: Daniel Mack <daniel@zonque.org>
|
||||
Date: Fri, 3 Apr 2015 12:41:52 +0200
|
||||
Subject: [PATCH] samples/kdbus: stub out code for glibc < 2.7
|
||||
|
||||
Andrew Morton reports the following build error in samples/kdbus on Fedora
|
||||
Core 6:
|
||||
|
||||
samples/kdbus/kdbus-workers.c:73:26: error: sys/signalfd.h: No such file or directory
|
||||
samples/kdbus/kdbus-workers.c: In function 'master_new':
|
||||
samples/kdbus/kdbus-workers.c:231: warning: implicit declaration of function 'signalfd'
|
||||
samples/kdbus/kdbus-workers.c:231: error: 'SFD_CLOEXEC' undeclared (first use in this function)
|
||||
samples/kdbus/kdbus-workers.c:231: error: (Each undeclared identifier is reported only once
|
||||
samples/kdbus/kdbus-workers.c:231: error: for each function it appears in.)
|
||||
samples/kdbus/kdbus-workers.c: In function 'master_handle_signal':
|
||||
samples/kdbus/kdbus-workers.c:406: error: storage size of 'val' isn't known
|
||||
samples/kdbus/kdbus-workers.c:406: warning: unused variable 'val'
|
||||
samples/kdbus/kdbus-workers.c: In function 'child_run':
|
||||
samples/kdbus/kdbus-workers.c:773: error: 'CLOCK_MONOTONIC_COARSE' undeclared (first use in this function)
|
||||
samples/kdbus/kdbus-workers.c: In function 'bus_open_connection':
|
||||
samples/kdbus/kdbus-workers.c:1038: error: 'O_CLOEXEC' undeclared (first use in this function)
|
||||
samples/kdbus/kdbus-workers.c: In function 'bus_make':
|
||||
samples/kdbus/kdbus-workers.c:1275: error: 'O_CLOEXEC' undeclared (first use in this function)
|
||||
|
||||
Fedora Core 6 was released in 2006, which predates the introduction of
|
||||
signalfds in the kernel (v2.6.22, 2007).
|
||||
|
||||
The example cannot be built without signalfds, and kbuild cannot depend on
|
||||
specific features of the local libc when building userspace executables, so
|
||||
we have to work around the issue by checking for specific glibc versions at
|
||||
compile time and stub the entire thing if it can't be compiled.
|
||||
|
||||
Reported-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
Signed-off-by: Daniel Mack <daniel@zonque.org>
|
||||
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
---
|
||||
samples/kdbus/kdbus-workers.c | 23 +++++++++++++++++++++--
|
||||
1 file changed, 21 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/samples/kdbus/kdbus-workers.c b/samples/kdbus/kdbus-workers.c
|
||||
index d331e0186899..c3ba958639f3 100644
|
||||
--- a/samples/kdbus/kdbus-workers.c
|
||||
+++ b/samples/kdbus/kdbus-workers.c
|
||||
@@ -57,6 +57,12 @@
|
||||
* top-down, but requires some forward-declarations. Just ignore those.
|
||||
*/
|
||||
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
+/* glibc < 2.7 does not ship sys/signalfd.h */
|
||||
+#if __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 7
|
||||
+
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
@@ -65,8 +71,6 @@
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
-#include <stdio.h>
|
||||
-#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/poll.h>
|
||||
@@ -1324,3 +1328,18 @@ static int bus_make(uid_t uid, const char *name)
|
||||
|
||||
return fd;
|
||||
}
|
||||
+
|
||||
+#else
|
||||
+
|
||||
+#warning "Skipping compilation due to unsupported libc version"
|
||||
+
|
||||
+int main(int argc, char **argv)
|
||||
+{
|
||||
+ fprintf(stderr,
|
||||
+ "Compilation of %s was skipped due to unsupported libc.\n",
|
||||
+ argv[0]);
|
||||
+
|
||||
+ return EXIT_FAILURE;
|
||||
+}
|
||||
+
|
||||
+#endif /* libc sanity check */
|
32
samples-kdbus-use-parentheses-uniformly-in-KDBUS_FOR.patch
Normal file
32
samples-kdbus-use-parentheses-uniformly-in-KDBUS_FOR.patch
Normal file
@ -0,0 +1,32 @@
|
||||
From: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Date: Wed, 10 Jun 2015 00:00:08 +0300
|
||||
Subject: [PATCH] samples/kdbus: use parentheses uniformly in KDBUS_FOREACH
|
||||
macro
|
||||
|
||||
Enclose all arguments into parentheses to stay consistent across the
|
||||
whole macro.
|
||||
|
||||
Signed-off-by: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
samples/kdbus/kdbus-api.h | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/samples/kdbus/kdbus-api.h b/samples/kdbus/kdbus-api.h
|
||||
index fab873b89d97..7f3abae18396 100644
|
||||
--- a/samples/kdbus/kdbus-api.h
|
||||
+++ b/samples/kdbus/kdbus-api.h
|
||||
@@ -10,10 +10,10 @@
|
||||
#define KDBUS_ITEM_NEXT(item) \
|
||||
(typeof(item))((uint8_t *)(item) + KDBUS_ALIGN8((item)->size))
|
||||
#define KDBUS_FOREACH(iter, first, _size) \
|
||||
- for (iter = (first); \
|
||||
+ for ((iter) = (first); \
|
||||
((uint8_t *)(iter) < (uint8_t *)(first) + (_size)) && \
|
||||
((uint8_t *)(iter) >= (uint8_t *)(first)); \
|
||||
- iter = (void *)(((uint8_t *)iter) + KDBUS_ALIGN8((iter)->size)))
|
||||
+ (iter) = (void *)((uint8_t *)(iter) + KDBUS_ALIGN8((iter)->size)))
|
||||
|
||||
static inline int kdbus_cmd_bus_make(int control_fd, struct kdbus_cmd *cmd)
|
||||
{
|
33
selftest-kdbus-enable-cross-compilation.patch
Normal file
33
selftest-kdbus-enable-cross-compilation.patch
Normal file
@ -0,0 +1,33 @@
|
||||
From: Tyler Baker <tyler.baker@linaro.org>
|
||||
Date: Wed, 1 Apr 2015 16:20:16 -0700
|
||||
Subject: [PATCH] selftest/kdbus: enable cross compilation
|
||||
|
||||
Use the CC variable instead of hard coding gcc and include lib.mk.
|
||||
|
||||
Signed-off-by: Tyler Baker <tyler.baker@linaro.org>
|
||||
Acked-by: Shuah Khan <shuahkh@osg.samsung.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
tools/testing/selftests/kdbus/Makefile | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/tools/testing/selftests/kdbus/Makefile b/tools/testing/selftests/kdbus/Makefile
|
||||
index f6cfab26f315..de8242f9b00e 100644
|
||||
--- a/tools/testing/selftests/kdbus/Makefile
|
||||
+++ b/tools/testing/selftests/kdbus/Makefile
|
||||
@@ -33,11 +33,13 @@ OBJS= \
|
||||
|
||||
all: kdbus-test
|
||||
|
||||
+include ../lib.mk
|
||||
+
|
||||
%.o: %.c
|
||||
- gcc $(CFLAGS) -c $< -o $@
|
||||
+ $(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
kdbus-test: $(OBJS)
|
||||
- gcc $(CFLAGS) $^ $(LDLIBS) -o $@
|
||||
+ $(CC) $(CFLAGS) $^ $(LDLIBS) -o $@
|
||||
|
||||
run_tests:
|
||||
./kdbus-test --tap
|
29
selftests-kdbus-drop-duplicated-code-from-__kdbus_ms.patch
Normal file
29
selftests-kdbus-drop-duplicated-code-from-__kdbus_ms.patch
Normal file
@ -0,0 +1,29 @@
|
||||
From: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Date: Wed, 17 Jun 2015 19:33:27 +0300
|
||||
Subject: [PATCH] selftests/kdbus: drop duplicated code from __kdbus_msg_send()
|
||||
|
||||
Set value of `size' in one step instead of four.
|
||||
|
||||
Signed-off-by: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
tools/testing/selftests/kdbus/kdbus-util.c | 5 +----
|
||||
1 file changed, 1 insertion(+), 4 deletions(-)
|
||||
|
||||
diff --git a/tools/testing/selftests/kdbus/kdbus-util.c b/tools/testing/selftests/kdbus/kdbus-util.c
|
||||
index 5b924531d938..d35ec89cb816 100644
|
||||
--- a/tools/testing/selftests/kdbus/kdbus-util.c
|
||||
+++ b/tools/testing/selftests/kdbus/kdbus-util.c
|
||||
@@ -462,10 +462,7 @@ static int __kdbus_msg_send(const struct kdbus_conn *conn,
|
||||
int memfd = -1;
|
||||
int ret;
|
||||
|
||||
- size = sizeof(*msg);
|
||||
- size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
|
||||
- size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
|
||||
- size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
|
||||
+ size = sizeof(*msg) + 3 * KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
|
||||
|
||||
if (dst_id == KDBUS_DST_ID_BROADCAST)
|
||||
size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_bloom_filter)) + 64;
|
33
selftests-kdbus-drop-useless-assignment.patch
Normal file
33
selftests-kdbus-drop-useless-assignment.patch
Normal file
@ -0,0 +1,33 @@
|
||||
From: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Date: Wed, 17 Jun 2015 19:33:25 +0300
|
||||
Subject: [PATCH] selftests/kdbus: drop useless assignment
|
||||
|
||||
Assign returned file descriptor directly to `fd', without intermediate
|
||||
`ret' variable.
|
||||
|
||||
Signed-off-by: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
tools/testing/selftests/kdbus/kdbus-util.c | 8 +++-----
|
||||
1 file changed, 3 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/tools/testing/selftests/kdbus/kdbus-util.c b/tools/testing/selftests/kdbus/kdbus-util.c
|
||||
index 6909fb9b1ce5..5b924531d938 100644
|
||||
--- a/tools/testing/selftests/kdbus/kdbus-util.c
|
||||
+++ b/tools/testing/selftests/kdbus/kdbus-util.c
|
||||
@@ -408,11 +408,9 @@ int sys_memfd_create(const char *name, __u64 size)
|
||||
{
|
||||
int ret, fd;
|
||||
|
||||
- ret = syscall(__NR_memfd_create, name, MFD_ALLOW_SEALING);
|
||||
- if (ret < 0)
|
||||
- return ret;
|
||||
-
|
||||
- fd = ret;
|
||||
+ fd = syscall(__NR_memfd_create, name, MFD_ALLOW_SEALING);
|
||||
+ if (fd < 0)
|
||||
+ return fd;
|
||||
|
||||
ret = ftruncate(fd, size);
|
||||
if (ret < 0) {
|
110
selftests-kdbus-fix-error-paths-in-__kdbus_msg_send.patch
Normal file
110
selftests-kdbus-fix-error-paths-in-__kdbus_msg_send.patch
Normal file
@ -0,0 +1,110 @@
|
||||
From: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Date: Wed, 17 Jun 2015 19:33:28 +0300
|
||||
Subject: [PATCH] selftests/kdbus: fix error paths in __kdbus_msg_send()
|
||||
|
||||
Handle errors properly, free allocated resources.
|
||||
|
||||
Signed-off-by: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
tools/testing/selftests/kdbus/kdbus-util.c | 31 ++++++++++++++++++------------
|
||||
1 file changed, 19 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/tools/testing/selftests/kdbus/kdbus-util.c b/tools/testing/selftests/kdbus/kdbus-util.c
|
||||
index d35ec89cb816..9fac4b31536d 100644
|
||||
--- a/tools/testing/selftests/kdbus/kdbus-util.c
|
||||
+++ b/tools/testing/selftests/kdbus/kdbus-util.c
|
||||
@@ -452,8 +452,8 @@ static int __kdbus_msg_send(const struct kdbus_conn *conn,
|
||||
uint64_t cmd_flags,
|
||||
int cancel_fd)
|
||||
{
|
||||
- struct kdbus_cmd_send *cmd;
|
||||
- struct kdbus_msg *msg;
|
||||
+ struct kdbus_cmd_send *cmd = NULL;
|
||||
+ struct kdbus_msg *msg = NULL;
|
||||
const char ref1[1024 * 128 + 3] = "0123456789_0";
|
||||
const char ref2[] = "0123456789_1";
|
||||
struct kdbus_item *item;
|
||||
@@ -476,14 +476,14 @@ static int __kdbus_msg_send(const struct kdbus_conn *conn,
|
||||
if (write(memfd, "kdbus memfd 1234567", 19) != 19) {
|
||||
ret = -errno;
|
||||
kdbus_printf("writing to memfd failed: %m\n");
|
||||
- return ret;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
ret = sys_memfd_seal_set(memfd);
|
||||
if (ret < 0) {
|
||||
ret = -errno;
|
||||
kdbus_printf("memfd sealing failed: %m\n");
|
||||
- return ret;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_memfd));
|
||||
@@ -496,7 +496,7 @@ static int __kdbus_msg_send(const struct kdbus_conn *conn,
|
||||
if (!msg) {
|
||||
ret = -errno;
|
||||
kdbus_printf("unable to malloc()!?\n");
|
||||
- return ret;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
if (dst_id == KDBUS_DST_ID_BROADCAST)
|
||||
@@ -514,7 +514,7 @@ static int __kdbus_msg_send(const struct kdbus_conn *conn,
|
||||
if (timeout) {
|
||||
ret = clock_gettime(CLOCK_MONOTONIC_COARSE, &now);
|
||||
if (ret < 0)
|
||||
- return ret;
|
||||
+ goto out;
|
||||
|
||||
msg->timeout_ns = now.tv_sec * 1000000000ULL +
|
||||
now.tv_nsec + timeout;
|
||||
@@ -565,6 +565,12 @@ static int __kdbus_msg_send(const struct kdbus_conn *conn,
|
||||
size += KDBUS_ITEM_SIZE(sizeof(cancel_fd));
|
||||
|
||||
cmd = malloc(size);
|
||||
+ if (!cmd) {
|
||||
+ ret = -errno;
|
||||
+ kdbus_printf("unable to malloc()!?\n");
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
cmd->size = size;
|
||||
cmd->flags = cmd_flags;
|
||||
cmd->msg_address = (uintptr_t)msg;
|
||||
@@ -579,12 +585,9 @@ static int __kdbus_msg_send(const struct kdbus_conn *conn,
|
||||
}
|
||||
|
||||
ret = kdbus_cmd_send(conn->fd, cmd);
|
||||
- if (memfd >= 0)
|
||||
- close(memfd);
|
||||
-
|
||||
if (ret < 0) {
|
||||
kdbus_printf("error sending message: %d (%m)\n", ret);
|
||||
- return ret;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
if (cmd_flags & KDBUS_SEND_SYNC_REPLY) {
|
||||
@@ -598,13 +601,17 @@ static int __kdbus_msg_send(const struct kdbus_conn *conn,
|
||||
|
||||
ret = kdbus_free(conn, cmd->reply.offset);
|
||||
if (ret < 0)
|
||||
- return ret;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
+out:
|
||||
free(msg);
|
||||
free(cmd);
|
||||
|
||||
- return 0;
|
||||
+ if (memfd >= 0)
|
||||
+ close(memfd);
|
||||
+
|
||||
+ return ret < 0 ? ret : 0;
|
||||
}
|
||||
|
||||
int kdbus_msg_send(const struct kdbus_conn *conn, const char *name,
|
24
selftests-kdbus-fix-gitignore.patch
Normal file
24
selftests-kdbus-fix-gitignore.patch
Normal file
@ -0,0 +1,24 @@
|
||||
From: David Herrmann <dh.herrmann@gmail.com>
|
||||
Date: Mon, 16 Mar 2015 10:17:13 +0100
|
||||
Subject: [PATCH] selftests/kdbus: fix gitignore
|
||||
|
||||
Drop unused elements from .gitignore (which are leftovers when
|
||||
documentation was placed in the same directory).
|
||||
Add "kdbus-test" to .gitignore, which is the test binary of all kdbus
|
||||
selftests.
|
||||
|
||||
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
tools/testing/selftests/kdbus/.gitignore | 4 +---
|
||||
1 file changed, 1 insertion(+), 3 deletions(-)
|
||||
|
||||
diff --git a/tools/testing/selftests/kdbus/.gitignore b/tools/testing/selftests/kdbus/.gitignore
|
||||
index 7b421f76c888..d3ef42f6ada6 100644
|
||||
--- a/tools/testing/selftests/kdbus/.gitignore
|
||||
+++ b/tools/testing/selftests/kdbus/.gitignore
|
||||
@@ -1,3 +1 @@
|
||||
-*.7
|
||||
-manpage.*
|
||||
-*.proc
|
||||
+kdbus-test
|
53
selftests-kdbus-fix-precedence-issues-in-macros.patch
Normal file
53
selftests-kdbus-fix-precedence-issues-in-macros.patch
Normal file
@ -0,0 +1,53 @@
|
||||
From: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Date: Wed, 10 Jun 2015 00:00:04 +0300
|
||||
Subject: [PATCH] selftests/kdbus: fix precedence issues in macros
|
||||
|
||||
`item' argument in KDBUS_ITEM_NEXT macro is not enclosed into
|
||||
parentheses when the cast operator is applied, which leads to improper
|
||||
type conversion if `item' is supplied as a complex expression, e.g.
|
||||
|
||||
KDBUS_ITEM_NEXT(condition ? a : b)
|
||||
|
||||
RUN_CLONE_CHILD macro has similar issue, missing parentheses around
|
||||
`clone_ret' when using indirection operator.
|
||||
|
||||
Use parentheses properly to guarantee right precedence.
|
||||
|
||||
Signed-off-by: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
tools/testing/selftests/kdbus/kdbus-util.h | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/tools/testing/selftests/kdbus/kdbus-util.h b/tools/testing/selftests/kdbus/kdbus-util.h
|
||||
index b53b03f0565c..df5721ee8f54 100644
|
||||
--- a/tools/testing/selftests/kdbus/kdbus-util.h
|
||||
+++ b/tools/testing/selftests/kdbus/kdbus-util.h
|
||||
@@ -27,7 +27,7 @@
|
||||
#define KDBUS_ITEM_SIZE(s) KDBUS_ALIGN8((s) + KDBUS_ITEM_HEADER_SIZE)
|
||||
|
||||
#define KDBUS_ITEM_NEXT(item) \
|
||||
- (typeof(item))(((uint8_t *)item) + KDBUS_ALIGN8((item)->size))
|
||||
+ (typeof(item))((uint8_t *)(item) + KDBUS_ALIGN8((item)->size))
|
||||
#define KDBUS_ITEM_FOREACH(item, head, first) \
|
||||
for (item = (head)->first; \
|
||||
((uint8_t *)(item) < (uint8_t *)(head) + (head)->size) && \
|
||||
@@ -104,7 +104,7 @@ extern int kdbus_util_verbose;
|
||||
_setup_; \
|
||||
efd = eventfd(0, EFD_CLOEXEC); \
|
||||
ASSERT_RETURN(efd >= 0); \
|
||||
- *clone_ret = 0; \
|
||||
+ *(clone_ret) = 0; \
|
||||
pid = syscall(__NR_clone, flags, NULL); \
|
||||
if (pid == 0) { \
|
||||
eventfd_t event_status = 0; \
|
||||
@@ -129,7 +129,7 @@ extern int kdbus_util_verbose;
|
||||
ret = TEST_OK; \
|
||||
} else { \
|
||||
ret = -errno; \
|
||||
- *clone_ret = -errno; \
|
||||
+ *(clone_ret) = -errno; \
|
||||
} \
|
||||
close(efd); \
|
||||
ret; \
|
98
selftests-kdbus-fix-trivial-style-issues.patch
Normal file
98
selftests-kdbus-fix-trivial-style-issues.patch
Normal file
@ -0,0 +1,98 @@
|
||||
From: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Date: Wed, 10 Jun 2015 00:00:03 +0300
|
||||
Subject: [PATCH] selftests/kdbus: fix trivial style issues
|
||||
|
||||
Signed-off-by: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
tools/testing/selftests/kdbus/kdbus-enum.h | 1 +
|
||||
tools/testing/selftests/kdbus/kdbus-util.c | 2 +-
|
||||
tools/testing/selftests/kdbus/kdbus-util.h | 21 +++++++++------------
|
||||
3 files changed, 11 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/tools/testing/selftests/kdbus/kdbus-enum.h b/tools/testing/selftests/kdbus/kdbus-enum.h
|
||||
index a67cec3512a7..ed28cca26906 100644
|
||||
--- a/tools/testing/selftests/kdbus/kdbus-enum.h
|
||||
+++ b/tools/testing/selftests/kdbus/kdbus-enum.h
|
||||
@@ -6,6 +6,7 @@
|
||||
* Free Software Foundation; either version 2.1 of the License, or (at
|
||||
* your option) any later version.
|
||||
*/
|
||||
+
|
||||
#pragma once
|
||||
|
||||
const char *enum_CMD(long long id);
|
||||
diff --git a/tools/testing/selftests/kdbus/kdbus-util.c b/tools/testing/selftests/kdbus/kdbus-util.c
|
||||
index 9fac4b31536d..29a0cb1aace2 100644
|
||||
--- a/tools/testing/selftests/kdbus/kdbus-util.c
|
||||
+++ b/tools/testing/selftests/kdbus/kdbus-util.c
|
||||
@@ -1355,7 +1355,7 @@ static int all_ids_are_mapped(const char *path)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int all_uids_gids_are_mapped()
|
||||
+int all_uids_gids_are_mapped(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
diff --git a/tools/testing/selftests/kdbus/kdbus-util.h b/tools/testing/selftests/kdbus/kdbus-util.h
|
||||
index 50ff07140bdd..b53b03f0565c 100644
|
||||
--- a/tools/testing/selftests/kdbus/kdbus-util.h
|
||||
+++ b/tools/testing/selftests/kdbus/kdbus-util.h
|
||||
@@ -7,6 +7,7 @@
|
||||
* Free Software Foundation; either version 2.1 of the License, or (at
|
||||
* your option) any later version.
|
||||
*/
|
||||
+
|
||||
#pragma once
|
||||
|
||||
#define BIT(X) (1 << (X))
|
||||
@@ -30,24 +31,22 @@
|
||||
#define KDBUS_ITEM_FOREACH(item, head, first) \
|
||||
for (item = (head)->first; \
|
||||
((uint8_t *)(item) < (uint8_t *)(head) + (head)->size) && \
|
||||
- ((uint8_t *)(item) >= (uint8_t *)(head)); \
|
||||
+ ((uint8_t *)(item) >= (uint8_t *)(head)); \
|
||||
item = KDBUS_ITEM_NEXT(item))
|
||||
#define KDBUS_FOREACH(iter, first, _size) \
|
||||
for (iter = (first); \
|
||||
((uint8_t *)(iter) < (uint8_t *)(first) + (_size)) && \
|
||||
((uint8_t *)(iter) >= (uint8_t *)(first)); \
|
||||
- iter = (void*)(((uint8_t *)iter) + KDBUS_ALIGN8((iter)->size)))
|
||||
-
|
||||
+ iter = (void *)(((uint8_t *)iter) + KDBUS_ALIGN8((iter)->size)))
|
||||
|
||||
-#define _KDBUS_ATTACH_BITS_SET_NR (__builtin_popcountll(_KDBUS_ATTACH_ALL))
|
||||
+#define _KDBUS_ATTACH_BITS_SET_NR (__builtin_popcountll(_KDBUS_ATTACH_ALL))
|
||||
|
||||
/* Sum of KDBUS_ITEM_* that reflects _KDBUS_ATTACH_ALL */
|
||||
-#define KDBUS_ATTACH_ITEMS_TYPE_SUM \
|
||||
- ((((_KDBUS_ATTACH_BITS_SET_NR - 1) * \
|
||||
- ((_KDBUS_ATTACH_BITS_SET_NR - 1) + 1)) / 2 ) + \
|
||||
+#define KDBUS_ATTACH_ITEMS_TYPE_SUM \
|
||||
+ ((((_KDBUS_ATTACH_BITS_SET_NR - 1) * \
|
||||
+ ((_KDBUS_ATTACH_BITS_SET_NR - 1) + 1)) / 2) + \
|
||||
(_KDBUS_ITEM_ATTACH_BASE * _KDBUS_ATTACH_BITS_SET_NR))
|
||||
|
||||
-
|
||||
#define POOL_SIZE (16 * 1024LU * 1024LU)
|
||||
|
||||
#define UNPRIV_UID 65534
|
||||
@@ -207,14 +206,12 @@ int kdbus_add_match_id(struct kdbus_conn *conn, uint64_t cookie,
|
||||
uint64_t type, uint64_t id);
|
||||
int kdbus_add_match_empty(struct kdbus_conn *conn);
|
||||
|
||||
-int all_uids_gids_are_mapped();
|
||||
+int all_uids_gids_are_mapped(void);
|
||||
int drop_privileges(uid_t uid, gid_t gid);
|
||||
uint64_t now(clockid_t clock);
|
||||
char *unique_name(const char *prefix);
|
||||
|
||||
-int userns_map_uid_gid(pid_t pid,
|
||||
- const char *map_uid,
|
||||
- const char *map_gid);
|
||||
+int userns_map_uid_gid(pid_t pid, const char *map_uid, const char *map_gid);
|
||||
int test_is_capable(int cap, ...);
|
||||
int config_user_ns_is_enabled(void);
|
||||
int config_auditsyscall_is_enabled(void);
|
26
selftests-kdbus-handle-cap_get_proc-error-properly.patch
Normal file
26
selftests-kdbus-handle-cap_get_proc-error-properly.patch
Normal file
@ -0,0 +1,26 @@
|
||||
From: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Date: Wed, 17 Jun 2015 19:33:24 +0300
|
||||
Subject: [PATCH] selftests/kdbus: handle cap_get_proc() error properly
|
||||
|
||||
Fix typo in checking error value of cap_get_proc(): cap -> caps
|
||||
|
||||
Signed-off-by: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
tools/testing/selftests/kdbus/kdbus-util.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tools/testing/selftests/kdbus/kdbus-util.c b/tools/testing/selftests/kdbus/kdbus-util.c
|
||||
index 4b376ecfdbed..6909fb9b1ce5 100644
|
||||
--- a/tools/testing/selftests/kdbus/kdbus-util.c
|
||||
+++ b/tools/testing/selftests/kdbus/kdbus-util.c
|
||||
@@ -1547,7 +1547,7 @@ int test_is_capable(int cap, ...)
|
||||
cap_t caps;
|
||||
|
||||
caps = cap_get_proc();
|
||||
- if (!cap) {
|
||||
+ if (!caps) {
|
||||
ret = -errno;
|
||||
kdbus_printf("error cap_get_proc(): %d (%m)\n", ret);
|
||||
return ret;
|
27
selftests-kdbus-install-kdbus-test.patch
Normal file
27
selftests-kdbus-install-kdbus-test.patch
Normal file
@ -0,0 +1,27 @@
|
||||
From: Tyler Baker <tyler.baker@linaro.org>
|
||||
Date: Tue, 21 Apr 2015 15:50:51 -0700
|
||||
Subject: [PATCH] selftests/kdbus: install kdbus-test
|
||||
|
||||
Set TEST_PROGS so that kdbus-test is installed.
|
||||
|
||||
Acked-by: Michael Ellerman <mpe@ellerman.id.au>
|
||||
Signed-off-by: Tyler Baker <tyler.baker@linaro.org>
|
||||
Cc: Shuah Khan <shuahkh@osg.samsung.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
tools/testing/selftests/kdbus/Makefile | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/tools/testing/selftests/kdbus/Makefile b/tools/testing/selftests/kdbus/Makefile
|
||||
index 7ad587b3c767..8f36cb5667cc 100644
|
||||
--- a/tools/testing/selftests/kdbus/Makefile
|
||||
+++ b/tools/testing/selftests/kdbus/Makefile
|
||||
@@ -40,6 +40,8 @@ include ../lib.mk
|
||||
kdbus-test: $(OBJS)
|
||||
$(CC) $(CFLAGS) $^ $(LDLIBS) -o $@
|
||||
|
||||
+TEST_PROGS := kdbus-test
|
||||
+
|
||||
run_tests:
|
||||
./kdbus-test --tap
|
||||
|
40
selftests-kdbus-remove-useless-initializations-from-.patch
Normal file
40
selftests-kdbus-remove-useless-initializations-from-.patch
Normal file
@ -0,0 +1,40 @@
|
||||
From: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Date: Wed, 17 Jun 2015 19:33:26 +0300
|
||||
Subject: [PATCH] selftests/kdbus: remove useless initializations from
|
||||
kdbus_clone_userns_test()
|
||||
|
||||
Do not initialize efd, unpriv_conn_id, userns_conn_id and monitor. These
|
||||
vars are assigned to values later in code while initial values are never
|
||||
used.
|
||||
|
||||
Signed-off-by: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
tools/testing/selftests/kdbus/test-metadata-ns.c | 9 +++------
|
||||
1 file changed, 3 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/tools/testing/selftests/kdbus/test-metadata-ns.c b/tools/testing/selftests/kdbus/test-metadata-ns.c
|
||||
index 2cb1d4d2a5be..ccdfae06922b 100644
|
||||
--- a/tools/testing/selftests/kdbus/test-metadata-ns.c
|
||||
+++ b/tools/testing/selftests/kdbus/test-metadata-ns.c
|
||||
@@ -281,16 +281,13 @@ out:
|
||||
static int kdbus_clone_userns_test(const char *bus,
|
||||
struct kdbus_conn *conn)
|
||||
{
|
||||
- int ret;
|
||||
- int status;
|
||||
- int efd = -1;
|
||||
+ int ret, status, efd;
|
||||
pid_t pid, ppid;
|
||||
- uint64_t unpriv_conn_id = 0;
|
||||
- uint64_t userns_conn_id = 0;
|
||||
+ uint64_t unpriv_conn_id, userns_conn_id;
|
||||
struct kdbus_msg *msg;
|
||||
const struct kdbus_item *item;
|
||||
struct kdbus_pids expected_pids;
|
||||
- struct kdbus_conn *monitor = NULL;
|
||||
+ struct kdbus_conn *monitor;
|
||||
|
||||
kdbus_printf("STARTING TEST 'metadata-ns'.\n");
|
||||
|
39
selftests-kdbus-use-parentheses-in-iteration-macros-.patch
Normal file
39
selftests-kdbus-use-parentheses-in-iteration-macros-.patch
Normal file
@ -0,0 +1,39 @@
|
||||
From: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Date: Wed, 10 Jun 2015 00:00:05 +0300
|
||||
Subject: [PATCH] selftests/kdbus: use parentheses in iteration macros
|
||||
uniformly
|
||||
|
||||
Enclose all arguments into parentheses in KDBUS_ITEM_FOREACH and
|
||||
KDBUS_FOREACH macros to stay consistent across the whole macro.
|
||||
|
||||
Signed-off-by: Sergei Zviagintsev <sergei@s15v.net>
|
||||
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
tools/testing/selftests/kdbus/kdbus-util.h | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/tools/testing/selftests/kdbus/kdbus-util.h b/tools/testing/selftests/kdbus/kdbus-util.h
|
||||
index df5721ee8f54..d1a0f1b4d0eb 100644
|
||||
--- a/tools/testing/selftests/kdbus/kdbus-util.h
|
||||
+++ b/tools/testing/selftests/kdbus/kdbus-util.h
|
||||
@@ -29,15 +29,15 @@
|
||||
#define KDBUS_ITEM_NEXT(item) \
|
||||
(typeof(item))((uint8_t *)(item) + KDBUS_ALIGN8((item)->size))
|
||||
#define KDBUS_ITEM_FOREACH(item, head, first) \
|
||||
- for (item = (head)->first; \
|
||||
+ for ((item) = (head)->first; \
|
||||
((uint8_t *)(item) < (uint8_t *)(head) + (head)->size) && \
|
||||
((uint8_t *)(item) >= (uint8_t *)(head)); \
|
||||
- item = KDBUS_ITEM_NEXT(item))
|
||||
+ (item) = KDBUS_ITEM_NEXT(item))
|
||||
#define KDBUS_FOREACH(iter, first, _size) \
|
||||
- for (iter = (first); \
|
||||
+ for ((iter) = (first); \
|
||||
((uint8_t *)(iter) < (uint8_t *)(first) + (_size)) && \
|
||||
((uint8_t *)(iter) >= (uint8_t *)(first)); \
|
||||
- iter = (void *)(((uint8_t *)iter) + KDBUS_ALIGN8((iter)->size)))
|
||||
+ (iter) = (void *)((uint8_t *)(iter) + KDBUS_ALIGN8((iter)->size)))
|
||||
|
||||
#define _KDBUS_ATTACH_BITS_SET_NR (__builtin_popcountll(_KDBUS_ATTACH_ALL))
|
||||
|
Loading…
Reference in New Issue
Block a user