* Re: [PATCH v2] ipc: Modify message queue accounting to reflect both total user data and auxiliary kernel data
From: Doug Ledford @ 2015-07-07 18:49 UTC (permalink / raw)
To: Marcus Gelderie
Cc: Michael Kerrisk (man-pages), Davidlohr Bueso, linux-kernel,
David Howells, Alexander Viro, John Duffy, Arto Bendiken,
Linux API
In-Reply-To: <20150625185019.GA17933-dYYy/5+rgCadFe0WYshgmA@public.gmane.org_W_724V_09011603_00_009>
[-- Attachment #1: Type: text/plain, Size: 9220 bytes --]
> On Jun 25, 2015, at 2:50 PM, Marcus Gelderie <redmnic-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>
> Hey all,
>
> answers in text below...
>
> TLDR: I can remove the QKERSIZE field, as I believe that it does not affect he
> RLIMIT accounting (details [=code] below). Question is: Should it?
>
> Before I provide another patch, I would appreciate another round of feedback, though.
>
> So…
> On Thu, Jun 25, 2015 at 09:23:33AM +0200, Michael Kerrisk (man-pages) wrote:
>> On 25 June 2015 at 07:47, Davidlohr Bueso <dave-h16yJtLeMjHk1uMJSBkQmQ@public.gmane.org> wrote:
>>> Good catch, and a nice opportunity to make the mq manpage more specific
>>> wrt to queue sizes.
>>>
>>> [...]
>>>
> ACK, I can write a patch for the manpage once we figure out what to do
> here.
>>>> Reporting the size of the message queue in kernel has its merits, but
>>>> doing so in the QSIZE field of the pseudo file corresponding to the
>>>> queue is a breaking change, as mentioned above. This patch therefore
>>>> returns the QSIZE field to its original meaning. At the same time,
>>>> it introduces a new field QKERSIZE that reflects the size of the queue
>>>> in kernel (user data + kernel data).
>>>
>>> Hmmm I'm not sure about this. What are the specific benefits of having
>>> QKERSIZE? We don't export in-kernel data like this in any other ipc
>>> (posix or sysv) mechanism, afaik. Plus, we do not compromise kernel data
>>> structures like this, as we would break userspace if later we change
>>> posix_msg_tree_node. So NAK to this.
>>>
>>> I would just remove the extra
>>> + info->qsize += sizeof(struct posix_msg_tree_node);
>>>
>>> bits from d6629859b36 (along with -stable v3.5), plus a patch updating
>>> the manpage that this field only reflects user data.
>>
> This can be done if the RLIMIT accounting is not done against that
> value (more below).
>
>> I've been hoping that Doug would jump into this discussion…
Sorry to have been quiet so far. PTO interfered.
>> If I recall/understand Doug correctly (see
>> http://thread.gmane.org/gmane.linux.man/7050/focus=1797645 ), his
>> rationale for the QSIZE change was that it then revealed a value that
>> was closer to what was being used to account against the
>> RLIMIT_MSGQUEUE resource limit. (Even with these changes, the QSIZE
>> value was not 100% accurate for accounting against RLIMIT_MSGQUEUE,
>> since some pieces of kernel overhead were still not being accounted
>> for. Nevertheless, it's much closer than the old (pre 3.5) QSIZE for
>> some corner cases.) Thus, Marcus's rationale for preserving this info
>> as QKERSIZE.
Yes. A bit more rationale was that the change to use an rbtree for priorities made the worst case scenario for queue size grow quite a lot. This is especially true when dealing with queues with a very small message size. If we didn’t account for some of this growth in size, we opened ourselves up to a DDoS type attack where a malicious user could create lots of queues with very small message sizes and lots of messages and then just create enough messages of different priorities to force allocating all of these structs. Since they would be allowed to create 1 byte messages in the queue, and could easily create a 1024 element queue, that would be a 1k accounting for user data that in worst case scenario used up something like 96k of kernel memory. With the default RLIMIT for msg queues being something like 800K, let’s just assume one user id can create 800 * 96k of kernel memory allocations, so 72MB of kernel memory used per user id. Given a few user ids, it can actually be significant. And all the while the sysadmin is scratching his head going “where the hell is all my memory going?” because there is no clear indication that a 1 byte message in the POSIX mqueue subsystem is consuming 96bytes or so of kernel memory.
So, just to be clear, my rationale here is “Breaking expectations is bad, but leaving a possible DDoS style exploit is worse”. That’s why I changed the accounting. I had one or two users complain that they had to administratively adjust the RLIMIT_MSGQUEUE setting on their servers to compensate, but that’s as it should be. Now they *know* where their memory is being used instead of having a lurking memory black hole in their system. For those users that use large message sizes, they didn’t even notice the change, it was just lost in the noise.
>
> Actually, looking at the code, it seems to me that the QKERSIZE
> (a.k.a. the current qsize field) is actually not used for the purpose of
> accounting at all. From ipc/mqueue.c (line 281 ff, comments added by me):
>
> /* worst case estimate for the btree in memory */
>
> mq_treesize = info->attr.mq_maxmsg * sizeof(struct msg_msg) +
> min_t(unsigned int, info->attr.mq_maxmsg, MQ_PRIO_MAX) *
> sizeof(struct posix_msg_tree_node);
>
> /* worst case estimate for the user data in the queue */
>
> mq_bytes = mq_treesize + (info->attr.mq_maxmsg *
> info->attr.mq_msgsize);
>
> spin_lock(&mq_lock);
>
> /* acutal accounting; u->mq_bytes is the other
> * message queus for this user (computed in the way
> * above (i.e. worst-case estimates)
> */
>
> if (u->mq_bytes + mq_bytes < u->mq_bytes ||
> u->mq_bytes + mq_bytes > rlimit(RLIMIT_MSGQUEUE)) {
> [....]
> ret = -EMFILE;
> [.....]
>
> So, I think that if the RLIMIT should take the actual size (not the
> worst case) into account, then we have a bug. I can write a patch, but that
> should be separate from this... meaning I'll turn this into a patchset.
>
> However, we should decide what we want first: If I read the manpage (mq_overview), I
> am inclined to think that the RLIMIT should use the acutal amount of
> data occupied by the queue (or at least the user data). But it does not
> necessarily rule out an accounting against worst-case estimation (to me
> at least).
You have to use worst case. You don’t have a choice. The reason is that the check is only performed at queue creation time (and the user API expects this), so once the queue is created and the user is allowed to use it, failure due to RLIMIT issues is no longer allowed. We therefore must use whatever worst case scenario we wish to use when we test the size during creation and then we have to be OK with the variance we might get from that during real world usage. My tests/maths were intended to be “close enough” that they couldn’t be fooled with small message sizes and large queue sizes, but not intended to be perfect.
>> Now whether QKERSIZE is actually useful or used by anyone is another
>> question. As far as I know, there was no user request that drove the
>> change. But Doug can perhaps say something to this. QSIZE should I
>> think definitely be fixed (reverted to pre-3.5 behavior). I'm agnostic
>> about QKERSIZE.
Here’s what I would prefer to see happen:
1) Keep the maths as they are. We need to account worst case because apps don’t expect run time checks/failures.
2) Keep accounting for kernel data size as part of queue size and adding both before checking it against the rlimit for the user.
3) Create a new mq_create call that take a new mq_attr struct. This struct should add a field for max_priorities. For existing apps, the current default of 32,768 priorities can be used. For other apps, let them select their requested number of priorities. By selecting lower numbers of priorities, that worst case scenario gets much better (as long as their queue size is larger than their number of priorities).
Or, as an alternative:
1) Change the maths to account for the msg struct, but ignore the rbtree structs. This is still different from when I made my change in that the maths used to only account for a msg struct *. This would put the overall total change somewhere in between real memory usage and memory queue size. For instance, if you had a 1k queue of 1 byte messages, here’s how it lays out:
Pre-3.5 math: 1k * (1byte + (sizeof *)) = 5k or 9k (32/64bit arch)
Pre-3.5 reality: 1k * (1byte + (sizeof *) + sizeof (struct msg_msg) + unaccounted stuff) = 50ishk
Post-3.5 math: 1k * (1byte + sizeof (struct msg_msg) + sizeof (struct msg_node)) = 90ishk
Post-3.5 reality: 90ishk
Proposed math: 1k * (qbyte + sizeof (struc msg_msg)) = 50ishk
Proposed reality: 90ishk
The reason I suggest this is that the real world usage I’ve seen does not use lots of priorities. So, even though the *worst case* reality is 90k, the common case will be in the 50k range like the math. Given that we are less than a 2 to 1 ratio of worst case to math, a DDoS is unlikely to go undetected. The only real problem here is that if you have an admin that wants to create lots of queues and use as much ram as possible, and they use lots of priorities, then they might get confused when their calculated sizes of mqueues fills RAM faster than they expected and the actually run out of RAM in use.
—
Doug Ledford <dledford-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
GPG Key ID: 0E572FDD
[-- Attachment #2: Message signed with OpenPGP using GPGMail --]
[-- Type: application/pgp-signature, Size: 842 bytes --]
^ permalink raw reply
* Re: [PATCH V3 0/5] Allow user to request memory to be locked on page fault
From: Andrew Morton @ 2015-07-07 21:16 UTC (permalink / raw)
To: Eric B Munson
Cc: Shuah Khan, Michal Hocko, Michael Kerrisk, Vlastimil Babka,
linux-alpha-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-mips-6z/3iImG2C8G8FEW9MqTrA,
linux-parisc-u79uwXL29TY76Z2rM5mHXA,
linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ,
sparclinux-u79uwXL29TY76Z2rM5mHXA,
linux-xtensa-PjhNF2WwrV/0Sa2dR60CXw,
linux-mm-Bw31MaZKKs3YtjvyW6yDsg,
linux-arch-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1436288623-13007-1-git-send-email-emunson-JqFfY2XvxFXQT0dZR+AlfA@public.gmane.org>
On Tue, 7 Jul 2015 13:03:38 -0400 Eric B Munson <emunson-JqFfY2XvxFXQT0dZR+AlfA@public.gmane.org> wrote:
> mlock() allows a user to control page out of program memory, but this
> comes at the cost of faulting in the entire mapping when it is
> allocated. For large mappings where the entire area is not necessary
> this is not ideal. Instead of forcing all locked pages to be present
> when they are allocated, this set creates a middle ground. Pages are
> marked to be placed on the unevictable LRU (locked) when they are first
> used, but they are not faulted in by the mlock call.
>
> This series introduces a new mlock() system call that takes a flags
> argument along with the start address and size. This flags argument
> gives the caller the ability to request memory be locked in the
> traditional way, or to be locked after the page is faulted in. New
> calls are added for munlock() and munlockall() which give the called a
> way to specify which flags are supposed to be cleared. A new MCL flag
> is added to mirror the lock on fault behavior from mlock() in
> mlockall(). Finally, a flag for mmap() is added that allows a user to
> specify that the covered are should not be paged out, but only after the
> memory has been used the first time.
Thanks for sticking with this. Adding new syscalls is a bit of a
hassle but I do think we end up with a better interface - the existing
mlock/munlock/mlockall interfaces just aren't appropriate for these
things.
I don't know whether these syscalls should be documented via new
manpages, or if we should instead add them to the existing
mlock/munlock/mlockall manpages. Michael, could you please advise?
^ permalink raw reply
* Re: [PATCH V3 5/5] selftests: vm: Add tests for lock on fault
From: Andrew Morton @ 2015-07-07 21:51 UTC (permalink / raw)
To: Eric B Munson
Cc: Shuah Khan, Michal Hocko, Vlastimil Babka,
linux-mm-Bw31MaZKKs3YtjvyW6yDsg,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1436288623-13007-6-git-send-email-emunson-JqFfY2XvxFXQT0dZR+AlfA@public.gmane.org>
On Tue, 7 Jul 2015 13:03:43 -0400 Eric B Munson <emunson-JqFfY2XvxFXQT0dZR+AlfA@public.gmane.org> wrote:
> Test the mmap() flag, and the mlockall() flag. These tests ensure that
> pages are not faulted in until they are accessed, that the pages are
> unevictable once faulted in, and that VMA splitting and merging works
> with the new VM flag. The second test ensures that mlock limits are
> respected. Note that the limit test needs to be run a normal user.
So we don't have tests for the new syscalls?
I have renumbered those syscalls (added 1) because of sys_userfaultfd.
^ permalink raw reply
* Re: [RFCv3 0/5] enable migration of driver pages
From: Andrew Morton @ 2015-07-07 22:37 UTC (permalink / raw)
To: Gioh Kim
Cc: aquini, mst, linux-api, linux-kernel, virtualization, bfields,
minchan, Gioh Kim, linux-mm, viro, gunho.lee, linux-fsdevel,
jlayton, koct9i, iamjoonsoo.kim, vbabka
In-Reply-To: <1436243785-24105-1-git-send-email-gioh.kim@lge.com>
On Tue, 7 Jul 2015 13:36:20 +0900 Gioh Kim <gioh.kim@lge.com> wrote:
> From: Gioh Kim <gurugio@hanmail.net>
>
> Hello,
>
> This series try to enable migration of non-LRU pages, such as driver's page.
>
> My ARM-based platform occured severe fragmentation problem after long-term
> (several days) test. Sometimes even order-3 page allocation failed. It has
> memory size 512MB ~ 1024MB. 30% ~ 40% memory is consumed for graphic processing
> and 20~30 memory is reserved for zram.
>
> I found that many pages of GPU driver and zram are non-movable pages. So I
> reported Minchan Kim, the maintainer of zram, and he made the internal
> compaction logic of zram. And I made the internal compaction of GPU driver.
>
> They reduced some fragmentation but they are not enough effective.
> They are activated by its own interface, /sys, so they are not cooperative
> with kernel compaction. If there is too much fragmentation and kernel starts
> to compaction, zram and GPU driver cannot work with the kernel compaction.
>
> ...
>
> This patch set is tested:
> - turn on Ubuntu 14.04 with 1G memory on qemu.
> - do kernel building
> - after several seconds check more than 512MB is used with free command
> - command "balloon 512" in qemu monitor
> - check hundreds MB of pages are migrated
OK, but what happens if the balloon driver is not used to force
compaction? Does your test machine successfully compact pages on
demand, so those order-3 allocations now succeed?
Why are your changes to the GPU driver not included in this patch series?
^ permalink raw reply
* Re: [RFCv3 0/5] enable migration of driver pages
From: Gioh Kim @ 2015-07-08 0:02 UTC (permalink / raw)
To: Andrew Morton
Cc: jlayton, bfields, vbabka, iamjoonsoo.kim, viro, mst, koct9i,
minchan, aquini, linux-fsdevel, virtualization, linux-kernel,
linux-api, linux-mm, gunho.lee, Gioh Kim
In-Reply-To: <20150707153701.bfcde75108d1fb8aaedc8134@linux-foundation.org>
2015-07-08 오전 7:37에 Andrew Morton 이(가) 쓴 글:
> On Tue, 7 Jul 2015 13:36:20 +0900 Gioh Kim <gioh.kim@lge.com> wrote:
>
>> From: Gioh Kim <gurugio@hanmail.net>
>>
>> Hello,
>>
>> This series try to enable migration of non-LRU pages, such as driver's page.
>>
>> My ARM-based platform occured severe fragmentation problem after long-term
>> (several days) test. Sometimes even order-3 page allocation failed. It has
>> memory size 512MB ~ 1024MB. 30% ~ 40% memory is consumed for graphic processing
>> and 20~30 memory is reserved for zram.
>>
>> I found that many pages of GPU driver and zram are non-movable pages. So I
>> reported Minchan Kim, the maintainer of zram, and he made the internal
>> compaction logic of zram. And I made the internal compaction of GPU driver.
>>
>> They reduced some fragmentation but they are not enough effective.
>> They are activated by its own interface, /sys, so they are not cooperative
>> with kernel compaction. If there is too much fragmentation and kernel starts
>> to compaction, zram and GPU driver cannot work with the kernel compaction.
>>
>> ...
>>
>> This patch set is tested:
>> - turn on Ubuntu 14.04 with 1G memory on qemu.
>> - do kernel building
>> - after several seconds check more than 512MB is used with free command
>> - command "balloon 512" in qemu monitor
>> - check hundreds MB of pages are migrated
>
> OK, but what happens if the balloon driver is not used to force
> compaction? Does your test machine successfully compact pages on
> demand, so those order-3 allocations now succeed?
If any driver that has many pages like the balloon driver is forced to compact,
the system can get free high-order pages.
I have to show how this patch work with a driver existing in the kernel source,
for kernel developers' undestanding. So I selected the balloon driver
because it has already compaction and working with kernel compaction.
I can show how driver pages is compacted with lru-pages together.
Actually balloon driver is not best example to show how this patch compacts pages.
The balloon driver compaction is decreasing page consumtion, for instance 1024MB -> 512MB.
I think it is not compaction precisely. It frees pages.
Of course there will be many high-order pages after 512MB is freed.
>
> Why are your changes to the GPU driver not included in this patch series?
My platform is ARM-based and GPU is ARM-Mali. The driver is not open source.
It's too bad that I cannot show effect of this patch with the GPU driver.
>
>
>
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: [RFCv3 0/5] enable migration of driver pages
From: Andrew Morton @ 2015-07-08 0:07 UTC (permalink / raw)
To: Gioh Kim
Cc: jlayton-vpEMnDpepFuMZCB2o+C8xQ, bfields-uC3wQj2KruNg9hUCZPvPmw,
vbabka-AlSwsSmVLrQ, iamjoonsoo.kim-Hm3cg6mZ9cc,
viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn, mst-H+wXaHxf7aLQT0dZR+AlfA,
koct9i-Re5JQEeQqe8AvxtiuMwx3w, minchan-DgEjT+Ai2ygdnm+yROfE0A,
aquini-H+wXaHxf7aLQT0dZR+AlfA,
linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
virtualization-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA, linux-mm-Bw31MaZKKs3YtjvyW6yDsg,
gunho.lee-Hm3cg6mZ9cc, Gioh Kim
In-Reply-To: <559C68B3.3010105-Hm3cg6mZ9cc@public.gmane.org>
On Wed, 08 Jul 2015 09:02:59 +0900 Gioh Kim <gioh.kim-Hm3cg6mZ9cc@public.gmane.org> wrote:
>
>
> 2015-07-08 ______ 7:37___ Andrew Morton ___(___) ___ ___:
> > On Tue, 7 Jul 2015 13:36:20 +0900 Gioh Kim <gioh.kim-Hm3cg6mZ9cc@public.gmane.org> wrote:
> >
> >> From: Gioh Kim <gurugio-A7HHaXTFBl7R7s880joybQ@public.gmane.org>
> >>
> >> Hello,
> >>
> >> This series try to enable migration of non-LRU pages, such as driver's page.
> >>
> >> My ARM-based platform occured severe fragmentation problem after long-term
> >> (several days) test. Sometimes even order-3 page allocation failed. It has
> >> memory size 512MB ~ 1024MB. 30% ~ 40% memory is consumed for graphic processing
> >> and 20~30 memory is reserved for zram.
> >>
> >> I found that many pages of GPU driver and zram are non-movable pages. So I
> >> reported Minchan Kim, the maintainer of zram, and he made the internal
> >> compaction logic of zram. And I made the internal compaction of GPU driver.
> >>
> >> They reduced some fragmentation but they are not enough effective.
> >> They are activated by its own interface, /sys, so they are not cooperative
> >> with kernel compaction. If there is too much fragmentation and kernel starts
> >> to compaction, zram and GPU driver cannot work with the kernel compaction.
> >>
> >> ...
> >>
> >> This patch set is tested:
> >> - turn on Ubuntu 14.04 with 1G memory on qemu.
> >> - do kernel building
> >> - after several seconds check more than 512MB is used with free command
> >> - command "balloon 512" in qemu monitor
> >> - check hundreds MB of pages are migrated
> >
> > OK, but what happens if the balloon driver is not used to force
> > compaction? Does your test machine successfully compact pages on
> > demand, so those order-3 allocations now succeed?
>
> If any driver that has many pages like the balloon driver is forced to compact,
> the system can get free high-order pages.
>
> I have to show how this patch work with a driver existing in the kernel source,
> for kernel developers' undestanding. So I selected the balloon driver
> because it has already compaction and working with kernel compaction.
> I can show how driver pages is compacted with lru-pages together.
>
> Actually balloon driver is not best example to show how this patch compacts pages.
> The balloon driver compaction is decreasing page consumtion, for instance 1024MB -> 512MB.
> I think it is not compaction precisely. It frees pages.
> Of course there will be many high-order pages after 512MB is freed.
Can the various in-kernel GPU drivers benefit from this? If so, wiring
up one or more of those would be helpful?
^ permalink raw reply
* Re: [RFCv3 0/5] enable migration of driver pages
From: Gioh Kim @ 2015-07-08 0:19 UTC (permalink / raw)
To: Andrew Morton
Cc: jlayton, bfields, vbabka, iamjoonsoo.kim, viro, mst, koct9i,
minchan, aquini, linux-fsdevel, virtualization, linux-kernel,
linux-api, linux-mm, gunho.lee, Gioh Kim
In-Reply-To: <20150707170746.1b91ba0d07382cbc9ba3db92@linux-foundation.org>
2015-07-08 오전 9:07에 Andrew Morton 이(가) 쓴 글:
> On Wed, 08 Jul 2015 09:02:59 +0900 Gioh Kim <gioh.kim@lge.com> wrote:
>
>>
>>
>> 2015-07-08 ______ 7:37___ Andrew Morton ___(___) ___ ___:
>>> On Tue, 7 Jul 2015 13:36:20 +0900 Gioh Kim <gioh.kim@lge.com> wrote:
>>>
>>>> From: Gioh Kim <gurugio@hanmail.net>
>>>>
>>>> Hello,
>>>>
>>>> This series try to enable migration of non-LRU pages, such as driver's page.
>>>>
>>>> My ARM-based platform occured severe fragmentation problem after long-term
>>>> (several days) test. Sometimes even order-3 page allocation failed. It has
>>>> memory size 512MB ~ 1024MB. 30% ~ 40% memory is consumed for graphic processing
>>>> and 20~30 memory is reserved for zram.
>>>>
>>>> I found that many pages of GPU driver and zram are non-movable pages. So I
>>>> reported Minchan Kim, the maintainer of zram, and he made the internal
>>>> compaction logic of zram. And I made the internal compaction of GPU driver.
>>>>
>>>> They reduced some fragmentation but they are not enough effective.
>>>> They are activated by its own interface, /sys, so they are not cooperative
>>>> with kernel compaction. If there is too much fragmentation and kernel starts
>>>> to compaction, zram and GPU driver cannot work with the kernel compaction.
>>>>
>>>> ...
>>>>
>>>> This patch set is tested:
>>>> - turn on Ubuntu 14.04 with 1G memory on qemu.
>>>> - do kernel building
>>>> - after several seconds check more than 512MB is used with free command
>>>> - command "balloon 512" in qemu monitor
>>>> - check hundreds MB of pages are migrated
>>>
>>> OK, but what happens if the balloon driver is not used to force
>>> compaction? Does your test machine successfully compact pages on
>>> demand, so those order-3 allocations now succeed?
>>
>> If any driver that has many pages like the balloon driver is forced to compact,
>> the system can get free high-order pages.
>>
>> I have to show how this patch work with a driver existing in the kernel source,
>> for kernel developers' undestanding. So I selected the balloon driver
>> because it has already compaction and working with kernel compaction.
>> I can show how driver pages is compacted with lru-pages together.
>>
>> Actually balloon driver is not best example to show how this patch compacts pages.
>> The balloon driver compaction is decreasing page consumtion, for instance 1024MB -> 512MB.
>> I think it is not compaction precisely. It frees pages.
>> Of course there will be many high-order pages after 512MB is freed.
>
> Can the various in-kernel GPU drivers benefit from this? If so, wiring
> up one or more of those would be helpful?
I'm sure that other in-kernel GPU drivers can have benefit.
It must be helpful.
If I was familiar with other in-kernel GPU drivers code, I tried to patch them.
It's too bad.
Minchan Kim said he had a plan to apply this patch into zram compaction.
Many embedded machines use several hundreds MB for zram.
The zram can also have benefit with this patch as much as GPU drivers.
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
^ permalink raw reply
* Re: [RFCv3 0/5] enable migration of driver pages
From: Minchan Kim @ 2015-07-08 0:35 UTC (permalink / raw)
To: Gioh Kim
Cc: jlayton, aquini, mst, linux-api, linux-kernel, virtualization,
bfields, linux-mm, Gioh Kim, viro, gunho.lee, linux-fsdevel,
iamjoonsoo.kim, koct9i, Andrew Morton, vbabka
In-Reply-To: <559C6CA6.1050809@lge.com>
On Wed, Jul 08, 2015 at 09:19:50AM +0900, Gioh Kim wrote:
>
>
> 2015-07-08 오전 9:07에 Andrew Morton 이(가) 쓴 글:
> >On Wed, 08 Jul 2015 09:02:59 +0900 Gioh Kim <gioh.kim@lge.com> wrote:
> >
> >>
> >>
> >>2015-07-08 ______ 7:37___ Andrew Morton ___(___) ___ ___:
> >>>On Tue, 7 Jul 2015 13:36:20 +0900 Gioh Kim <gioh.kim@lge.com> wrote:
> >>>
> >>>>From: Gioh Kim <gurugio@hanmail.net>
> >>>>
> >>>>Hello,
> >>>>
> >>>>This series try to enable migration of non-LRU pages, such as driver's page.
> >>>>
> >>>>My ARM-based platform occured severe fragmentation problem after long-term
> >>>>(several days) test. Sometimes even order-3 page allocation failed. It has
> >>>>memory size 512MB ~ 1024MB. 30% ~ 40% memory is consumed for graphic processing
> >>>>and 20~30 memory is reserved for zram.
> >>>>
> >>>>I found that many pages of GPU driver and zram are non-movable pages. So I
> >>>>reported Minchan Kim, the maintainer of zram, and he made the internal
> >>>>compaction logic of zram. And I made the internal compaction of GPU driver.
> >>>>
> >>>>They reduced some fragmentation but they are not enough effective.
> >>>>They are activated by its own interface, /sys, so they are not cooperative
> >>>>with kernel compaction. If there is too much fragmentation and kernel starts
> >>>>to compaction, zram and GPU driver cannot work with the kernel compaction.
> >>>>
> >>>>...
> >>>>
> >>>>This patch set is tested:
> >>>>- turn on Ubuntu 14.04 with 1G memory on qemu.
> >>>>- do kernel building
> >>>>- after several seconds check more than 512MB is used with free command
> >>>>- command "balloon 512" in qemu monitor
> >>>>- check hundreds MB of pages are migrated
> >>>
> >>>OK, but what happens if the balloon driver is not used to force
> >>>compaction? Does your test machine successfully compact pages on
> >>>demand, so those order-3 allocations now succeed?
> >>
> >>If any driver that has many pages like the balloon driver is forced to compact,
> >>the system can get free high-order pages.
> >>
> >>I have to show how this patch work with a driver existing in the kernel source,
> >>for kernel developers' undestanding. So I selected the balloon driver
> >>because it has already compaction and working with kernel compaction.
> >>I can show how driver pages is compacted with lru-pages together.
> >>
> >>Actually balloon driver is not best example to show how this patch compacts pages.
> >>The balloon driver compaction is decreasing page consumtion, for instance 1024MB -> 512MB.
> >>I think it is not compaction precisely. It frees pages.
> >>Of course there will be many high-order pages after 512MB is freed.
> >
> >Can the various in-kernel GPU drivers benefit from this? If so, wiring
> >up one or more of those would be helpful?
>
> I'm sure that other in-kernel GPU drivers can have benefit.
> It must be helpful.
>
> If I was familiar with other in-kernel GPU drivers code, I tried to patch them.
> It's too bad.
>
> Minchan Kim said he had a plan to apply this patch into zram compaction.
> Many embedded machines use several hundreds MB for zram.
> The zram can also have benefit with this patch as much as GPU drivers.
>
Hello Gioh,
It would be helpful for fork-latency and zra+CMA in small memory system.
I will implement zsmalloc.migratepages after I finish current going works.
Thanks for the nice work!
--
Kind regards,
Minchan Kim
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply
* Re: [PATCH V3 2/5] mm: mlock: Add new mlock, munlock, and munlockall system calls
From: Heiko Carstens @ 2015-07-08 6:46 UTC (permalink / raw)
To: Eric B Munson
Cc: Andrew Morton, Michal Hocko, Vlastimil Babka, linux-alpha,
linux-kernel, linux-arm-kernel, adi-buildroot-devel,
linux-cris-kernel, linux-ia64, linux-m68k, linux-mips,
linux-am33-list, linux-parisc, linuxppc-dev, linux-s390, linux-sh,
sparclinux, linux-xtensa, linux-api, linux-arch, linux-mm
In-Reply-To: <1436288623-13007-3-git-send-email-emunson@akamai.com>
On Tue, Jul 07, 2015 at 01:03:40PM -0400, Eric B Munson wrote:
> With the refactored mlock code, introduce new system calls for mlock,
> munlock, and munlockall. The new calls will allow the user to specify
> what lock states are being added or cleared. mlock2 and munlock2 are
> trivial at the moment, but a follow on patch will add a new mlock state
> making them useful.
>
> munlock2 addresses a limitation of the current implementation. If a
> user calls mlockall(MCL_CURRENT | MCL_FUTURE) and then later decides
> that MCL_FUTURE should be removed, they would have to call munlockall()
> followed by mlockall(MCL_CURRENT) which could potentially be very
> expensive. The new munlockall2 system call allows a user to simply
> clear the MCL_FUTURE flag.
>
> Signed-off-by: Eric B Munson <emunson@akamai.com>
...
> diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S
> index 1acad02..f6d81d6 100644
> --- a/arch/s390/kernel/syscalls.S
> +++ b/arch/s390/kernel/syscalls.S
> @@ -363,3 +363,6 @@ SYSCALL(sys_bpf,compat_sys_bpf)
> SYSCALL(sys_s390_pci_mmio_write,compat_sys_s390_pci_mmio_write)
> SYSCALL(sys_s390_pci_mmio_read,compat_sys_s390_pci_mmio_read)
> SYSCALL(sys_execveat,compat_sys_execveat)
> +SYSCALL(sys_mlock2,compat_sys_mlock2) /* 355 */
> +SYSCALL(sys_munlock2,compat_sys_munlock2)
> +SYSCALL(sys_munlockall2,compat_sys_munlockall2)
FWIW, you would also need to add matching lines to the two files
arch/s390/include/uapi/asm/unistd.h
arch/s390/kernel/compat_wrapper.c
so that the system call would be wired up on s390.
^ permalink raw reply
* Re: [PATCH V3 2/5] mm: mlock: Add new mlock, munlock, and munlockall system calls
From: Geert Uytterhoeven @ 2015-07-08 7:02 UTC (permalink / raw)
To: Heiko Carstens
Cc: Eric B Munson, Andrew Morton, Michal Hocko, Vlastimil Babka,
alpha, linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
adi-buildroot-devel@lists.sourceforge.net, Cris,
linux-ia64@vger.kernel.org, linux-m68k, Linux MIPS Mailing List,
moderated list:PANASONIC MN10300..., Parisc List,
linuxppc-dev@lists.ozlabs.org, linux-s390, Linux-sh list,
sparclinux
In-Reply-To: <20150708064607.GB7079@osiris>
On Wed, Jul 8, 2015 at 8:46 AM, Heiko Carstens
<heiko.carstens@de.ibm.com> wrote:
>> diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S
>> index 1acad02..f6d81d6 100644
>> --- a/arch/s390/kernel/syscalls.S
>> +++ b/arch/s390/kernel/syscalls.S
>> @@ -363,3 +363,6 @@ SYSCALL(sys_bpf,compat_sys_bpf)
>> SYSCALL(sys_s390_pci_mmio_write,compat_sys_s390_pci_mmio_write)
>> SYSCALL(sys_s390_pci_mmio_read,compat_sys_s390_pci_mmio_read)
>> SYSCALL(sys_execveat,compat_sys_execveat)
>> +SYSCALL(sys_mlock2,compat_sys_mlock2) /* 355 */
>> +SYSCALL(sys_munlock2,compat_sys_munlock2)
>> +SYSCALL(sys_munlockall2,compat_sys_munlockall2)
>
> FWIW, you would also need to add matching lines to the two files
>
> arch/s390/include/uapi/asm/unistd.h
> arch/s390/kernel/compat_wrapper.c
>
> so that the system call would be wired up on s390.
Similar comment for m68k:
arch/m68k/include/asm/unistd.h
arch/m68k/include/uapi/asm/unistd.h
I think you best look at the last commits that added system calls, for all
architectures, to make sure you don't do partial updates.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [RFC 0/8] Additional kmsg devices
From: Marcin Niesluchowski @ 2015-07-08 8:30 UTC (permalink / raw)
To: Richard Weinberger
Cc: linux-doc@vger.kernel.org, LKML, open list:ABI/API,
Jonathan Corbet, Greg Kroah-Hartman, Petr Mladek, Tejun Heo,
Kay Sievers, Andrew Morton, Joe Perches, Karol Lewandowski,
Bartlomiej Zolnierkiewicz
In-Reply-To: <5596A80D.5040109@nod.at>
On 07/03/2015 05:19 PM, Richard Weinberger wrote:
> Am 03.07.2015 um 17:09 schrieb Marcin Niesluchowski:
>>> Why can't you just make sure that your target has a working
>>> syslogd/rsyslogd/journald/whatever?
>>> All can be done perfectly fine in userspace.
>> * Message credibility: Lets imagine simple service which collects logs via unix sockets. There is no reliable way of identifying logging process. getsockopt() with SO_PEERCRED
>> option would give pid form cred structure, but according to manual it may not be of actual logging process:
>> "The returned credentials are those that were in effect at the time of the call to connect(2) or socketpair(2)."
>> - select(7)
> This interface can be improved. Should be easy.
What kind of improvement do you have in mind?
>> * Early userspace tool: Helpful especially for embeded systems.
> This is what we do already. In early user space spawn your logger as early as possible.
> "embedded Linux is special" is not an excuse btw. ;)
I would say "embedded Linux is real use case"instead of "special". What
I meant that it does only require one ioctl and no additional resources
are needed.
>> * Reliability: Userspace service may be killed due to out of memory (OOM). This is kernel cyclic buffer, which size can be specified differently according to situation.
> This is what we have /proc/<pid>/oom_adj and /proc/<pid>/oom_score_adj for.
You are right, but additional resources and complexity is required.
>> * Possibility of using it with pstore: This code could be extended to log additional buffers to persistent storage same way main (kmsg) log buffer is.
> pstorefs and friends?
pstore filesystem is used to access already stored kernel data (e.g.
kmsg buffer). But does not provide mechanism of storing userspace memory.
>> * Use case of attaching file descriptor to stdout/stderr: Especially in early userspace.
> You can redirect these also in userspace.
True for that, but as I said in my first argument there is no
possibility of logging process identification in case of sockets.
>> * Performance: Those services mentioned by You are weeker solutions in that case. Especially systemd-journald is much too heavy soulution.
> Do you have numbers? I agree systemd-journald is heavy wight. But it is by far not the only logging daemon we have...
I compared write operations on kmsg buffervia write/read operations on
socketon SOCK_STREAM socket and sendmsg/recv on SOCK_DGRAM socket.
Compared toSOCK_STREAM socket it was about 39% slowerbut compared
toSOCK_DGRAM socket it was about 326% faster.syslogfor example uses
SOCK_DGRAM sockets.In all cases there were 2^20 (1048576) write/sendmsg
operations of 2^8 (256) bytes.
Best Regards,
Marcin Niesluchowski
^ permalink raw reply
* [RFC 0/8] Introduce LSM to KDBUS
From: Paul Osmialowski @ 2015-07-08 10:25 UTC (permalink / raw)
To: Paul Moore, James Morris, Casey Schaufler, Serge E. Hallyn,
Kees Cook, Tetsuo Handa, Stephen Smalley, Neil Brown, Mark Rustad,
Greg Kroah-Hartman, Daniel Mack, David Herrmann, Djalal Harouni,
Shuah Khan, Al Viro, linux-security-module, linux-kernel,
linux-api
Cc: Karol Lewandowski, Paul Osmialowski, Lukasz Skalski
This patchset partially summarizes effects of collective work by
Karol Lewandowski and Paul Moore towards introduction of LSM into KDBUS.
These patches originate from following git repositories:
git://git.infradead.org/users/pcmoore/selinux (branch: working-kdbus)
https://github.com/lmctl/linux.git (branch: kdbus-lsm-v4.for-systemd-v212)
https://github.com/lmctl/kdbus.git (branch: kdbus-lsm-v4.for-systemd-v212)
Since kdbus made its way to linux-next tree, I was kindly asked by
Karol Lewandowski to fit his work into the current kdbus code existing
there.
As both kdbus and security related code changed a bit, so are my changes
quite substantial in places.
Note that SELinux kdbus access control patches are absent - only SMACK part
of original work is included.
I've also made some changes to kdbus test suite. In order to see LSM hooks
in action we need to be able to run tests from different executable
binaries holding different security labels.
Therefore I added ability to select execution of particular test by
executed binary name. This is essential for running newly added 'send' test
which should communicate with 'daemon' test running in another process.
Karol Lewandowski (1):
lsm: make security_file_receive available for external modules
Paul Osmialowski (7):
lsm: smack: Make ipc/kdbus includes visible so smack callbacks could
see them
lsm: kdbus security hooks
lsm: smack: smack callbacks for kdbus security hooks
kdbus: use LSM hooks in kdbus code
kdbus: TEST_CREATE_CONN now does no depend on TEST_CREATE_BUS
kdbus: selftests extended
kdbus: Ability to run kdbus test by executable binary name
include/linux/lsm_hooks.h | 67 +++++++++++++
include/linux/security.h | 99 +++++++++++++++++++
ipc/kdbus/bus.c | 12 ++-
ipc/kdbus/bus.h | 3 +
ipc/kdbus/connection.c | 54 +++++++++++
ipc/kdbus/connection.h | 4 +
ipc/kdbus/domain.c | 9 +-
ipc/kdbus/domain.h | 2 +
ipc/kdbus/endpoint.c | 11 +++
ipc/kdbus/names.c | 11 +++
ipc/kdbus/queue.c | 30 ++++--
security/security.c | 118 +++++++++++++++++++++++
security/smack/Makefile | 2 +
security/smack/smack_lsm.c | 68 +++++++++++++
tools/testing/selftests/kdbus/Makefile | 1 +
tools/testing/selftests/kdbus/kdbus-test.c | 37 ++++++-
tools/testing/selftests/kdbus/kdbus-test.h | 1 +
tools/testing/selftests/kdbus/kdbus-util.c | 37 ++++---
tools/testing/selftests/kdbus/kdbus-util.h | 2 +-
tools/testing/selftests/kdbus/test-activator.c | 20 ++--
tools/testing/selftests/kdbus/test-chat.c | 6 +-
tools/testing/selftests/kdbus/test-connection.c | 8 +-
tools/testing/selftests/kdbus/test-fd.c | 2 +-
tools/testing/selftests/kdbus/test-message.c | 69 ++++++++-----
tools/testing/selftests/kdbus/test-metadata-ns.c | 10 +-
tools/testing/selftests/kdbus/test-monitor.c | 9 +-
tools/testing/selftests/kdbus/test-policy-ns.c | 8 +-
tools/testing/selftests/kdbus/test-policy-priv.c | 48 +++++----
tools/testing/selftests/kdbus/test-send.c | 84 ++++++++++++++++
tools/testing/selftests/kdbus/test-sync.c | 2 +-
tools/testing/selftests/kdbus/test-timeout.c | 2 +-
31 files changed, 732 insertions(+), 104 deletions(-)
create mode 100644 tools/testing/selftests/kdbus/test-send.c
--
1.9.1
^ permalink raw reply
* [RFC 1/8] lsm: make security_file_receive available for external modules
From: Paul Osmialowski @ 2015-07-08 10:25 UTC (permalink / raw)
To: Paul Moore, James Morris, Casey Schaufler, Serge E. Hallyn,
Kees Cook, Tetsuo Handa, Stephen Smalley, Neil Brown, Mark Rustad,
Greg Kroah-Hartman, Daniel Mack, David Herrmann, Djalal Harouni,
Shuah Khan, Al Viro, linux-security-module, linux-kernel,
linux-api
Cc: Karol Lewandowski, Paul Osmialowski, Lukasz Skalski
In-Reply-To: <1436351110-5902-1-git-send-email-p.osmialowsk@samsung.com>
From: Karol Lewandowski <k.lewandowsk@samsung.com>
This is required for using filedesc related LSM hooks in kdbus code
if it is built as a module.
Signed-off-by: Karol Lewandowski <k.lewandowsk@samsung.com>
---
security/security.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/security/security.c b/security/security.c
index 595fffa..b1e935b 100644
--- a/security/security.c
+++ b/security/security.c
@@ -837,6 +837,7 @@ int security_file_receive(struct file *file)
{
return call_int_hook(file_receive, 0, file);
}
+EXPORT_SYMBOL(security_file_receive);
int security_file_open(struct file *file, const struct cred *cred)
{
--
1.9.1
^ permalink raw reply related
* [RFC 2/8] lsm: smack: Make ipc/kdbus includes visible so smack callbacks could see them
From: Paul Osmialowski @ 2015-07-08 10:25 UTC (permalink / raw)
To: Paul Moore, James Morris, Casey Schaufler, Serge E. Hallyn,
Kees Cook, Tetsuo Handa, Stephen Smalley, Neil Brown, Mark Rustad,
Greg Kroah-Hartman, Daniel Mack, David Herrmann, Djalal Harouni,
Shuah Khan, Al Viro, linux-security-module-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA
Cc: Karol Lewandowski, Paul Osmialowski, Lukasz Skalski
In-Reply-To: <1436351110-5902-1-git-send-email-p.osmialowsk-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Signed-off-by: Paul Osmialowski <p.osmialowsk-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
security/smack/Makefile | 2 ++
1 file changed, 2 insertions(+)
diff --git a/security/smack/Makefile b/security/smack/Makefile
index ee2ebd5..bd6927c 100644
--- a/security/smack/Makefile
+++ b/security/smack/Makefile
@@ -6,3 +6,5 @@ obj-$(CONFIG_SECURITY_SMACK) := smack.o
smack-y := smack_lsm.o smack_access.o smackfs.o
smack-$(CONFIG_SECURITY_SMACK_NETFILTER) += smack_netfilter.o
+
+ccflags-y += -Iipc
--
1.9.1
^ permalink raw reply related
* [RFC 3/8] lsm: kdbus security hooks
From: Paul Osmialowski @ 2015-07-08 10:25 UTC (permalink / raw)
To: Paul Moore, James Morris, Casey Schaufler, Serge E. Hallyn,
Kees Cook, Tetsuo Handa, Stephen Smalley, Neil Brown, Mark Rustad,
Greg Kroah-Hartman, Daniel Mack, David Herrmann, Djalal Harouni,
Shuah Khan, Al Viro, linux-security-module-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA
Cc: Karol Lewandowski, Paul Osmialowski, Lukasz Skalski
In-Reply-To: <1436351110-5902-1-git-send-email-p.osmialowsk-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
This is combination of the work by Karol Lewandowski and Paul Moore
on LSM hooks for kdbus.
Originates from:
git://git.infradead.org/users/pcmoore/selinux (branch: working-kdbus)
commit: 7050f206a79564886938d0edc4e1e9da5972c72d
https://github.com/lmctl/linux.git (branch: kdbus-lsm-v4.for-systemd-v212)
commit: a9fe4c33b6e5ab25a243e0590df406aabb6add12
Signed-off-by: Karol Lewandowski <k.lewandowsk-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Signed-off-by: Paul Moore <pmoore-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Paul Osmialowski <p.osmialowsk-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
include/linux/lsm_hooks.h | 67 ++++++++++++++++++++++++++
include/linux/security.h | 99 +++++++++++++++++++++++++++++++++++++++
security/security.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 283 insertions(+)
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 9429f05..2a8d8fc 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -1297,6 +1297,36 @@
* @inode we wish to get the security context of.
* @ctx is a pointer in which to place the allocated security context.
* @ctxlen points to the place to put the length of @ctx.
+ *
+ * @kdbus_domain_alloc:
+ * Allocate kdbus domain.
+ * @kdbus_domain_free:
+ * Deallocate kdbus domain.
+ * @kdbus_bus_alloc:
+ * Allocate kdbus bus.
+ * @kdbus_bus_free:
+ * Deallocate kdbus bus.
+ * @kdbus_send:
+ * Send message.
+ * @kdbus_recv:
+ * Receive message.
+ * @kdbus_name_acquire:
+ * Request a well-known bus name to associate with the connection.
+ * @kdbus_name_list:
+ * Retrieve the list of all currently registered well-known and unique
+ * names.
+ * @kdbus_ep_create:
+ * Endpoint create
+ * @kdbus_connect:
+ * Connect
+ * @kdbus_conn_free:
+ * Deallocate connection
+ * @kdbus_conn_info:
+ * Retrieve credentials and properties of the initial creator of the
+ * connection.
+ * @kdbus_talk:
+ * Talk to a given peer.
+ *
* This is the main security structure.
*/
@@ -1520,6 +1550,29 @@ union security_list_options {
int (*inode_setsecctx)(struct dentry *dentry, void *ctx, u32 ctxlen);
int (*inode_getsecctx)(struct inode *inode, void **ctx, u32 *ctxlen);
+ int (*kdbus_domain_alloc)(struct kdbus_domain *domain);
+ void (*kdbus_domain_free)(struct kdbus_domain *domain);
+
+ int (*kdbus_bus_alloc)(struct kdbus_bus *bus);
+ void (*kdbus_bus_free)(struct kdbus_bus *bus);
+ int (*kdbus_send)(const struct kdbus_conn *conn,
+ const struct kdbus_bus *bus);
+ int (*kdbus_recv)(const struct kdbus_conn *conn,
+ const struct kdbus_bus *bus);
+ int (*kdbus_name_acquire)(const struct kdbus_conn *conn,
+ const char *name);
+ int (*kdbus_name_list)(const struct kdbus_bus *bus);
+
+ int (*kdbus_ep_create)(const struct kdbus_bus *bus);
+ int (*kdbus_ep_setpolicy)(const struct kdbus_bus *bus);
+
+ int (*kdbus_connect)(struct kdbus_conn *conn,
+ const char *secctx, u32 seclen);
+ void (*kdbus_conn_free)(struct kdbus_conn *conn);
+ int (*kdbus_conn_info)(const struct kdbus_conn *conn);
+ int (*kdbus_talk)(const struct kdbus_conn *src,
+ const struct kdbus_conn *dst);
+
#ifdef CONFIG_SECURITY_NETWORK
int (*unix_stream_connect)(struct sock *sock, struct sock *other,
struct sock *newsk);
@@ -1760,6 +1813,20 @@ struct security_hook_heads {
struct list_head inode_notifysecctx;
struct list_head inode_setsecctx;
struct list_head inode_getsecctx;
+ struct list_head kdbus_domain_alloc;
+ struct list_head kdbus_domain_free;
+ struct list_head kdbus_bus_alloc;
+ struct list_head kdbus_bus_free;
+ struct list_head kdbus_send;
+ struct list_head kdbus_recv;
+ struct list_head kdbus_name_acquire;
+ struct list_head kdbus_name_list;
+ struct list_head kdbus_ep_create;
+ struct list_head kdbus_ep_setpolicy;
+ struct list_head kdbus_connect;
+ struct list_head kdbus_conn_free;
+ struct list_head kdbus_conn_info;
+ struct list_head kdbus_talk;
#ifdef CONFIG_SECURITY_NETWORK
struct list_head unix_stream_connect;
struct list_head unix_may_send;
diff --git a/include/linux/security.h b/include/linux/security.h
index 79d85dd..5f257b9 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -53,6 +53,10 @@ struct msg_queue;
struct xattr;
struct xfrm_sec_ctx;
struct mm_struct;
+struct kdbus_ep;
+struct kdbus_bus;
+struct kdbus_conn;
+struct kdbus_domain;
/* If capable should audit the security request */
#define SECURITY_CAP_NOAUDIT 0
@@ -356,6 +360,28 @@ void security_release_secctx(char *secdata, u32 seclen);
int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen);
int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen);
int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen);
+
+int security_kdbus_domain_alloc(struct kdbus_domain *domain);
+void security_kdbus_domain_free(struct kdbus_domain *domain);
+
+int security_kdbus_bus_alloc(struct kdbus_bus *bus);
+void security_kdbus_bus_free(struct kdbus_bus *bus);
+int security_kdbus_send(const struct kdbus_conn *conn,
+ const struct kdbus_bus *bus);
+int security_kdbus_recv(const struct kdbus_conn *conn,
+ const struct kdbus_bus *bus);
+int security_kdbus_name_acquire(const struct kdbus_conn *conn,
+ const char *name);
+int security_kdbus_name_list(const struct kdbus_bus *bus);
+int security_kdbus_ep_create(struct kdbus_bus *bus);
+int security_kdbus_ep_setpolicy(struct kdbus_bus *bus);
+int security_kdbus_connect(struct kdbus_conn *conn,
+ const char *secctx, u32 seclen);
+void security_kdbus_conn_free(struct kdbus_conn *conn);
+int security_kdbus_conn_info(const struct kdbus_conn *conn);
+int security_kdbus_talk(const struct kdbus_conn *src,
+ const struct kdbus_conn *dst);
+
#else /* CONFIG_SECURITY */
struct security_mnt_opts {
};
@@ -1105,6 +1131,79 @@ static inline int security_inode_getsecctx(struct inode *inode, void **ctx, u32
{
return -EOPNOTSUPP;
}
+
+static inline int security_kdbus_domain_alloc(struct kdbus_domain *domain)
+{
+ return 0;
+}
+
+static inline void security_kdbus_domain_free(struct kdbus_domain *domain)
+{
+}
+
+static inline int security_kdbus_bus_alloc(struct kdbus_bus *bus)
+{
+ return 0;
+}
+
+static inline void security_kdbus_bus_free(struct kdbus_bus *bus)
+{
+}
+
+static inline int security_kdbus_send(const struct kdbus_conn *conn,
+ const struct kdbus_bus *bus)
+{
+ return 0;
+}
+
+static inline int security_kdbus_recv(const struct kdbus_conn *conn,
+ const struct kdbus_bus *bus)
+{
+ return 0;
+}
+
+static inline int security_kdbus_name_acquire(const struct kdbus_conn *conn,
+ const char *name)
+{
+ return 0;
+}
+
+static inline int security_kdbus_name_list(const struct kdbus_bus *bus)
+{
+ return 0;
+}
+
+static inline int security_kdbus_ep_create(const struct kdbus_bus *bus)
+{
+ return 0;
+}
+
+static inline int security_kdbus_ep_setpolicy(const struct kdbus_bus *bus)
+{
+ return 0;
+}
+
+static inline int security_kdbus_connect(struct kdbus_conn *conn,
+ const char *secctx, u32 seclen)
+{
+ return 0;
+}
+
+static inline void security_kdbus_conn_free(struct kdbus_conn *conn)
+{
+}
+
+static inline int security_kdbus_conn_info(const struct kdbus_conn *conn)
+{
+ return 0;
+}
+
+static inline int security_kdbus_talk(const struct kdbus_conn *src,
+ const struct kdbus_conn *dst)
+{
+ return 0;
+}
+
#endif /* CONFIG_SECURITY */
#ifdef CONFIG_SECURITY_NETWORK
diff --git a/security/security.c b/security/security.c
index b1e935b..7fb46d1 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1185,6 +1185,95 @@ int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
}
EXPORT_SYMBOL(security_inode_getsecctx);
+int security_kdbus_domain_alloc(struct kdbus_domain *domain)
+{
+ return call_int_hook(kdbus_domain_alloc, 0, domain);
+}
+EXPORT_SYMBOL(security_kdbus_domain_alloc);
+
+void security_kdbus_domain_free(struct kdbus_domain *domain)
+{
+ call_void_hook(kdbus_domain_free, domain);
+}
+EXPORT_SYMBOL(security_kdbus_domain_free);
+
+int security_kdbus_bus_alloc(struct kdbus_bus *bus)
+{
+ return call_int_hook(kdbus_bus_alloc, 0, bus);
+}
+EXPORT_SYMBOL(security_kdbus_bus_alloc);
+
+void security_kdbus_bus_free(struct kdbus_bus *bus)
+{
+ call_void_hook(kdbus_bus_free, bus);
+}
+EXPORT_SYMBOL(security_kdbus_bus_free);
+
+int security_kdbus_send(const struct kdbus_conn *conn,
+ const struct kdbus_bus *bus)
+{
+ return call_int_hook(kdbus_send, 0, conn, bus);
+}
+EXPORT_SYMBOL(security_kdbus_send);
+
+int security_kdbus_recv(const struct kdbus_conn *conn,
+ const struct kdbus_bus *bus)
+{
+ return call_int_hook(kdbus_recv, 0, conn, bus);
+}
+EXPORT_SYMBOL(security_kdbus_recv);
+
+int security_kdbus_name_acquire(const struct kdbus_conn *conn,
+ const char *name)
+{
+ return call_int_hook(kdbus_name_acquire, 0, conn, name);
+}
+EXPORT_SYMBOL(security_kdbus_name_acquire);
+
+int security_kdbus_name_list(const struct kdbus_bus *bus)
+{
+ return call_int_hook(kdbus_name_list, 0, bus);
+}
+EXPORT_SYMBOL(security_kdbus_name_list);
+
+int security_kdbus_ep_create(struct kdbus_bus *bus)
+{
+ return call_int_hook(kdbus_ep_create, 0, bus);
+}
+EXPORT_SYMBOL(security_kdbus_ep_create);
+
+int security_kdbus_ep_setpolicy(struct kdbus_bus *bus)
+{
+ return call_int_hook(kdbus_ep_setpolicy, 0, bus);
+}
+EXPORT_SYMBOL(security_kdbus_ep_setpolicy);
+
+int security_kdbus_connect(struct kdbus_conn *conn,
+ const char *secctx, u32 seclen)
+{
+ return call_int_hook(kdbus_connect, 0, conn, secctx, seclen);
+}
+EXPORT_SYMBOL(security_kdbus_connect);
+
+void security_kdbus_conn_free(struct kdbus_conn *conn)
+{
+ call_void_hook(kdbus_conn_free, conn);
+}
+EXPORT_SYMBOL(security_kdbus_conn_free);
+
+int security_kdbus_conn_info(const struct kdbus_conn *conn)
+{
+ return call_int_hook(kdbus_conn_info, 0, conn);
+}
+EXPORT_SYMBOL(security_kdbus_conn_info);
+
+int security_kdbus_talk(const struct kdbus_conn *src,
+ const struct kdbus_conn *dst)
+{
+ return call_int_hook(kdbus_talk, 0, src, dst);
+}
+EXPORT_SYMBOL(security_kdbus_talk);
+
#ifdef CONFIG_SECURITY_NETWORK
int security_unix_stream_connect(struct sock *sock, struct sock *other, struct sock *newsk)
@@ -1774,6 +1863,34 @@ struct security_hook_heads security_hook_heads = {
LIST_HEAD_INIT(security_hook_heads.inode_setsecctx),
.inode_getsecctx =
LIST_HEAD_INIT(security_hook_heads.inode_getsecctx),
+ .kdbus_domain_alloc =
+ LIST_HEAD_INIT(security_hook_heads.kdbus_domain_alloc),
+ .kdbus_domain_free =
+ LIST_HEAD_INIT(security_hook_heads.kdbus_domain_free),
+ .kdbus_bus_alloc =
+ LIST_HEAD_INIT(security_hook_heads.kdbus_bus_alloc),
+ .kdbus_bus_free =
+ LIST_HEAD_INIT(security_hook_heads.kdbus_bus_free),
+ .kdbus_send =
+ LIST_HEAD_INIT(security_hook_heads.kdbus_send),
+ .kdbus_recv =
+ LIST_HEAD_INIT(security_hook_heads.kdbus_recv),
+ .kdbus_name_acquire =
+ LIST_HEAD_INIT(security_hook_heads.kdbus_name_acquire),
+ .kdbus_name_list =
+ LIST_HEAD_INIT(security_hook_heads.kdbus_name_list),
+ .kdbus_ep_create =
+ LIST_HEAD_INIT(security_hook_heads.kdbus_ep_create),
+ .kdbus_ep_setpolicy =
+ LIST_HEAD_INIT(security_hook_heads.kdbus_ep_setpolicy),
+ .kdbus_connect =
+ LIST_HEAD_INIT(security_hook_heads.kdbus_connect),
+ .kdbus_conn_free =
+ LIST_HEAD_INIT(security_hook_heads.kdbus_conn_free),
+ .kdbus_conn_info =
+ LIST_HEAD_INIT(security_hook_heads.kdbus_conn_info),
+ .kdbus_talk =
+ LIST_HEAD_INIT(security_hook_heads.kdbus_talk),
#ifdef CONFIG_SECURITY_NETWORK
.unix_stream_connect =
LIST_HEAD_INIT(security_hook_heads.unix_stream_connect),
--
1.9.1
^ permalink raw reply related
* [RFC 4/8] lsm: smack: smack callbacks for kdbus security hooks
From: Paul Osmialowski @ 2015-07-08 10:25 UTC (permalink / raw)
To: Paul Moore, James Morris, Casey Schaufler, Serge E. Hallyn,
Kees Cook, Tetsuo Handa, Stephen Smalley, Neil Brown, Mark Rustad,
Greg Kroah-Hartman, Daniel Mack, David Herrmann, Djalal Harouni,
Shuah Khan, Al Viro, linux-security-module-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA
Cc: Karol Lewandowski, Paul Osmialowski, Lukasz Skalski
In-Reply-To: <1436351110-5902-1-git-send-email-p.osmialowsk-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
This adds implementation of three smack callbacks sitting behind kdbus
security hooks as proposed by Karol Lewandowski.
Originates from:
git://git.infradead.org/users/pcmoore/selinux (branch: working-kdbus)
commit: fc3505d058c001fe72a6f66b833e0be5b2d118f3
https://github.com/lmctl/linux.git (branch: kdbus-lsm-v4.for-systemd-v212)
commit: 103c26fd27d1ec8c32d85dd3d85681f936ac66fb
Signed-off-by: Karol Lewandowski <k.lewandowsk-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Signed-off-by: Paul Osmialowski <p.osmialowsk-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
security/smack/smack_lsm.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 68 insertions(+)
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index a143328..033b756 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -41,6 +41,7 @@
#include <linux/msg.h>
#include <linux/shm.h>
#include <linux/binfmts.h>
+#include <kdbus/connection.h>
#include "smack.h"
#define TRANS_TRUE "TRUE"
@@ -3336,6 +3337,69 @@ static int smack_setprocattr(struct task_struct *p, char *name,
}
/**
+ * smack_kdbus_connect - Set the security blob for a KDBus connection
+ * @conn: the connection
+ * @secctx: smack label
+ * @seclen: smack label length
+ *
+ * Returns 0
+ */
+static int smack_kdbus_connect(struct kdbus_conn *conn,
+ const char *secctx, u32 seclen)
+{
+ struct smack_known *skp;
+
+ if (secctx && seclen > 0)
+ skp = smk_import_entry(secctx, seclen);
+ else
+ skp = smk_of_current();
+ conn->security = skp;
+
+ return 0;
+}
+
+/**
+ * smack_kdbus_conn_free - Clear the security blob for a KDBus connection
+ * @conn: the connection
+ *
+ * Clears the blob pointer
+ */
+static void smack_kdbus_conn_free(struct kdbus_conn *conn)
+{
+ conn->security = NULL;
+}
+
+/**
+ * smack_kdbus_talk - Smack access on KDBus
+ * @src: source kdbus connection
+ * @dst: destination kdbus connection
+ *
+ * Return 0 if a subject with the smack of sock could access
+ * an object with the smack of other, otherwise an error code
+ */
+static int smack_kdbus_talk(const struct kdbus_conn *src,
+ const struct kdbus_conn *dst)
+{
+ struct smk_audit_info ad;
+ struct smack_known *sskp = src->security;
+ struct smack_known *dskp = dst->security;
+ int ret;
+
+ BUG_ON(sskp == NULL);
+ BUG_ON(dskp == NULL);
+
+ if (smack_privileged(CAP_MAC_OVERRIDE))
+ return 0;
+
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NONE);
+
+ ret = smk_access(sskp, dskp, MAY_WRITE, &ad);
+ if (ret)
+ return ret;
+ return 0;
+}
+
+/**
* smack_unix_stream_connect - Smack access on UDS
* @sock: one sock
* @other: the other sock
@@ -4393,6 +4457,10 @@ struct security_hook_list smack_hooks[] = {
LSM_HOOK_INIT(inode_notifysecctx, smack_inode_notifysecctx),
LSM_HOOK_INIT(inode_setsecctx, smack_inode_setsecctx),
LSM_HOOK_INIT(inode_getsecctx, smack_inode_getsecctx),
+
+ LSM_HOOK_INIT(kdbus_connect, smack_kdbus_connect),
+ LSM_HOOK_INIT(kdbus_conn_free, smack_kdbus_conn_free),
+ LSM_HOOK_INIT(kdbus_talk, smack_kdbus_talk),
};
--
1.9.1
^ permalink raw reply related
* [RFC 5/8] kdbus: use LSM hooks in kdbus code
From: Paul Osmialowski @ 2015-07-08 10:25 UTC (permalink / raw)
To: Paul Moore, James Morris, Casey Schaufler, Serge E. Hallyn,
Kees Cook, Tetsuo Handa, Stephen Smalley, Neil Brown, Mark Rustad,
Greg Kroah-Hartman, Daniel Mack, David Herrmann, Djalal Harouni,
Shuah Khan, Al Viro, linux-security-module-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA
Cc: Karol Lewandowski, Paul Osmialowski, Lukasz Skalski
In-Reply-To: <1436351110-5902-1-git-send-email-p.osmialowsk-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Originates from:
https://github.com/lmctl/kdbus.git (branch: kdbus-lsm-v4.for-systemd-v212)
commit: aa0885489d19be92fa41c6f0a71df28763228a40
Signed-off-by: Karol Lewandowski <k.lewandowsk-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Signed-off-by: Paul Osmialowski <p.osmialowsk-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
ipc/kdbus/bus.c | 12 ++++++++++-
ipc/kdbus/bus.h | 3 +++
ipc/kdbus/connection.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++
ipc/kdbus/connection.h | 4 ++++
ipc/kdbus/domain.c | 9 ++++++++-
ipc/kdbus/domain.h | 2 ++
ipc/kdbus/endpoint.c | 11 ++++++++++
ipc/kdbus/names.c | 11 ++++++++++
ipc/kdbus/queue.c | 30 ++++++++++++++++++----------
9 files changed, 124 insertions(+), 12 deletions(-)
diff --git a/ipc/kdbus/bus.c b/ipc/kdbus/bus.c
index bbdf0f2..9894895 100644
--- a/ipc/kdbus/bus.c
+++ b/ipc/kdbus/bus.c
@@ -22,6 +22,7 @@
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/uio.h>
+#include <linux/security.h>
#include "bus.h"
#include "notify.h"
@@ -51,6 +52,7 @@ static void kdbus_bus_free(struct kdbus_node *node)
kdbus_domain_unref(bus->domain);
kdbus_policy_db_clear(&bus->policy_db);
kdbus_meta_proc_unref(bus->creator_meta);
+ security_kdbus_bus_free(bus);
kfree(bus);
}
@@ -161,6 +163,12 @@ static struct kdbus_bus *kdbus_bus_new(struct kdbus_domain *domain,
goto exit_unref;
}
+ ret = security_kdbus_bus_alloc(b);
+ if (ret) {
+ ret = -EPERM;
+ goto exit_unref;
+ }
+
/*
* Bus-limits of the creator are accounted on its real UID, just like
* all other per-user limits.
@@ -169,11 +177,13 @@ static struct kdbus_bus *kdbus_bus_new(struct kdbus_domain *domain,
if (IS_ERR(b->creator)) {
ret = PTR_ERR(b->creator);
b->creator = NULL;
- goto exit_unref;
+ goto exit_free_security;
}
return b;
+exit_free_security:
+ security_kdbus_bus_free(b);
exit_unref:
kdbus_node_deactivate(&b->node);
kdbus_node_unref(&b->node);
diff --git a/ipc/kdbus/bus.h b/ipc/kdbus/bus.h
index 5bea5ef..03e4a54 100644
--- a/ipc/kdbus/bus.h
+++ b/ipc/kdbus/bus.h
@@ -53,6 +53,7 @@ struct kdbus_user;
* @notify_list: List of pending kernel-generated messages
* @notify_lock: Notification list lock
* @notify_flush_lock: Notification flushing lock
+ * @security: LSM security blob
*/
struct kdbus_bus {
struct kdbus_node node;
@@ -81,6 +82,8 @@ struct kdbus_bus {
struct list_head notify_list;
spinlock_t notify_lock;
struct mutex notify_flush_lock;
+
+ void *security;
};
struct kdbus_bus *kdbus_bus_ref(struct kdbus_bus *bus);
diff --git a/ipc/kdbus/connection.c b/ipc/kdbus/connection.c
index 9993753..b85cdc7 100644
--- a/ipc/kdbus/connection.c
+++ b/ipc/kdbus/connection.c
@@ -31,6 +31,7 @@
#include <linux/slab.h>
#include <linux/syscalls.h>
#include <linux/uio.h>
+#include <linux/security.h>
#include "bus.h"
#include "connection.h"
@@ -73,6 +74,8 @@ static struct kdbus_conn *kdbus_conn_new(struct kdbus_ep *ep, bool privileged,
bool is_activator;
bool is_monitor;
struct kvec kvec;
+ u32 sid, len;
+ char *label;
int ret;
struct {
@@ -222,6 +225,14 @@ static struct kdbus_conn *kdbus_conn_new(struct kdbus_ep *ep, bool privileged,
}
}
+ security_task_getsecid(current, &sid);
+ security_secid_to_secctx(sid, &label, &len);
+ ret = security_kdbus_connect(conn, label, len);
+ if (ret) {
+ ret = -EPERM;
+ goto exit_unref;
+ }
+
if (atomic_inc_return(&conn->user->connections) > KDBUS_USER_MAX_CONN) {
/* decremented by destructor as conn->user is valid */
ret = -EMFILE;
@@ -276,6 +287,7 @@ static void __kdbus_conn_free(struct kref *kref)
kdbus_pool_free(conn->pool);
kdbus_ep_unref(conn->ep);
put_cred(conn->cred);
+ security_kdbus_conn_free(conn);
kfree(conn->description);
kfree(conn->quota);
kfree(conn);
@@ -1107,6 +1119,12 @@ static int kdbus_conn_reply(struct kdbus_conn *src, struct kdbus_kmsg *kmsg)
if (ret < 0)
goto exit;
+ ret = security_kdbus_talk(src, dst);
+ if (ret) {
+ ret = -EPERM;
+ goto exit;
+ }
+
mutex_lock(&dst->lock);
reply = kdbus_reply_find(src, dst, kmsg->msg.cookie_reply);
if (reply) {
@@ -1187,6 +1205,12 @@ static struct kdbus_reply *kdbus_conn_call(struct kdbus_conn *src,
if (ret < 0)
goto exit;
+ ret = security_kdbus_talk(src, dst);
+ if (ret) {
+ ret = -EPERM;
+ goto exit;
+ }
+
if (!kdbus_conn_policy_talk(src, current_cred(), dst)) {
ret = -EPERM;
goto exit;
@@ -1248,6 +1272,12 @@ static int kdbus_conn_unicast(struct kdbus_conn *src, struct kdbus_kmsg *kmsg)
if (ret < 0)
goto exit;
+ ret = security_kdbus_talk(src, dst);
+ if (ret) {
+ ret = -EPERM;
+ goto exit;
+ }
+
if (is_signal) {
/* like broadcasts we eavesdrop even if the msg is dropped */
kdbus_bus_eavesdrop(bus, src, kmsg);
@@ -1639,6 +1669,12 @@ struct kdbus_conn *kdbus_cmd_hello(struct kdbus_ep *ep, bool privileged,
if (ret < 0)
goto exit;
+ ret = security_kdbus_ep_setpolicy(c->ep->bus);
+ if (ret) {
+ ret = -EPERM;
+ goto exit;
+ }
+
ret = kdbus_policy_set(&c->ep->bus->policy_db, args.items,
args.items_size, 1,
kdbus_conn_is_policy_holder(c), c);
@@ -1732,6 +1768,10 @@ int kdbus_cmd_conn_info(struct kdbus_conn *conn, void __user *argp)
if (ret != 0)
return ret;
+ ret = security_kdbus_conn_info(conn);
+ if (ret)
+ return -EPERM;
+
/* registry must be held throughout lookup *and* collecting data */
down_read(&bus->name_registry->rwlock);
@@ -1905,6 +1945,12 @@ int kdbus_cmd_update(struct kdbus_conn *conn, void __user *argp)
/* now that we verified the input, update the connection */
if (item_policy) {
+ ret = security_kdbus_ep_setpolicy(conn->ep->bus);
+ if (ret) {
+ ret = -EPERM;
+ goto exit;
+ }
+
ret = kdbus_policy_set(&conn->ep->bus->policy_db, cmd->items,
KDBUS_ITEMS_SIZE(cmd, items),
1, true, conn);
@@ -1948,6 +1994,10 @@ int kdbus_cmd_send(struct kdbus_conn *conn, struct file *f, void __user *argp)
.argc = ARRAY_SIZE(argv),
};
+ ret = security_kdbus_send(conn, conn->ep->bus);
+ if (ret)
+ return -EPERM;
+
if (!kdbus_conn_is_ordinary(conn))
return -EOPNOTSUPP;
@@ -2044,6 +2094,10 @@ int kdbus_cmd_recv(struct kdbus_conn *conn, void __user *argp)
.argc = ARRAY_SIZE(argv),
};
+ ret = security_kdbus_recv(conn, conn->ep->bus);
+ if (ret)
+ return -EPERM;
+
if (!kdbus_conn_is_ordinary(conn) &&
!kdbus_conn_is_monitor(conn) &&
!kdbus_conn_is_activator(conn))
diff --git a/ipc/kdbus/connection.h b/ipc/kdbus/connection.h
index d1ffe90..1f91d39 100644
--- a/ipc/kdbus/connection.h
+++ b/ipc/kdbus/connection.h
@@ -19,6 +19,7 @@
#include <linux/kref.h>
#include <linux/lockdep.h>
#include <linux/path.h>
+#include <uapi/linux/kdbus.h>
#include "limits.h"
#include "metadata.h"
@@ -73,6 +74,7 @@ struct kdbus_kmsg;
* @names_queue_list: Well-known names this connection waits for
* @privileged: Whether this connection is privileged on the bus
* @faked_meta: Whether the metadata was faked on HELLO
+ * @security: LSM security blob
*/
struct kdbus_conn {
struct kref kref;
@@ -113,6 +115,8 @@ struct kdbus_conn {
bool privileged:1;
bool faked_meta:1;
+
+ void *security;
};
struct kdbus_conn *kdbus_conn_ref(struct kdbus_conn *conn);
diff --git a/ipc/kdbus/domain.c b/ipc/kdbus/domain.c
index ac9f760..da9cdab 100644
--- a/ipc/kdbus/domain.c
+++ b/ipc/kdbus/domain.c
@@ -20,6 +20,7 @@
#include <linux/sizes.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
+#include <linux/security.h>
#include "bus.h"
#include "domain.h"
@@ -73,6 +74,7 @@ static void kdbus_domain_free(struct kdbus_node *node)
put_user_ns(domain->user_namespace);
ida_destroy(&domain->user_ida);
idr_destroy(&domain->user_idr);
+ security_kdbus_domain_free(domain);
kfree(domain);
}
@@ -104,6 +106,10 @@ struct kdbus_domain *kdbus_domain_new(unsigned int access)
idr_init(&d->user_idr);
ida_init(&d->user_ida);
+ ret = security_kdbus_domain_alloc(d);
+ if (ret)
+ return ERR_PTR(-EPERM);
+
/* Pin user namespace so we can guarantee domain-unique bus * names. */
d->user_namespace = get_user_ns(current_user_ns());
@@ -116,6 +122,7 @@ struct kdbus_domain *kdbus_domain_new(unsigned int access)
exit_unref:
kdbus_node_deactivate(&d->node);
kdbus_node_unref(&d->node);
+ security_kdbus_domain_free(d);
return ERR_PTR(ret);
}
@@ -264,7 +271,7 @@ static void __kdbus_user_free(struct kref *kref)
if (uid_valid(user->uid))
idr_remove(&user->domain->user_idr, __kuid_val(user->uid));
mutex_unlock(&user->domain->lock);
-
+ security_kdbus_domain_free(user->domain);
kdbus_domain_unref(user->domain);
kfree(user);
}
diff --git a/ipc/kdbus/domain.h b/ipc/kdbus/domain.h
index 447a2bd..3db06d8 100644
--- a/ipc/kdbus/domain.h
+++ b/ipc/kdbus/domain.h
@@ -31,6 +31,7 @@
* @user_ida: Set of all users to compute small indices
* @user_namespace: User namespace, pinned at creation time
* @dentry: Root dentry of VFS mount (don't use outside of kdbusfs)
+ * @security: LSM security blob
*/
struct kdbus_domain {
struct kdbus_node node;
@@ -40,6 +41,7 @@ struct kdbus_domain {
struct ida user_ida;
struct user_namespace *user_namespace;
struct dentry *dentry;
+ void *security;
};
/**
diff --git a/ipc/kdbus/endpoint.c b/ipc/kdbus/endpoint.c
index 9a95a5e..380228f 100644
--- a/ipc/kdbus/endpoint.c
+++ b/ipc/kdbus/endpoint.c
@@ -21,6 +21,7 @@
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/uio.h>
+#include <linux/security.h>
#include "bus.h"
#include "connection.h"
@@ -122,6 +123,12 @@ struct kdbus_ep *kdbus_ep_new(struct kdbus_bus *bus, const char *name,
kdbus_policy_db_init(&e->policy_db);
e->bus = kdbus_bus_ref(bus);
+ ret = security_kdbus_ep_create(bus);
+ if (ret) {
+ ret = -EPERM;
+ goto exit_unref;
+ }
+
ret = kdbus_node_link(&e->node, &bus->node, name);
if (ret < 0)
goto exit_unref;
@@ -265,6 +272,10 @@ int kdbus_cmd_ep_update(struct kdbus_ep *ep, void __user *argp)
.argc = ARRAY_SIZE(argv),
};
+ ret = security_kdbus_ep_setpolicy(ep->bus);
+ if (ret)
+ return -EPERM;
+
ret = kdbus_args_parse(&args, argp, &cmd);
if (ret != 0)
return ret;
diff --git a/ipc/kdbus/names.c b/ipc/kdbus/names.c
index d77ee08..dd20bea 100644
--- a/ipc/kdbus/names.c
+++ b/ipc/kdbus/names.c
@@ -24,6 +24,7 @@
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/uio.h>
+#include <linux/security.h>
#include "bus.h"
#include "connection.h"
@@ -503,6 +504,12 @@ int kdbus_cmd_name_acquire(struct kdbus_conn *conn, void __user *argp)
goto exit;
}
+ ret = security_kdbus_name_acquire(conn, item_name);
+ if (ret) {
+ ret = -EPERM;
+ goto exit;
+ }
+
/*
* Do atomic_inc_return here to reserve our slot, then decrement
* it before returning.
@@ -724,6 +731,10 @@ int kdbus_cmd_list(struct kdbus_conn *conn, void __user *argp)
if (ret != 0)
return ret;
+ ret = security_kdbus_name_list(conn->ep->bus);
+ if (ret)
+ return -EPERM;
+
/* lock order: domain -> bus -> ep -> names -> conn */
down_read(®->rwlock);
down_read(&conn->ep->bus->conn_rwlock);
diff --git a/ipc/kdbus/queue.c b/ipc/kdbus/queue.c
index 25bb3ad..9872fb4 100644
--- a/ipc/kdbus/queue.c
+++ b/ipc/kdbus/queue.c
@@ -28,6 +28,7 @@
#include <linux/slab.h>
#include <linux/syscalls.h>
#include <linux/uio.h>
+#include <linux/security.h>
#include "util.h"
#include "domain.h"
@@ -514,12 +515,17 @@ int kdbus_queue_entry_install(struct kdbus_queue_entry *entry,
for (i = 0; i < res->fds_count; i++) {
if (install_fds) {
- fds[i] = get_unused_fd_flags(O_CLOEXEC);
- if (fds[i] >= 0)
- fd_install(fds[i],
- get_file(res->fds[i]));
- else
+ if (security_file_receive(res->fds[i])) {
+ fds[i] = -1;
incomplete_fds = true;
+ } else {
+ fds[i] = get_unused_fd_flags(O_CLOEXEC);
+ if (fds[i] >= 0)
+ fd_install(fds[i],
+ get_file(res->fds[i]));
+ else
+ incomplete_fds = true;
+ }
} else {
fds[i] = -1;
}
@@ -557,13 +563,17 @@ int kdbus_queue_entry_install(struct kdbus_queue_entry *entry,
m.fd = -1;
if (install_fds) {
- m.fd = get_unused_fd_flags(O_CLOEXEC);
- if (m.fd < 0) {
- m.fd = -1;
+ if (security_file_receive(d->memfd.file)) {
incomplete_fds = true;
} else {
- fd_install(m.fd,
- get_file(d->memfd.file));
+ m.fd = get_unused_fd_flags(O_CLOEXEC);
+ if (m.fd < 0) {
+ m.fd = -1;
+ incomplete_fds = true;
+ } else {
+ fd_install(m.fd,
+ get_file(d->memfd.file));
+ }
}
}
--
1.9.1
^ permalink raw reply related
* [RFC 6/8] kdbus: TEST_CREATE_CONN now does no depend on TEST_CREATE_BUS
From: Paul Osmialowski @ 2015-07-08 10:25 UTC (permalink / raw)
To: Paul Moore, James Morris, Casey Schaufler, Serge E. Hallyn,
Kees Cook, Tetsuo Handa, Stephen Smalley, Neil Brown, Mark Rustad,
Greg Kroah-Hartman, Daniel Mack, David Herrmann, Djalal Harouni,
Shuah Khan, Al Viro, linux-security-module, linux-kernel,
linux-api
Cc: Karol Lewandowski, Paul Osmialowski, Lukasz Skalski
In-Reply-To: <1436351110-5902-1-git-send-email-p.osmialowsk@samsung.com>
Without this patch, it is impossible to specify test case able to
connect to a bus already created (e.g. by 'test-daemon' test case), you can
only specify:
1) TEST_CREATE_BUS which creates new bus, or
2) TEST_CREATE_CONN OR'ed with TEST_CREATE_BUS which creates new bus and
creates connection to it.
This patch adds the missing ability to specify TEST_CREATE_CONN alone.
It will be used by a new test case (will be added by separate commit) which
is supposed to connect to already started test-daemon case.
Signed-off-by: Paul Osmialowski <p.osmialowsk@samsung.com>
---
tools/testing/selftests/kdbus/kdbus-test.c | 21 +++++++++++++++++++++
tools/testing/selftests/kdbus/kdbus-util.c | 18 +++++++++++-------
2 files changed, 32 insertions(+), 7 deletions(-)
diff --git a/tools/testing/selftests/kdbus/kdbus-test.c b/tools/testing/selftests/kdbus/kdbus-test.c
index 294e82a..d3a656f 100644
--- a/tools/testing/selftests/kdbus/kdbus-test.c
+++ b/tools/testing/selftests/kdbus/kdbus-test.c
@@ -309,6 +309,27 @@ static int test_prepare_env(const struct kdbus_test *t,
}
if (t->flags & TEST_CREATE_CONN) {
+ if (!env->buspath) {
+ char *s = NULL;
+ char *n = NULL;
+ int ret;
+
+ if (!args->busname) {
+ n = unique_name("test-bus");
+ ASSERT_RETURN(n);
+ }
+
+ ret = kdbus_create_bus(-1,
+ args->busname ?: n,
+ 0,
+ 0, &s);
+ free(n);
+ ASSERT_RETURN(ret == 0);
+
+ asprintf(&env->buspath, "%s/%s/bus", args->root, s);
+ free(s);
+ }
+ ASSERT_RETURN(env->buspath);
env->conn = kdbus_hello(env->buspath, 0, NULL, 0);
ASSERT_RETURN(env->conn);
}
diff --git a/tools/testing/selftests/kdbus/kdbus-util.c b/tools/testing/selftests/kdbus/kdbus-util.c
index 29a0cb1..26104ca 100644
--- a/tools/testing/selftests/kdbus/kdbus-util.c
+++ b/tools/testing/selftests/kdbus/kdbus-util.c
@@ -141,7 +141,7 @@ int kdbus_create_bus(int control_fd, const char *name,
char str[64];
} name;
} bus_make;
- int ret;
+ int ret = 0;
memset(&bus_make, 0, sizeof(bus_make));
bus_make.bp.size = sizeof(bus_make.bp);
@@ -171,13 +171,17 @@ int kdbus_create_bus(int control_fd, const char *name,
bus_make.attach[1].size +
bus_make.name.size;
- kdbus_printf("Creating bus with name >%s< on control fd %d ...\n",
- name, control_fd);
+ if (control_fd != -1) {
+ kdbus_printf(
+ "Creating bus with name >%s< on control fd %d ...\n",
+ name, control_fd);
- ret = kdbus_cmd_bus_make(control_fd, &bus_make.cmd);
- if (ret < 0) {
- kdbus_printf("--- error when making bus: %d (%m)\n", ret);
- return ret;
+ ret = kdbus_cmd_bus_make(control_fd, &bus_make.cmd);
+ if (ret < 0) {
+ kdbus_printf("--- error when making bus: %d (%m)\n",
+ ret);
+ return ret;
+ }
}
if (ret == 0 && path)
--
1.9.1
^ permalink raw reply related
* [RFC 7/8] kdbus: selftests extended
From: Paul Osmialowski @ 2015-07-08 10:25 UTC (permalink / raw)
To: Paul Moore, James Morris, Casey Schaufler, Serge E. Hallyn,
Kees Cook, Tetsuo Handa, Stephen Smalley, Neil Brown, Mark Rustad,
Greg Kroah-Hartman, Daniel Mack, David Herrmann, Djalal Harouni,
Shuah Khan, Al Viro, linux-security-module, linux-kernel,
linux-api
Cc: Karol Lewandowski, Paul Osmialowski, Lukasz Skalski
In-Reply-To: <1436351110-5902-1-git-send-email-p.osmialowsk@samsung.com>
The 'test-send' test case should connect to an already running test-daemon
which creates a bus with known name.
The main goal of this test case is to verify that messages as well as
file descriptors (opened with different open modes) can be transferred
properly.
In order to achieve its goals, this test case opens three files
(/tmp/kdbus-test-send.rd, /tmp/kdbus-test-send.wr,
/tmp/kdbus-test-send.rdwr) with three different open modes (O_RDONLY,
O_WRONLY, O_RDWR). If any of these files exists it is used 'as is',
otherwise it is created with some default content. Then this test tries
to send simple message followed by three messages each one of them
containing an array of opened file descriptors (single element array in the
first message, two element array in the second, three element array in the
third).
The ability to send array of file descriptors required changes in almost
all of the test case files.
Signed-off-by: Karol Lewandowski <k.lewandowsk@samsung.com>
Signed-off-by: Paul Osmialowski <p.osmialowsk@samsung.com>
---
tools/testing/selftests/kdbus/Makefile | 1 +
tools/testing/selftests/kdbus/kdbus-test.c | 11 +++-
tools/testing/selftests/kdbus/kdbus-test.h | 1 +
tools/testing/selftests/kdbus/kdbus-util.c | 19 ++++--
tools/testing/selftests/kdbus/kdbus-util.h | 2 +-
tools/testing/selftests/kdbus/test-activator.c | 20 +++---
tools/testing/selftests/kdbus/test-chat.c | 6 +-
tools/testing/selftests/kdbus/test-connection.c | 8 ++-
tools/testing/selftests/kdbus/test-fd.c | 2 +-
tools/testing/selftests/kdbus/test-message.c | 69 +++++++++++--------
tools/testing/selftests/kdbus/test-metadata-ns.c | 10 +--
tools/testing/selftests/kdbus/test-monitor.c | 9 +--
tools/testing/selftests/kdbus/test-policy-ns.c | 8 +--
tools/testing/selftests/kdbus/test-policy-priv.c | 48 ++++++++------
tools/testing/selftests/kdbus/test-send.c | 84 ++++++++++++++++++++++++
tools/testing/selftests/kdbus/test-sync.c | 2 +-
tools/testing/selftests/kdbus/test-timeout.c | 2 +-
17 files changed, 217 insertions(+), 85 deletions(-)
create mode 100644 tools/testing/selftests/kdbus/test-send.c
diff --git a/tools/testing/selftests/kdbus/Makefile b/tools/testing/selftests/kdbus/Makefile
index 8f36cb5..f400756 100644
--- a/tools/testing/selftests/kdbus/Makefile
+++ b/tools/testing/selftests/kdbus/Makefile
@@ -27,6 +27,7 @@ OBJS= \
test-policy.o \
test-policy-ns.o \
test-policy-priv.o \
+ test-send.o \
test-sync.o \
test-timeout.o
diff --git a/tools/testing/selftests/kdbus/kdbus-test.c b/tools/testing/selftests/kdbus/kdbus-test.c
index d3a656f..5a296da 100644
--- a/tools/testing/selftests/kdbus/kdbus-test.c
+++ b/tools/testing/selftests/kdbus/kdbus-test.c
@@ -25,6 +25,7 @@
enum {
TEST_CREATE_BUS = 1 << 0,
TEST_CREATE_CONN = 1 << 1,
+ TEST_CREATE_CAN_FAIL = 1 << 2,
};
struct kdbus_test {
@@ -148,6 +149,12 @@ static const struct kdbus_test tests[] = {
.flags = TEST_CREATE_BUS,
},
{
+ .name = "send",
+ .desc = "send",
+ .func = kdbus_test_send,
+ .flags = TEST_CREATE_CONN | TEST_CREATE_CAN_FAIL,
+ },
+ {
.name = "sync-byebye",
.desc = "synchronous replies vs. BYEBYE",
.func = kdbus_test_sync_byebye,
@@ -302,7 +309,7 @@ static int test_prepare_env(const struct kdbus_test *t,
_KDBUS_ATTACH_ALL,
_KDBUS_ATTACH_ALL, &s);
free(n);
- ASSERT_RETURN(ret == 0);
+ ASSERT_RETURN((ret == 0) || (t->flags & TEST_CREATE_CAN_FAIL));
asprintf(&env->buspath, "%s/%s/bus", args->root, s);
free(s);
@@ -331,7 +338,7 @@ static int test_prepare_env(const struct kdbus_test *t,
}
ASSERT_RETURN(env->buspath);
env->conn = kdbus_hello(env->buspath, 0, NULL, 0);
- ASSERT_RETURN(env->conn);
+ ASSERT_RETURN(env->conn || (t->flags & TEST_CREATE_CAN_FAIL));
}
env->root = args->root;
diff --git a/tools/testing/selftests/kdbus/kdbus-test.h b/tools/testing/selftests/kdbus/kdbus-test.h
index a5c6ae8..604c25c 100644
--- a/tools/testing/selftests/kdbus/kdbus-test.h
+++ b/tools/testing/selftests/kdbus/kdbus-test.h
@@ -75,6 +75,7 @@ int kdbus_test_name_queue(struct kdbus_test_env *env);
int kdbus_test_policy(struct kdbus_test_env *env);
int kdbus_test_policy_ns(struct kdbus_test_env *env);
int kdbus_test_policy_priv(struct kdbus_test_env *env);
+int kdbus_test_send(struct kdbus_test_env *env);
int kdbus_test_sync_byebye(struct kdbus_test_env *env);
int kdbus_test_sync_reply(struct kdbus_test_env *env);
int kdbus_test_timeout(struct kdbus_test_env *env);
diff --git a/tools/testing/selftests/kdbus/kdbus-util.c b/tools/testing/selftests/kdbus/kdbus-util.c
index 26104ca..622ff5a 100644
--- a/tools/testing/selftests/kdbus/kdbus-util.c
+++ b/tools/testing/selftests/kdbus/kdbus-util.c
@@ -454,7 +454,9 @@ static int __kdbus_msg_send(const struct kdbus_conn *conn,
int64_t priority,
uint64_t dst_id,
uint64_t cmd_flags,
- int cancel_fd)
+ int cancel_fd,
+ int fds_count,
+ int fds[])
{
struct kdbus_cmd_send *cmd = NULL;
struct kdbus_msg *msg = NULL;
@@ -467,6 +469,7 @@ static int __kdbus_msg_send(const struct kdbus_conn *conn,
int ret;
size = sizeof(*msg) + 3 * KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
+ size += fds_count > 0 ? KDBUS_ITEM_SIZE(sizeof(int) * fds_count) : 0;
if (dst_id == KDBUS_DST_ID_BROADCAST)
size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_bloom_filter)) + 64;
@@ -564,6 +567,13 @@ static int __kdbus_msg_send(const struct kdbus_conn *conn,
}
item = KDBUS_ITEM_NEXT(item);
+ if (fds_count > 0) {
+ item->type = KDBUS_ITEM_FDS;
+ item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(int) * fds_count;
+ memcpy(&item->fds, fds, sizeof(int) * fds_count);
+ item = KDBUS_ITEM_NEXT(item);
+ }
+
size = sizeof(*cmd);
if (cancel_fd != -1)
size += KDBUS_ITEM_SIZE(sizeof(cancel_fd));
@@ -620,10 +630,10 @@ out:
int kdbus_msg_send(const struct kdbus_conn *conn, const char *name,
uint64_t cookie, uint64_t flags, uint64_t timeout,
- int64_t priority, uint64_t dst_id)
+ int64_t priority, uint64_t dst_id, int fds_count, int fds[])
{
return __kdbus_msg_send(conn, name, cookie, flags, timeout, priority,
- dst_id, 0, -1);
+ dst_id, 0, -1, fds_count, fds);
}
int kdbus_msg_send_sync(const struct kdbus_conn *conn, const char *name,
@@ -631,7 +641,8 @@ int kdbus_msg_send_sync(const struct kdbus_conn *conn, const char *name,
int64_t priority, uint64_t dst_id, int cancel_fd)
{
return __kdbus_msg_send(conn, name, cookie, flags, timeout, priority,
- dst_id, KDBUS_SEND_SYNC_REPLY, cancel_fd);
+ dst_id, KDBUS_SEND_SYNC_REPLY, cancel_fd,
+ 0, NULL);
}
int kdbus_msg_send_reply(const struct kdbus_conn *conn,
diff --git a/tools/testing/selftests/kdbus/kdbus-util.h b/tools/testing/selftests/kdbus/kdbus-util.h
index d1a0f1b..7bb28e6 100644
--- a/tools/testing/selftests/kdbus/kdbus-util.h
+++ b/tools/testing/selftests/kdbus/kdbus-util.h
@@ -172,7 +172,7 @@ int kdbus_create_bus(int control_fd, const char *name,
char **path);
int kdbus_msg_send(const struct kdbus_conn *conn, const char *name,
uint64_t cookie, uint64_t flags, uint64_t timeout,
- int64_t priority, uint64_t dst_id);
+ int64_t priority, uint64_t dst_id, int fds_count, int fds[]);
int kdbus_msg_send_sync(const struct kdbus_conn *conn, const char *name,
uint64_t cookie, uint64_t flags, uint64_t timeout,
int64_t priority, uint64_t dst_id, int cancel_fd);
diff --git a/tools/testing/selftests/kdbus/test-activator.c b/tools/testing/selftests/kdbus/test-activator.c
index 3d1b763..c70fafe 100644
--- a/tools/testing/selftests/kdbus/test-activator.c
+++ b/tools/testing/selftests/kdbus/test-activator.c
@@ -84,13 +84,13 @@ static int kdbus_priv_activator(struct kdbus_test_env *env)
ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
/* Try to talk using the ID */
ret = kdbus_msg_send(unpriv, NULL, 0xdeadbeef, 0, 0,
- 0, activator->id);
+ 0, activator->id, 0, NULL);
ASSERT_EXIT(ret == -ENXIO);
/* Try to talk to the name */
ret = kdbus_msg_send(unpriv, "foo.priv.activator",
0xdeadbeef, 0, 0, 0,
- KDBUS_DST_ID_NAME);
+ KDBUS_DST_ID_NAME, 0, NULL);
ASSERT_EXIT(ret == -EPERM);
}));
ASSERT_RETURN(ret >= 0);
@@ -110,7 +110,7 @@ static int kdbus_priv_activator(struct kdbus_test_env *env)
cookie++;
ret = kdbus_msg_send(service, "foo.priv.activator", cookie,
- 0, 0, 0, KDBUS_DST_ID_NAME);
+ 0, 0, 0, KDBUS_DST_ID_NAME, 0, NULL);
ASSERT_RETURN(ret == 0);
ret = kdbus_starter_poll(activator);
@@ -141,7 +141,7 @@ static int kdbus_priv_activator(struct kdbus_test_env *env)
/* Try to talk to the name */
ret = kdbus_msg_send(unpriv, "foo.priv.activator",
cookie, 0, 0, 0,
- KDBUS_DST_ID_NAME);
+ KDBUS_DST_ID_NAME, 0, NULL);
ASSERT_EXIT(ret == -EPERM);
}));
ASSERT_RETURN(ret >= 0);
@@ -155,7 +155,7 @@ static int kdbus_priv_activator(struct kdbus_test_env *env)
cookie++;
ret = kdbus_msg_send(client, "foo.priv.activator", cookie,
- 0, 0, 0, KDBUS_DST_ID_NAME);
+ 0, 0, 0, KDBUS_DST_ID_NAME, 0, NULL);
ASSERT_RETURN(ret == 0);
ret = kdbus_msg_recv_poll(service, 100, &msg, NULL);
ASSERT_RETURN(ret == 0 && msg->cookie == cookie);
@@ -170,7 +170,8 @@ static int kdbus_priv_activator(struct kdbus_test_env *env)
/* Try to talk to the name */
ret = kdbus_msg_send(unpriv, "foo.priv.activator",
cookie, 0, 0, 0,
- KDBUS_DST_ID_NAME);
+ KDBUS_DST_ID_NAME,
+ 0, NULL);
ASSERT_EXIT(ret == -EPERM);
}));
ASSERT_RETURN(ret >= 0);
@@ -181,7 +182,7 @@ static int kdbus_priv_activator(struct kdbus_test_env *env)
/* Same user is able to TALK */
cookie++;
ret = kdbus_msg_send(client, "foo.priv.activator", cookie,
- 0, 0, 0, KDBUS_DST_ID_NAME);
+ 0, 0, 0, KDBUS_DST_ID_NAME, 0, NULL);
ASSERT_RETURN(ret == 0);
ret = kdbus_msg_recv_poll(service, 100, &msg, NULL);
ASSERT_RETURN(ret == 0 && msg->cookie == cookie);
@@ -207,7 +208,8 @@ static int kdbus_priv_activator(struct kdbus_test_env *env)
/* Try to talk to the name */
ret = kdbus_msg_send(unpriv, "foo.priv.activator",
cookie, 0, 0, 0,
- KDBUS_DST_ID_NAME);
+ KDBUS_DST_ID_NAME,
+ 0, NULL);
ASSERT_EXIT(ret == 0);
}));
ASSERT_RETURN(ret >= 0);
@@ -258,7 +260,7 @@ int kdbus_test_activator(struct kdbus_test_env *env)
ASSERT_RETURN(ret == 0);
ret = kdbus_msg_send(env->conn, "foo.test.activator", 0xdeafbeef,
- 0, 0, 0, KDBUS_DST_ID_NAME);
+ 0, 0, 0, KDBUS_DST_ID_NAME, 0, NULL);
ASSERT_RETURN(ret == 0);
fds[0].fd = activator->fd;
diff --git a/tools/testing/selftests/kdbus/test-chat.c b/tools/testing/selftests/kdbus/test-chat.c
index 71a92d8..e19f595 100644
--- a/tools/testing/selftests/kdbus/test-chat.c
+++ b/tools/testing/selftests/kdbus/test-chat.c
@@ -64,7 +64,7 @@ int kdbus_test_chat(struct kdbus_test_env *env)
cookie = 0;
ret = kdbus_msg_send(conn_b, NULL, 0xc0000000 | cookie, 0, 0, 0,
- KDBUS_DST_ID_BROADCAST);
+ KDBUS_DST_ID_BROADCAST, 0, NULL);
ASSERT_RETURN(ret == 0);
fds[0].fd = conn_a->fd;
@@ -91,7 +91,7 @@ int kdbus_test_chat(struct kdbus_test_env *env)
ASSERT_RETURN(ret == 0);
ret = kdbus_msg_send(conn_a, NULL,
0xc0000000 | cookie++,
- 0, 0, 0, conn_b->id);
+ 0, 0, 0, conn_b->id, 0, NULL);
ASSERT_RETURN(ret == 0);
}
@@ -100,7 +100,7 @@ int kdbus_test_chat(struct kdbus_test_env *env)
ASSERT_RETURN(ret == 0);
ret = kdbus_msg_send(conn_b, NULL,
0xc0000000 | cookie++,
- 0, 0, 0, conn_a->id);
+ 0, 0, 0, conn_a->id, 0, NULL);
ASSERT_RETURN(ret == 0);
}
diff --git a/tools/testing/selftests/kdbus/test-connection.c b/tools/testing/selftests/kdbus/test-connection.c
index e7c4866..779166f 100644
--- a/tools/testing/selftests/kdbus/test-connection.c
+++ b/tools/testing/selftests/kdbus/test-connection.c
@@ -127,7 +127,7 @@ int kdbus_test_byebye(struct kdbus_test_env *env)
/* send over 1st connection */
ret = kdbus_msg_send(env->conn, NULL, 0, 0, 0, 0,
- KDBUS_DST_ID_BROADCAST);
+ KDBUS_DST_ID_BROADCAST, 0, NULL);
ASSERT_RETURN(ret == 0);
/* say byebye on the 2nd, which must fail */
@@ -513,7 +513,8 @@ int kdbus_test_conn_update(struct kdbus_test_env *env)
conn = kdbus_hello(env->buspath, 0, NULL, 0);
ASSERT_RETURN(conn);
- ret = kdbus_msg_send(env->conn, NULL, 0x12345678, 0, 0, 0, conn->id);
+ ret = kdbus_msg_send(env->conn, NULL, 0x12345678, 0, 0, 0, conn->id,
+ 0, NULL);
ASSERT_RETURN(ret == 0);
ret = kdbus_msg_recv(conn, &msg, NULL);
@@ -536,7 +537,8 @@ int kdbus_test_conn_update(struct kdbus_test_env *env)
~KDBUS_ATTACH_TIMESTAMP);
ASSERT_RETURN(ret == 0);
- ret = kdbus_msg_send(env->conn, NULL, 0x12345678, 0, 0, 0, conn->id);
+ ret = kdbus_msg_send(env->conn, NULL, 0x12345678, 0, 0, 0, conn->id,
+ 0, NULL);
ASSERT_RETURN(ret == 0);
ret = kdbus_msg_recv(conn, &msg, NULL);
diff --git a/tools/testing/selftests/kdbus/test-fd.c b/tools/testing/selftests/kdbus/test-fd.c
index 2ae0f5a..bfd8980 100644
--- a/tools/testing/selftests/kdbus/test-fd.c
+++ b/tools/testing/selftests/kdbus/test-fd.c
@@ -466,7 +466,7 @@ static int kdbus_test_no_fds(struct kdbus_test_env *env,
*/
cookie++;
ret = kdbus_msg_send(conn_src, NULL, cookie, 0, 0, 0,
- conn_dst->id);
+ conn_dst->id, 0, NULL);
ASSERT_RETURN(ret == 0);
ret = waitpid(pid, &status, 0);
diff --git a/tools/testing/selftests/kdbus/test-message.c b/tools/testing/selftests/kdbus/test-message.c
index f1615da..d9b8fbd 100644
--- a/tools/testing/selftests/kdbus/test-message.c
+++ b/tools/testing/selftests/kdbus/test-message.c
@@ -51,7 +51,7 @@ int kdbus_test_message_basic(struct kdbus_test_env *env)
/* send over 1st connection */
ret = kdbus_msg_send(sender, NULL, cookie, 0, 0, 0,
- KDBUS_DST_ID_BROADCAST);
+ KDBUS_DST_ID_BROADCAST, 0, NULL);
ASSERT_RETURN(ret == 0);
/* Make sure that we do not get our own broadcasts */
@@ -67,7 +67,7 @@ int kdbus_test_message_basic(struct kdbus_test_env *env)
/* Msgs that expect a reply must have timeout and cookie */
ret = kdbus_msg_send(sender, NULL, 0, KDBUS_MSG_EXPECT_REPLY,
- 0, 0, conn->id);
+ 0, 0, conn->id, 0, NULL);
ASSERT_RETURN(ret == -EINVAL);
/* Faked replies with a valid reply cookie are rejected */
@@ -123,23 +123,36 @@ int kdbus_test_message_prio(struct kdbus_test_env *env)
{
struct kdbus_conn *a, *b;
uint64_t cookie = 0;
+ int ret;
a = kdbus_hello(env->buspath, 0, NULL, 0);
b = kdbus_hello(env->buspath, 0, NULL, 0);
ASSERT_RETURN(a && b);
- ASSERT_RETURN(kdbus_msg_send(b, NULL, ++cookie, 0, 0, 25, a->id) == 0);
- ASSERT_RETURN(kdbus_msg_send(b, NULL, ++cookie, 0, 0, -600, a->id) == 0);
- ASSERT_RETURN(kdbus_msg_send(b, NULL, ++cookie, 0, 0, 10, a->id) == 0);
- ASSERT_RETURN(kdbus_msg_send(b, NULL, ++cookie, 0, 0, -35, a->id) == 0);
- ASSERT_RETURN(kdbus_msg_send(b, NULL, ++cookie, 0, 0, -100, a->id) == 0);
- ASSERT_RETURN(kdbus_msg_send(b, NULL, ++cookie, 0, 0, 20, a->id) == 0);
- ASSERT_RETURN(kdbus_msg_send(b, NULL, ++cookie, 0, 0, -15, a->id) == 0);
- ASSERT_RETURN(kdbus_msg_send(b, NULL, ++cookie, 0, 0, -800, a->id) == 0);
- ASSERT_RETURN(kdbus_msg_send(b, NULL, ++cookie, 0, 0, -150, a->id) == 0);
- ASSERT_RETURN(kdbus_msg_send(b, NULL, ++cookie, 0, 0, 10, a->id) == 0);
- ASSERT_RETURN(kdbus_msg_send(b, NULL, ++cookie, 0, 0, -800, a->id) == 0);
- ASSERT_RETURN(kdbus_msg_send(b, NULL, ++cookie, 0, 0, -10, a->id) == 0);
+ ret = kdbus_msg_send(b, NULL, ++cookie, 0, 0, 25, a->id, 0, NULL);
+ ASSERT_RETURN(ret == 0);
+ ret = kdbus_msg_send(b, NULL, ++cookie, 0, 0, -600, a->id, 0, NULL);
+ ASSERT_RETURN(ret == 0);
+ ret = kdbus_msg_send(b, NULL, ++cookie, 0, 0, 10, a->id, 0, NULL);
+ ASSERT_RETURN(ret == 0);
+ ret = kdbus_msg_send(b, NULL, ++cookie, 0, 0, -35, a->id, 0, NULL);
+ ASSERT_RETURN(ret == 0);
+ ret = kdbus_msg_send(b, NULL, ++cookie, 0, 0, -100, a->id, 0, NULL);
+ ASSERT_RETURN(ret == 0);
+ ret = kdbus_msg_send(b, NULL, ++cookie, 0, 0, 20, a->id, 0, NULL);
+ ASSERT_RETURN(ret == 0);
+ ret = kdbus_msg_send(b, NULL, ++cookie, 0, 0, -15, a->id, 0, NULL);
+ ASSERT_RETURN(ret == 0);
+ ret = kdbus_msg_send(b, NULL, ++cookie, 0, 0, -800, a->id, 0, NULL);
+ ASSERT_RETURN(ret == 0);
+ ret = kdbus_msg_send(b, NULL, ++cookie, 0, 0, -150, a->id, 0, NULL);
+ ASSERT_RETURN(ret == 0);
+ ret = kdbus_msg_send(b, NULL, ++cookie, 0, 0, 10, a->id, 0, NULL);
+ ASSERT_RETURN(ret == 0);
+ ret = kdbus_msg_send(b, NULL, ++cookie, 0, 0, -800, a->id, 0, NULL);
+ ASSERT_RETURN(ret == 0);
+ ret = kdbus_msg_send(b, NULL, ++cookie, 0, 0, -10, a->id, 0, NULL);
+ ASSERT_RETURN(ret == 0);
ASSERT_RETURN(msg_recv_prio(a, -200, -800) == 0);
ASSERT_RETURN(msg_recv_prio(a, -100, -800) == 0);
@@ -195,7 +208,8 @@ static int kdbus_test_notify_kernel_quota(struct kdbus_test_env *env)
* Now the reader queue is full with kernel notfications,
* but as a user we still have room to push our messages.
*/
- ret = kdbus_msg_send(conn, NULL, 0xdeadbeef, 0, 0, 0, reader->id);
+ ret = kdbus_msg_send(conn, NULL, 0xdeadbeef, 0, 0, 0, reader->id,
+ 0, NULL);
ASSERT_RETURN(ret == 0);
/* More ID kernel notifications that will be lost */
@@ -315,7 +329,8 @@ static int kdbus_test_activator_quota(struct kdbus_test_env *env)
for (i = 0; i < KDBUS_CONN_MAX_MSGS; i++) {
ret = kdbus_msg_send(sender, "foo.test.activator",
cookie++, 0, 0, 0,
- KDBUS_DST_ID_NAME);
+ KDBUS_DST_ID_NAME,
+ 0, NULL);
if (ret < 0)
break;
activator_msgs_count++;
@@ -328,17 +343,18 @@ static int kdbus_test_activator_quota(struct kdbus_test_env *env)
/* Good, activator queue is full now */
/* ENXIO on direct send (activators can never be addressed by ID) */
- ret = kdbus_msg_send(conn, NULL, cookie++, 0, 0, 0, activator->id);
+ ret = kdbus_msg_send(conn, NULL, cookie++, 0, 0, 0, activator->id,
+ 0, NULL);
ASSERT_RETURN(ret == -ENXIO);
/* can't queue more */
ret = kdbus_msg_send(conn, "foo.test.activator", cookie++,
- 0, 0, 0, KDBUS_DST_ID_NAME);
+ 0, 0, 0, KDBUS_DST_ID_NAME, 0, NULL);
ASSERT_RETURN(ret == -ENOBUFS);
/* no match installed, so the broadcast will not inc dropped_msgs */
ret = kdbus_msg_send(sender, NULL, cookie++, 0, 0, 0,
- KDBUS_DST_ID_BROADCAST);
+ KDBUS_DST_ID_BROADCAST, 0, NULL);
ASSERT_RETURN(ret == 0);
/* Check activator queue */
@@ -357,7 +373,7 @@ static int kdbus_test_activator_quota(struct kdbus_test_env *env)
/* Consume the connection pool memory */
for (i = 0; i < KDBUS_CONN_MAX_MSGS; i++) {
ret = kdbus_msg_send(sender, NULL,
- cookie++, 0, 0, 0, conn->id);
+ cookie++, 0, 0, 0, conn->id, 0, NULL);
if (ret < 0)
break;
}
@@ -424,7 +440,7 @@ static int kdbus_test_activator_quota(struct kdbus_test_env *env)
/* This one is lost but it is not accounted */
ret = kdbus_msg_send(sender, NULL,
- cookie++, 0, 0, 0, conn->id);
+ cookie++, 0, 0, 0, conn->id, 0, NULL);
ASSERT_RETURN(ret == -ENOBUFS);
/* Acquire the name again */
@@ -477,7 +493,8 @@ static int kdbus_test_expected_reply_quota(struct kdbus_test_env *env)
ret = kdbus_msg_send(conn, NULL, cookie++,
KDBUS_MSG_EXPECT_REPLY,
100000000ULL, 0,
- connections[i]->id);
+ connections[i]->id,
+ 0, NULL);
if (ret < 0)
break;
@@ -497,7 +514,7 @@ static int kdbus_test_expected_reply_quota(struct kdbus_test_env *env)
* no further requests are allowed
*/
ret = kdbus_msg_send(conn, NULL, cookie++, KDBUS_MSG_EXPECT_REPLY,
- 1000000000ULL, 0, connections[8]->id);
+ 1000000000ULL, 0, connections[8]->id, 0, NULL);
ASSERT_RETURN(ret == -EMLINK);
for (i = 0; i < 9; i++)
@@ -575,7 +592,7 @@ int kdbus_test_pool_quota(struct kdbus_test_env *env)
ASSERT_RETURN(ret == -ENOBUFS);
/* We still can pass small messages */
- ret = kdbus_msg_send(b, NULL, cookie++, 0, 0, 0, c->id);
+ ret = kdbus_msg_send(b, NULL, cookie++, 0, 0, 0, c->id, 0, NULL);
ASSERT_RETURN(ret == 0);
for (i = size; i < (POOL_SIZE / 2 / 3); i += size) {
@@ -630,7 +647,7 @@ int kdbus_test_message_quota(struct kdbus_test_env *env)
ret = kdbus_fill_conn_queue(b, a->id, KDBUS_CONN_MAX_MSGS);
ASSERT_RETURN(ret == KDBUS_CONN_MAX_MSGS);
- ret = kdbus_msg_send(b, NULL, ++cookie, 0, 0, 0, a->id);
+ ret = kdbus_msg_send(b, NULL, ++cookie, 0, 0, 0, a->id, 0, NULL);
ASSERT_RETURN(ret == -ENOBUFS);
for (i = 0; i < KDBUS_CONN_MAX_MSGS; ++i) {
@@ -644,7 +661,7 @@ int kdbus_test_message_quota(struct kdbus_test_env *env)
ret = kdbus_fill_conn_queue(b, a->id, KDBUS_CONN_MAX_MSGS + 1);
ASSERT_RETURN(ret == KDBUS_CONN_MAX_MSGS);
- ret = kdbus_msg_send(b, NULL, ++cookie, 0, 0, 0, a->id);
+ ret = kdbus_msg_send(b, NULL, ++cookie, 0, 0, 0, a->id, 0, NULL);
ASSERT_RETURN(ret == -ENOBUFS);
kdbus_conn_free(a);
diff --git a/tools/testing/selftests/kdbus/test-metadata-ns.c b/tools/testing/selftests/kdbus/test-metadata-ns.c
index ccdfae0..4f264ac 100644
--- a/tools/testing/selftests/kdbus/test-metadata-ns.c
+++ b/tools/testing/selftests/kdbus/test-metadata-ns.c
@@ -115,7 +115,7 @@ static int __kdbus_clone_userns_test(const char *bus,
*/
ret = kdbus_msg_send(unpriv_conn, NULL, cookie, 0, 0,
- 0, conn->id);
+ 0, conn->id, 0, NULL);
ASSERT_EXIT(ret == 0);
/*
@@ -151,7 +151,7 @@ static int __kdbus_clone_userns_test(const char *bus,
cookie++;
ret = kdbus_msg_send(userns_conn, NULL, cookie,
- 0, 0, 0, conn->id);
+ 0, 0, 0, conn->id, 0, NULL);
ASSERT_EXIT(ret == 0);
/* Parent did send */
@@ -394,7 +394,7 @@ static int kdbus_clone_userns_test(const char *bus,
* Sending to unprivileged connections a unicast
*/
ret = kdbus_msg_send(conn, NULL, 0xdeadbeef, 0, 0,
- 0, unpriv_conn_id);
+ 0, unpriv_conn_id, 0, NULL);
ASSERT_RETURN(ret == 0);
/* signal to child that is in its userns */
@@ -406,14 +406,14 @@ static int kdbus_clone_userns_test(const char *bus,
* connections a unicast
*/
ret = kdbus_msg_send(conn, NULL, 0xdeadbeef, 0, 0,
- 0, userns_conn_id);
+ 0, userns_conn_id, 0, NULL);
ASSERT_RETURN(ret == 0);
/*
* Sending to unprivileged connections a broadcast
*/
ret = kdbus_msg_send(conn, NULL, 0xdeadbeef, 0, 0,
- 0, KDBUS_DST_ID_BROADCAST);
+ 0, KDBUS_DST_ID_BROADCAST, 0, NULL);
ASSERT_RETURN(ret == 0);
diff --git a/tools/testing/selftests/kdbus/test-monitor.c b/tools/testing/selftests/kdbus/test-monitor.c
index e00d738..ae87d87 100644
--- a/tools/testing/selftests/kdbus/test-monitor.c
+++ b/tools/testing/selftests/kdbus/test-monitor.c
@@ -56,7 +56,8 @@ int kdbus_test_monitor(struct kdbus_test_env *env)
ret = kdbus_name_acquire(monitor, "foo.bar.baz", NULL);
ASSERT_RETURN(ret == -EOPNOTSUPP);
- ret = kdbus_msg_send(env->conn, NULL, cookie, 0, 0, 0, conn->id);
+ ret = kdbus_msg_send(env->conn, NULL, cookie, 0, 0, 0, conn->id,
+ 0, NULL);
ASSERT_RETURN(ret == 0);
/* the recipient should have gotten the message */
@@ -80,7 +81,7 @@ int kdbus_test_monitor(struct kdbus_test_env *env)
cookie++;
ret = kdbus_msg_send(env->conn, NULL, cookie, 0, 0, 0,
- KDBUS_DST_ID_BROADCAST);
+ KDBUS_DST_ID_BROADCAST, 0, NULL);
ASSERT_RETURN(ret == 0);
/* The monitor should get the message. */
@@ -103,7 +104,7 @@ int kdbus_test_monitor(struct kdbus_test_env *env)
cookie++;
ret = kdbus_msg_send(env->conn, NULL, cookie, 0, 0, 0,
- KDBUS_DST_ID_BROADCAST);
+ KDBUS_DST_ID_BROADCAST, 0, NULL);
ASSERT_RETURN(ret == 0);
ret = kdbus_msg_recv_poll(monitor, 100, &msg, &offset);
@@ -128,7 +129,7 @@ int kdbus_test_monitor(struct kdbus_test_env *env)
cookie++;
ret = kdbus_msg_send(env->conn, NULL, cookie, 0, 0, 0,
- KDBUS_DST_ID_BROADCAST);
+ KDBUS_DST_ID_BROADCAST, 0, NULL);
ASSERT_RETURN(ret == 0);
ret = kdbus_msg_recv_poll(monitor, 100, &msg, &offset);
diff --git a/tools/testing/selftests/kdbus/test-policy-ns.c b/tools/testing/selftests/kdbus/test-policy-ns.c
index 3437012..2d70ee4 100644
--- a/tools/testing/selftests/kdbus/test-policy-ns.c
+++ b/tools/testing/selftests/kdbus/test-policy-ns.c
@@ -180,7 +180,7 @@ static int kdbus_recv_in_threads(const char *bus, const char *name,
break;
ret = kdbus_msg_send(conn_db[i], name, cookie++,
- 0, 0, 0, dst_id);
+ 0, 0, 0, dst_id, 0, NULL);
if (ret < 0) {
/*
* Receivers are not reading their messages,
@@ -295,7 +295,7 @@ static int kdbus_fork_test_by_id(const char *bus,
* EXIT_FAILURE.
*/
ret = kdbus_msg_send(conn_src, NULL, cookie,
- 0, 0, 0, conn_db[0]->id);
+ 0, 0, 0, conn_db[0]->id, 0, NULL);
ASSERT_EXIT(ret == child_status);
ret = kdbus_msg_recv_poll(conn_src, 100, NULL, NULL);
@@ -331,7 +331,7 @@ static int kdbus_fork_test_by_id(const char *bus,
}
ret = kdbus_msg_send(conn_db[0], NULL, ++cookie,
- 0, 0, 0, msg->src_id);
+ 0, 0, 0, msg->src_id, 0, NULL);
/*
* parent_status is checked against send operations,
* on failures always return TEST_ERR.
@@ -454,7 +454,7 @@ static int __kdbus_clone_userns_test(const char *bus,
ASSERT_EXIT(ret == 0);
ret = kdbus_msg_send(conn_src, name, 0xabcd1234,
- 0, 0, 0, KDBUS_DST_ID_NAME);
+ 0, 0, 0, KDBUS_DST_ID_NAME, 0, NULL);
kdbus_conn_free(conn_src);
_exit(ret == expected_status ? EXIT_SUCCESS : EXIT_FAILURE);
diff --git a/tools/testing/selftests/kdbus/test-policy-priv.c b/tools/testing/selftests/kdbus/test-policy-priv.c
index a318ccc..14a09c6 100644
--- a/tools/testing/selftests/kdbus/test-policy-priv.c
+++ b/tools/testing/selftests/kdbus/test-policy-priv.c
@@ -29,7 +29,7 @@ static int test_policy_priv_by_id(const char *bus,
ret = RUN_UNPRIVILEGED_CONN(unpriv, bus, ({
ret = kdbus_msg_send(unpriv, NULL,
expected_cookie, 0, 0, 0,
- conn_dst->id);
+ conn_dst->id, 0, NULL);
ASSERT_EXIT(ret == child_status);
}));
ASSERT_RETURN(ret >= 0);
@@ -92,7 +92,8 @@ static int test_policy_priv_by_broadcast(const char *bus,
/* Use expected_cookie since 'msg' might be NULL */
ret = kdbus_msg_send(child, NULL, expected_cookie + 1,
- 0, 0, 0, KDBUS_DST_ID_BROADCAST);
+ 0, 0, 0, KDBUS_DST_ID_BROADCAST,
+ 0, NULL);
ASSERT_EXIT(ret == 0);
kdbus_msg_free(msg);
@@ -107,7 +108,8 @@ static int test_policy_priv_by_broadcast(const char *bus,
ret = kdbus_msg_send(child_2, NULL,
expected_cookie, 0, 0, 0,
- KDBUS_DST_ID_BROADCAST);
+ KDBUS_DST_ID_BROADCAST,
+ 0, NULL);
ASSERT_RETURN(ret == 0);
/* Use a little bit high time */
@@ -142,7 +144,8 @@ static int test_policy_priv_by_broadcast(const char *bus,
ret = kdbus_msg_send(child_2, NULL,
expected_cookie, 0, 0, 0,
- KDBUS_DST_ID_BROADCAST);
+ KDBUS_DST_ID_BROADCAST,
+ 0, NULL);
ASSERT_EXIT(ret == 0);
/* Use a little bit high time */
@@ -218,7 +221,8 @@ static int test_priv_before_policy_upload(struct kdbus_test_env *env)
ret = kdbus_msg_send(unpriv, NULL, 0xdeadbeef,
KDBUS_MSG_EXPECT_REPLY,
5000000000ULL, 0,
- KDBUS_DST_ID_BROADCAST);
+ KDBUS_DST_ID_BROADCAST,
+ 0, NULL);
ASSERT_EXIT(ret == -ENOTUNIQ);
}));
ASSERT_RETURN(ret == 0);
@@ -405,7 +409,7 @@ static int test_broadcast_after_policy_upload(struct kdbus_test_env *env)
++expected_cookie;
ret = kdbus_msg_send(owner_a, NULL, expected_cookie, 0,
- 0, 0, KDBUS_DST_ID_BROADCAST);
+ 0, 0, KDBUS_DST_ID_BROADCAST, 0, NULL);
ASSERT_RETURN(ret == 0);
ret = kdbus_msg_recv_poll(owner_b, 100, &msg, NULL);
@@ -499,7 +503,8 @@ static int test_broadcast_after_policy_upload(struct kdbus_test_env *env)
ret = kdbus_msg_send(unpriv_owner, NULL,
expected_cookie,
0, 0, 0,
- KDBUS_DST_ID_BROADCAST);
+ KDBUS_DST_ID_BROADCAST,
+ 0, NULL);
ASSERT_EXIT(ret == 0);
/*
@@ -609,7 +614,7 @@ static int test_broadcast_after_policy_upload(struct kdbus_test_env *env)
NULL);
ASSERT_EXIT(ret >= 0);
ret = kdbus_msg_send(unpriv, NULL, expected_cookie,
- 0, 0, 0, KDBUS_DST_ID_BROADCAST);
+ 0, 0, 0, KDBUS_DST_ID_BROADCAST, 0, NULL);
ASSERT_EXIT(ret == 0);
}));
ASSERT_RETURN(ret == 0);
@@ -641,7 +646,7 @@ static int test_broadcast_after_policy_upload(struct kdbus_test_env *env)
NULL);
ASSERT_EXIT(ret >= 0);
ret = kdbus_msg_send(unpriv, NULL, expected_cookie,
- 0, 0, 0, KDBUS_DST_ID_BROADCAST);
+ 0, 0, 0, KDBUS_DST_ID_BROADCAST, 0, NULL);
ASSERT_EXIT(ret == 0);
}));
ASSERT_RETURN(ret == 0);
@@ -953,7 +958,8 @@ static int test_policy_priv(struct kdbus_test_env *env)
conn = kdbus_hello(env->buspath, 0, NULL, 0);
ASSERT_RETURN(conn);
- ret = kdbus_msg_send(conn, "com.example.b", 0xdeadbeef, 0, 0, 0, 0);
+ ret = kdbus_msg_send(conn, "com.example.b", 0xdeadbeef, 0, 0, 0, 0,
+ 0, NULL);
ASSERT_EXIT(ret >= 0);
ret = kdbus_msg_recv_poll(conn_b, 300, NULL, NULL);
@@ -967,7 +973,7 @@ static int test_policy_priv(struct kdbus_test_env *env)
ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
ret = kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0,
- 0, 0);
+ 0, 0, 0, NULL);
ASSERT_EXIT(ret == -EPERM);
}));
ASSERT_RETURN(ret >= 0);
@@ -996,7 +1002,7 @@ static int test_policy_priv(struct kdbus_test_env *env)
ASSERT_EXIT(ret >= 0);
ret = kdbus_msg_send(unpriv, "com.example.c", 0xdeadbeef, 0, 0,
- 0, 0);
+ 0, 0, 0, NULL);
ASSERT_EXIT(ret >= 0);
ret = kdbus_msg_recv_poll(owner, 100, NULL, NULL);
ASSERT_EXIT(ret >= 0);
@@ -1021,7 +1027,7 @@ static int test_policy_priv(struct kdbus_test_env *env)
ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
ret = kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0,
- 0, 0);
+ 0, 0, 0, NULL);
ASSERT_EXIT(ret >= 0);
}));
ASSERT_RETURN(ret >= 0);
@@ -1045,7 +1051,7 @@ static int test_policy_priv(struct kdbus_test_env *env)
ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
ret = kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0,
- 0, 0);
+ 0, 0, 0, NULL);
ASSERT_EXIT(ret >= 0);
}));
ASSERT_RETURN(ret >= 0);
@@ -1069,7 +1075,7 @@ static int test_policy_priv(struct kdbus_test_env *env)
ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
ret = kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0,
- 0, 0);
+ 0, 0, 0, NULL);
ASSERT_EXIT(ret >= 0);
}));
ASSERT_RETURN(ret >= 0);
@@ -1116,7 +1122,7 @@ static int test_policy_priv(struct kdbus_test_env *env)
ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
ret = kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0,
- 0, 0);
+ 0, 0, 0, NULL);
ASSERT_EXIT(ret == -EPERM);
}));
ASSERT_RETURN(ret >= 0);
@@ -1137,7 +1143,7 @@ static int test_policy_priv(struct kdbus_test_env *env)
ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
ret = kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0,
- 0, 0);
+ 0, 0, 0, NULL);
ASSERT_EXIT(ret >= 0);
}));
ASSERT_RETURN(ret >= 0);
@@ -1161,7 +1167,7 @@ static int test_policy_priv(struct kdbus_test_env *env)
ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
ret = kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0,
- 0, 0);
+ 0, 0, 0, NULL);
ASSERT_EXIT(ret >= 0);
ret = kdbus_msg_recv_poll(conn_b, 100, NULL, NULL);
@@ -1172,7 +1178,7 @@ static int test_policy_priv(struct kdbus_test_env *env)
ASSERT_RETURN(ret == 0);
ret = kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0,
- 0, 0);
+ 0, 0, 0, NULL);
ASSERT_EXIT(ret == -EPERM);
}));
ASSERT_RETURN(ret >= 0);
@@ -1213,7 +1219,7 @@ static int test_policy_priv(struct kdbus_test_env *env)
ASSERT_RETURN(unpriv);
ret = kdbus_msg_send(unpriv, "com.example.c", 0xdeadbeef, 0, 0,
- 0, 0);
+ 0, 0, 0, NULL);
ASSERT_EXIT(ret >= 0);
ret = kdbus_msg_recv_poll(owner, 100, NULL, NULL);
@@ -1223,7 +1229,7 @@ static int test_policy_priv(struct kdbus_test_env *env)
kdbus_conn_free(conn);
ret = kdbus_msg_send(unpriv, "com.example.c", 0xdeadbeef, 0, 0,
- 0, 0);
+ 0, 0, 0, NULL);
ASSERT_EXIT(ret == -EPERM);
kdbus_conn_free(unpriv);
diff --git a/tools/testing/selftests/kdbus/test-send.c b/tools/testing/selftests/kdbus/test-send.c
new file mode 100644
index 0000000..9bd8c8f
--- /dev/null
+++ b/tools/testing/selftests/kdbus/test-send.c
@@ -0,0 +1,84 @@
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <fcntl.h>
+#include <stdlib.h>
+/* Use in conjunction with test-kdbus-daemon */
+
+#include <unistd.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <errno.h>
+#include <assert.h>
+#include <poll.h>
+#include <sys/ioctl.h>
+
+#include "kdbus-test.h"
+#include "kdbus-util.h"
+#include "kdbus-enum.h"
+
+int get_file(const char *fname, int flags, const char *content)
+{
+ FILE *f;
+
+ if (access(fname, F_OK) < 0) {
+ f = fopen(fname, "w");
+ if (!f)
+ return -1;
+ fprintf(f, "%s\n", content);
+ fclose(f);
+ }
+
+ return open(fname, flags);
+}
+
+int kdbus_test_send(struct kdbus_test_env *env)
+{
+ int ret;
+ int serial = 1;
+ int fds[3];
+ size_t i;
+
+ if (!env->conn)
+ return EXIT_FAILURE;
+
+ fds[0] = get_file("/tmp/kdbus-test-send.rd", O_RDONLY, "foo");
+ fds[1] = get_file("/tmp/kdbus-test-send.wr", O_WRONLY, "bar");
+ fds[2] = get_file("/tmp/kdbus-test-send.rdwr", O_RDWR, "baz");
+
+ for (i = 0; i < ELEMENTSOF(fds); i++) {
+ if (fds[i] < 0) {
+ fprintf(stderr, "Unable to open data/fileN file(s)\n");
+ return EXIT_FAILURE;
+ }
+ }
+
+ ret = kdbus_msg_send(env->conn, "com.example.kdbus-test", serial++,
+ 0, 0, 0, 0, 0, NULL);
+ if (ret < 0)
+ fprintf(stderr, "error sending simple message: %d (%m)\n",
+ ret);
+
+ ret = kdbus_msg_send(env->conn, "com.example.kdbus-test", serial++,
+ 0, 0, 0, 0, 1, fds);
+ if (ret < 0)
+ fprintf(stderr, "error sending message with 1 fd: %d (%m)\n",
+ ret);
+
+ ret = kdbus_msg_send(env->conn, "com.example.kdbus-test", serial++,
+ 0, 0, 0, 0, 2, fds);
+ if (ret < 0)
+ fprintf(stderr, "error sending message with 2 fds: %d (%m)\n",
+ ret);
+
+ ret = kdbus_msg_send(env->conn, "com.example.kdbus-test", serial++,
+ 0, 0, 0, 0, 3, fds);
+ if (ret < 0)
+ fprintf(stderr, "error sending message with 3 fds: %d (%m)\n",
+ ret);
+
+ for (i = 0; i < ELEMENTSOF(fds); i++)
+ close(fds[i]);
+
+ return EXIT_SUCCESS;
+}
diff --git a/tools/testing/selftests/kdbus/test-sync.c b/tools/testing/selftests/kdbus/test-sync.c
index e2be910..77c3c41 100644
--- a/tools/testing/selftests/kdbus/test-sync.c
+++ b/tools/testing/selftests/kdbus/test-sync.c
@@ -113,7 +113,7 @@ static int close_epipe_sync(const char *bus)
}
ret = kdbus_msg_send(conn_dst, NULL, cookie, 0, 0, 0,
- KDBUS_DST_ID_BROADCAST);
+ KDBUS_DST_ID_BROADCAST, 0, NULL);
ASSERT_RETURN(ret == 0);
cookie++;
diff --git a/tools/testing/selftests/kdbus/test-timeout.c b/tools/testing/selftests/kdbus/test-timeout.c
index cfd1930..a5cdaf2 100644
--- a/tools/testing/selftests/kdbus/test-timeout.c
+++ b/tools/testing/selftests/kdbus/test-timeout.c
@@ -69,7 +69,7 @@ int kdbus_test_timeout(struct kdbus_test_env *env)
ASSERT_RETURN(kdbus_msg_send(conn_b, NULL, cookie,
KDBUS_MSG_EXPECT_REPLY,
(i + 1) * 100ULL * 1000000ULL, 0,
- conn_a->id) == 0);
+ conn_a->id, 0, NULL) == 0);
expected |= 1ULL << cookie;
}
--
1.9.1
^ permalink raw reply related
* [RFC 8/8] kdbus: Ability to run kdbus test by executable binary name
From: Paul Osmialowski @ 2015-07-08 10:25 UTC (permalink / raw)
To: Paul Moore, James Morris, Casey Schaufler, Serge E. Hallyn,
Kees Cook, Tetsuo Handa, Stephen Smalley, Neil Brown, Mark Rustad,
Greg Kroah-Hartman, Daniel Mack, David Herrmann, Djalal Harouni,
Shuah Khan, Al Viro, linux-security-module, linux-kernel,
linux-api
Cc: Karol Lewandowski, Paul Osmialowski, Lukasz Skalski
In-Reply-To: <1436351110-5902-1-git-send-email-p.osmialowsk@samsung.com>
With this applied, you can do following:
$ cp kdbus-test daemon
$ cp kdbus-test send
Then run 'daemon' in one shell session:
$ ./daemon --bus test
...and 'send' in another:
$ ./send --bus test
Useful for testing features introduced by previous patches.
Signed-off-by: Paul Osmialowski <p.osmialowsk@samsung.com>
---
tools/testing/selftests/kdbus/kdbus-test.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/tools/testing/selftests/kdbus/kdbus-test.c b/tools/testing/selftests/kdbus/kdbus-test.c
index 5a296da..9efbc5f 100644
--- a/tools/testing/selftests/kdbus/kdbus-test.c
+++ b/tools/testing/selftests/kdbus/kdbus-test.c
@@ -829,6 +829,7 @@ int main(int argc, char *argv[])
ARG_UIDMAP,
ARG_GIDMAP,
};
+ char *exec = basename(argv[0]);
kdbus_args = malloc(sizeof(*kdbus_args));
if (!kdbus_args) {
@@ -858,6 +859,10 @@ int main(int argc, char *argv[])
srand(time(NULL));
+ if (strcmp(exec, "kdbus-test") != 0) {
+ kdbus_args->test = exec;
+ }
+
while ((t = getopt_long(argc, argv, "hxfm:r:t:b:w:a", options, NULL)) >= 0) {
switch (t) {
case 'x':
--
1.9.1
^ permalink raw reply related
* Re: [RFC 0/8] Additional kmsg devices
From: Petr Mladek @ 2015-07-08 10:45 UTC (permalink / raw)
To: Karol Lewandowski
Cc: Marcin Niesluchowski, Richard Weinberger,
linux-doc@vger.kernel.org, LKML, open list:ABI/API,
Jonathan Corbet, Greg Kroah-Hartman, Tejun Heo, Kay Sievers,
Andrew Morton, Joe Perches, Bartlomiej Zolnierkiewicz,
Kyungmin Park
In-Reply-To: <559C0820.3060805@samsung.com>
On Tue 2015-07-07 19:10:56, Karol Lewandowski wrote:
> On 2015-07-07 15:11, Petr Mladek wrote:
> > On Fri 2015-07-03 17:09:03, Marcin Niesluchowski wrote:
> >> On 07/03/2015 01:21 PM, Richard Weinberger wrote:
> >>> On Fri, Jul 3, 2015 at 12:49 PM, Marcin Niesluchowski
> >>> <m.niesluchow@samsung.com> wrote:
> >>>> Dear All,
> >>>>
> >>>> This series of patches extends kmsg interface with ability to dynamicaly
> >>>> create (and destroy) kmsg-like devices which can be used by user space
> >>>> for logging. Logging to kernel has number of benefits, including but not
> >>>> limited to - always available, requiring no userspace, automatically
> >>>> rotating and low overhead.
> >>>>
> >>>> User-space logging to kernel cyclic buffers was already successfully used
> >>>> in android logger concept but it had certain flaws that this commits try
> >>>> to address:
> >>>> * drops hardcoded number of devices and static paths in favor for dynamic
> >>>> configuration by ioctl interface in userspace
> >>>> * extends existing driver instead of creating completely new one
> >>> So, now we start moving syslogd into kernel land because userspace is
> >>> too broken to provide
> >>> decent logging?
> >>>
> >>> I can understand the systemd is using kmsg if no other logging service
> >>> is available
> >>> but I really don't think we should encourage other programs to do so.
> >>>
> >>> Why can't you just make sure that your target has a working
> >>> syslogd/rsyslogd/journald/whatever?
> >>> All can be done perfectly fine in userspace.
> >> * Message credibility: Lets imagine simple service which collects
> >> logs via unix sockets. There is no reliable way of identifying
> >> logging process. getsockopt() with SO_PEERCRED option would give pid
> >> form cred structure, but according to manual it may not be of actual
> >> logging process:
> >> "The returned credentials are those that were in effect at the
> >> time of the call to connect(2) or socketpair(2)."
> >> - select(7)
> >>
> >> * Early userspace tool: Helpful especially for embeded systems.
> >>
> >> * Reliability: Userspace service may be killed due to out of memory
> >> (OOM). This is kernel cyclic buffer, which size can be specified
> >> differently according to situation.
> > But then many services will fight for the space in the kernel ring
> > buffer.
>
> Yes. Please note however that problems you describe are also valid for
> /dev/kmsg today.
Mea culpa, I should not write when I do not have enough time to read
the patches. I somehow missed the patch that added more buffers, so
many opinions were misleading.
> > It will be harder to handle continuous lines.
>
> I don't see how it would be different from what we have today.
There is currently only one buffer for continuous lines. It is flushed
when you write from another CPU even before the current message is completed.
It needs to be flushed also when you write from another devkmsg.
I thought that there would be much bigger chance to mix parts of
messages in a single buffer but it is not true after all.
Best Regards,
Petr
^ permalink raw reply
* Re: [RFC 3/8] lsm: kdbus security hooks
From: Lukasz Pawelczyk @ 2015-07-08 11:00 UTC (permalink / raw)
To: Paul Osmialowski, Paul Moore, James Morris, Casey Schaufler,
Serge E. Hallyn, Kees Cook, Tetsuo Handa, Stephen Smalley,
Neil Brown, Mark Rustad, Greg Kroah-Hartman, Daniel Mack,
David Herrmann, Djalal Harouni, Shuah Khan, Al Viro,
linux-security-module-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA
Cc: Karol Lewandowski, Lukasz Skalski
In-Reply-To: <1436351110-5902-4-git-send-email-p.osmialowsk-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
On śro, 2015-07-08 at 12:25 +0200, Paul Osmialowski wrote:
> This is combination of the work by Karol Lewandowski and Paul Moore
> on LSM hooks for kdbus.
>
> Originates from:
>
> git://git.infradead.org/users/pcmoore/selinux (branch: working-kdbus)
> commit: 7050f206a79564886938d0edc4e1e9da5972c72d
>
> https://github.com/lmctl/linux.git (branch: kdbus-lsm-v4.for-systemd
> -v212)
> commit: a9fe4c33b6e5ab25a243e0590df406aabb6add12
>
> Signed-off-by: Karol Lewandowski <k.lewandowsk-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> Signed-off-by: Paul Moore <pmoore-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> Signed-off-by: Paul Osmialowski <p.osmialowsk-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> ---
> include/linux/lsm_hooks.h | 67 ++++++++++++++++++++++++++
> include/linux/security.h | 99
> +++++++++++++++++++++++++++++++++++++++
> security/security.c | 117
> ++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 283 insertions(+)
>
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index 9429f05..2a8d8fc 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -1297,6 +1297,36 @@
> * @inode we wish to get the security context of.
> * @ctx is a pointer in which to place the allocated security
> context.
> * @ctxlen points to the place to put the length of @ctx.
> + *
> + * @kdbus_domain_alloc:
> + * Allocate kdbus domain.
> + * @kdbus_domain_free:
> + * Deallocate kdbus domain.
> + * @kdbus_bus_alloc:
> + * Allocate kdbus bus.
> + * @kdbus_bus_free:
> + * Deallocate kdbus bus.
> + * @kdbus_send:
> + * Send message.
> + * @kdbus_recv:
> + * Receive message.
> + * @kdbus_name_acquire:
> + * Request a well-known bus name to associate with the
> connection.
> + * @kdbus_name_list:
> + * Retrieve the list of all currently registered well-known and
> unique
> + * names.
> + * @kdbus_ep_create:
> + * Endpoint create
> + * @kdbus_connect:
> + * Connect
> + * @kdbus_conn_free:
> + * Deallocate connection
> + * @kdbus_conn_info:
> + * Retrieve credentials and properties of the initial creator
> of the
> + * connection.
> + * @kdbus_talk:
> + * Talk to a given peer.
> + *
> * This is the main security structure.
> */
>
> @@ -1520,6 +1550,29 @@ union security_list_options {
> int (*inode_setsecctx)(struct dentry *dentry, void *ctx, u32
> ctxlen);
> int (*inode_getsecctx)(struct inode *inode, void **ctx, u32
> *ctxlen);
>
> + int (*kdbus_domain_alloc)(struct kdbus_domain *domain);
> + void (*kdbus_domain_free)(struct kdbus_domain *domain);
Shouldn't all of this be inside some #ifdef CONFIG_KDBUS (or whatever
the CONFIG for kdbus is)?
> +
> + int (*kdbus_bus_alloc)(struct kdbus_bus *bus);
> + void (*kdbus_bus_free)(struct kdbus_bus *bus);
> + int (*kdbus_send)(const struct kdbus_conn *conn,
> + const struct kdbus_bus *bus);
> + int (*kdbus_recv)(const struct kdbus_conn *conn,
> + const struct kdbus_bus *bus);
> + int (*kdbus_name_acquire)(const struct kdbus_conn *conn,
> + const char *name);
> + int (*kdbus_name_list)(const struct kdbus_bus *bus);
> +
> + int (*kdbus_ep_create)(const struct kdbus_bus *bus);
> + int (*kdbus_ep_setpolicy)(const struct kdbus_bus *bus);
> +
> + int (*kdbus_connect)(struct kdbus_conn *conn,
> + const char *secctx, u32 seclen);
> + void (*kdbus_conn_free)(struct kdbus_conn *conn);
> + int (*kdbus_conn_info)(const struct kdbus_conn *conn);
> + int (*kdbus_talk)(const struct kdbus_conn *src,
> + const struct kdbus_conn *dst);
> +
> #ifdef CONFIG_SECURITY_NETWORK
> int (*unix_stream_connect)(struct sock *sock, struct sock
> *other,
> struct sock *newsk);
> @@ -1760,6 +1813,20 @@ struct security_hook_heads {
> struct list_head inode_notifysecctx;
> struct list_head inode_setsecctx;
> struct list_head inode_getsecctx;
> + struct list_head kdbus_domain_alloc;
> + struct list_head kdbus_domain_free;
> + struct list_head kdbus_bus_alloc;
> + struct list_head kdbus_bus_free;
> + struct list_head kdbus_send;
> + struct list_head kdbus_recv;
> + struct list_head kdbus_name_acquire;
> + struct list_head kdbus_name_list;
> + struct list_head kdbus_ep_create;
> + struct list_head kdbus_ep_setpolicy;
> + struct list_head kdbus_connect;
> + struct list_head kdbus_conn_free;
> + struct list_head kdbus_conn_info;
> + struct list_head kdbus_talk;
> #ifdef CONFIG_SECURITY_NETWORK
> struct list_head unix_stream_connect;
> struct list_head unix_may_send;
> diff --git a/include/linux/security.h b/include/linux/security.h
> index 79d85dd..5f257b9 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -53,6 +53,10 @@ struct msg_queue;
> struct xattr;
> struct xfrm_sec_ctx;
> struct mm_struct;
> +struct kdbus_ep;
> +struct kdbus_bus;
> +struct kdbus_conn;
> +struct kdbus_domain;
>
> /* If capable should audit the security request */
> #define SECURITY_CAP_NOAUDIT 0
> @@ -356,6 +360,28 @@ void security_release_secctx(char *secdata, u32
> seclen);
> int security_inode_notifysecctx(struct inode *inode, void *ctx, u32
> ctxlen);
> int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32
> ctxlen);
> int security_inode_getsecctx(struct inode *inode, void **ctx, u32
> *ctxlen);
> +
> +int security_kdbus_domain_alloc(struct kdbus_domain *domain);
> +void security_kdbus_domain_free(struct kdbus_domain *domain);
> +
> +int security_kdbus_bus_alloc(struct kdbus_bus *bus);
> +void security_kdbus_bus_free(struct kdbus_bus *bus);
> +int security_kdbus_send(const struct kdbus_conn *conn,
> + const struct kdbus_bus *bus);
> +int security_kdbus_recv(const struct kdbus_conn *conn,
> + const struct kdbus_bus *bus);
> +int security_kdbus_name_acquire(const struct kdbus_conn *conn,
> + const char *name);
> +int security_kdbus_name_list(const struct kdbus_bus *bus);
> +int security_kdbus_ep_create(struct kdbus_bus *bus);
> +int security_kdbus_ep_setpolicy(struct kdbus_bus *bus);
> +int security_kdbus_connect(struct kdbus_conn *conn,
> + const char *secctx, u32 seclen);
> +void security_kdbus_conn_free(struct kdbus_conn *conn);
> +int security_kdbus_conn_info(const struct kdbus_conn *conn);
> +int security_kdbus_talk(const struct kdbus_conn *src,
> + const struct kdbus_conn *dst);
> +
> #else /* CONFIG_SECURITY */
> struct security_mnt_opts {
> };
> @@ -1105,6 +1131,79 @@ static inline int
> security_inode_getsecctx(struct inode *inode, void **ctx, u32
> {
> return -EOPNOTSUPP;
> }
> +
> +static inline int security_kdbus_domain_alloc(struct kdbus_domain
> *domain)
> +{
> + return 0;
> +}
> +
> +static inline void security_kdbus_domain_free(struct kdbus_domain
> *domain)
> +{
> +}
> +
> +static inline int security_kdbus_bus_alloc(struct kdbus_bus *bus)
> +{
> + return 0;
> +}
> +
> +static inline void security_kdbus_bus_free(struct kdbus_bus *bus)
> +{
> +}
> +
> +static inline int security_kdbus_send(const struct kdbus_conn *conn,
> + const struct kdbus_bus *bus)
> +{
> + return 0;
> +}
> +
> +static inline int security_kdbus_recv(const struct kdbus_conn *conn,
> + const struct kdbus_bus *bus)
> +{
> + return 0;
> +}
> +
> +static inline int security_kdbus_name_acquire(const struct
> kdbus_conn *conn,
> + const char *name)
> +{
> + return 0;
> +}
> +
> +static inline int security_kdbus_name_list(const struct kdbus_bus
> *bus)
> +{
> + return 0;
> +}
> +
> +static inline int security_kdbus_ep_create(const struct kdbus_bus
> *bus)
> +{
> + return 0;
> +}
> +
> +static inline int security_kdbus_ep_setpolicy(const struct kdbus_bus
> *bus)
> +{
> + return 0;
> +}
> +
> +static inline int security_kdbus_connect(struct kdbus_conn *conn,
> + const char *secctx, u32
> seclen)
> +{
> + return 0;
> +}
> +
> +static inline void security_kdbus_conn_free(struct kdbus_conn *conn)
> +{
> +}
> +
> +static inline int security_kdbus_conn_info(const struct kdbus_conn
> *conn)
> +{
> + return 0;
> +}
> +
> +static inline int security_kdbus_talk(const struct kdbus_conn *src,
> + const struct kdbus_conn *dst)
> +{
> + return 0;
> +}
> +
> #endif /* CONFIG_SECURITY */
>
> #ifdef CONFIG_SECURITY_NETWORK
> diff --git a/security/security.c b/security/security.c
> index b1e935b..7fb46d1 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -1185,6 +1185,95 @@ int security_inode_getsecctx(struct inode
> *inode, void **ctx, u32 *ctxlen)
> }
> EXPORT_SYMBOL(security_inode_getsecctx);
>
> +int security_kdbus_domain_alloc(struct kdbus_domain *domain)
> +{
> + return call_int_hook(kdbus_domain_alloc, 0, domain);
> +}
> +EXPORT_SYMBOL(security_kdbus_domain_alloc);
> +
> +void security_kdbus_domain_free(struct kdbus_domain *domain)
> +{
> + call_void_hook(kdbus_domain_free, domain);
> +}
> +EXPORT_SYMBOL(security_kdbus_domain_free);
> +
> +int security_kdbus_bus_alloc(struct kdbus_bus *bus)
> +{
> + return call_int_hook(kdbus_bus_alloc, 0, bus);
> +}
> +EXPORT_SYMBOL(security_kdbus_bus_alloc);
> +
> +void security_kdbus_bus_free(struct kdbus_bus *bus)
> +{
> + call_void_hook(kdbus_bus_free, bus);
> +}
> +EXPORT_SYMBOL(security_kdbus_bus_free);
> +
> +int security_kdbus_send(const struct kdbus_conn *conn,
> + const struct kdbus_bus *bus)
> +{
> + return call_int_hook(kdbus_send, 0, conn, bus);
> +}
> +EXPORT_SYMBOL(security_kdbus_send);
> +
> +int security_kdbus_recv(const struct kdbus_conn *conn,
> + const struct kdbus_bus *bus)
> +{
> + return call_int_hook(kdbus_recv, 0, conn, bus);
> +}
> +EXPORT_SYMBOL(security_kdbus_recv);
> +
> +int security_kdbus_name_acquire(const struct kdbus_conn *conn,
> + const char *name)
> +{
> + return call_int_hook(kdbus_name_acquire, 0, conn, name);
> +}
> +EXPORT_SYMBOL(security_kdbus_name_acquire);
> +
> +int security_kdbus_name_list(const struct kdbus_bus *bus)
> +{
> + return call_int_hook(kdbus_name_list, 0, bus);
> +}
> +EXPORT_SYMBOL(security_kdbus_name_list);
> +
> +int security_kdbus_ep_create(struct kdbus_bus *bus)
> +{
> + return call_int_hook(kdbus_ep_create, 0, bus);
> +}
> +EXPORT_SYMBOL(security_kdbus_ep_create);
> +
> +int security_kdbus_ep_setpolicy(struct kdbus_bus *bus)
> +{
> + return call_int_hook(kdbus_ep_setpolicy, 0, bus);
> +}
> +EXPORT_SYMBOL(security_kdbus_ep_setpolicy);
> +
> +int security_kdbus_connect(struct kdbus_conn *conn,
> + const char *secctx, u32 seclen)
> +{
> + return call_int_hook(kdbus_connect, 0, conn, secctx,
> seclen);
> +}
> +EXPORT_SYMBOL(security_kdbus_connect);
> +
> +void security_kdbus_conn_free(struct kdbus_conn *conn)
> +{
> + call_void_hook(kdbus_conn_free, conn);
> +}
> +EXPORT_SYMBOL(security_kdbus_conn_free);
> +
> +int security_kdbus_conn_info(const struct kdbus_conn *conn)
> +{
> + return call_int_hook(kdbus_conn_info, 0, conn);
> +}
> +EXPORT_SYMBOL(security_kdbus_conn_info);
> +
> +int security_kdbus_talk(const struct kdbus_conn *src,
> + const struct kdbus_conn *dst)
> +{
> + return call_int_hook(kdbus_talk, 0, src, dst);
> +}
> +EXPORT_SYMBOL(security_kdbus_talk);
> +
> #ifdef CONFIG_SECURITY_NETWORK
>
> int security_unix_stream_connect(struct sock *sock, struct sock
> *other, struct sock *newsk)
> @@ -1774,6 +1863,34 @@ struct security_hook_heads security_hook_heads
> = {
> LIST_HEAD_INIT(security_hook_heads.inode_setsecctx),
> .inode_getsecctx =
> LIST_HEAD_INIT(security_hook_heads.inode_getsecctx),
> + .kdbus_domain_alloc =
> + LIST_HEAD_INIT(security_hook_heads.kdbus_domain_allo
> c),
> + .kdbus_domain_free =
> + LIST_HEAD_INIT(security_hook_heads.kdbus_domain_free
> ),
> + .kdbus_bus_alloc =
> + LIST_HEAD_INIT(security_hook_heads.kdbus_bus_alloc),
> + .kdbus_bus_free =
> + LIST_HEAD_INIT(security_hook_heads.kdbus_bus_free),
> + .kdbus_send =
> + LIST_HEAD_INIT(security_hook_heads.kdbus_send),
> + .kdbus_recv =
> + LIST_HEAD_INIT(security_hook_heads.kdbus_recv),
> + .kdbus_name_acquire =
> + LIST_HEAD_INIT(security_hook_heads.kdbus_name_acquir
> e),
> + .kdbus_name_list =
> + LIST_HEAD_INIT(security_hook_heads.kdbus_name_list),
> + .kdbus_ep_create =
> + LIST_HEAD_INIT(security_hook_heads.kdbus_ep_create),
> + .kdbus_ep_setpolicy =
> + LIST_HEAD_INIT(security_hook_heads.kdbus_ep_setpolic
> y),
> + .kdbus_connect =
> + LIST_HEAD_INIT(security_hook_heads.kdbus_connect),
> + .kdbus_conn_free =
> + LIST_HEAD_INIT(security_hook_heads.kdbus_conn_free),
> + .kdbus_conn_info =
> + LIST_HEAD_INIT(security_hook_heads.kdbus_conn_info),
> + .kdbus_talk =
> + LIST_HEAD_INIT(security_hook_heads.kdbus_talk),
> #ifdef CONFIG_SECURITY_NETWORK
> .unix_stream_connect =
> LIST_HEAD_INIT(security_hook_heads.unix_stream_conne
> ct),
--
Lukasz Pawelczyk
Samsung R&D Institute Poland
Samsung Electronics
^ permalink raw reply
* Re: [RFC 5/8] kdbus: use LSM hooks in kdbus code
From: Lukasz Pawelczyk @ 2015-07-08 11:06 UTC (permalink / raw)
To: Paul Osmialowski, Paul Moore, James Morris, Casey Schaufler,
Serge E. Hallyn, Kees Cook, Tetsuo Handa, Stephen Smalley,
Neil Brown, Mark Rustad, Greg Kroah-Hartman, Daniel Mack,
David Herrmann, Djalal Harouni, Shuah Khan, Al Viro,
linux-security-module-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA
Cc: Karol Lewandowski, Lukasz Skalski
In-Reply-To: <1436351110-5902-6-git-send-email-p.osmialowsk-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
On śro, 2015-07-08 at 12:25 +0200, Paul Osmialowski wrote:
> Originates from:
>
> https://github.com/lmctl/kdbus.git (branch: kdbus-lsm-v4.for-systemd
> -v212)
> commit: aa0885489d19be92fa41c6f0a71df28763228a40
>
> Signed-off-by: Karol Lewandowski <k.lewandowsk-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> Signed-off-by: Paul Osmialowski <p.osmialowsk-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> ---
> ipc/kdbus/bus.c | 12 ++++++++++-
> ipc/kdbus/bus.h | 3 +++
> ipc/kdbus/connection.c | 54
> ++++++++++++++++++++++++++++++++++++++++++++++++++
> ipc/kdbus/connection.h | 4 ++++
> ipc/kdbus/domain.c | 9 ++++++++-
> ipc/kdbus/domain.h | 2 ++
> ipc/kdbus/endpoint.c | 11 ++++++++++
> ipc/kdbus/names.c | 11 ++++++++++
> ipc/kdbus/queue.c | 30 ++++++++++++++++++----------
> 9 files changed, 124 insertions(+), 12 deletions(-)
>
> diff --git a/ipc/kdbus/bus.c b/ipc/kdbus/bus.c
> index bbdf0f2..9894895 100644
> --- a/ipc/kdbus/bus.c
> +++ b/ipc/kdbus/bus.c
> @@ -22,6 +22,7 @@
> #include <linux/slab.h>
> #include <linux/uaccess.h>
> #include <linux/uio.h>
> +#include <linux/security.h>
>
> #include "bus.h"
> #include "notify.h"
> @@ -51,6 +52,7 @@ static void kdbus_bus_free(struct kdbus_node *node)
> kdbus_domain_unref(bus->domain);
> kdbus_policy_db_clear(&bus->policy_db);
> kdbus_meta_proc_unref(bus->creator_meta);
> + security_kdbus_bus_free(bus);
> kfree(bus);
> }
>
> @@ -161,6 +163,12 @@ static struct kdbus_bus *kdbus_bus_new(struct
> kdbus_domain *domain,
> goto exit_unref;
> }
>
> + ret = security_kdbus_bus_alloc(b);
> + if (ret) {
> + ret = -EPERM;
> + goto exit_unref;
> + }
> +
> /*
> * Bus-limits of the creator are accounted on its real UID,
> just like
> * all other per-user limits.
> @@ -169,11 +177,13 @@ static struct kdbus_bus *kdbus_bus_new(struct
> kdbus_domain *domain,
> if (IS_ERR(b->creator)) {
> ret = PTR_ERR(b->creator);
> b->creator = NULL;
> - goto exit_unref;
> + goto exit_free_security;
> }
>
> return b;
>
> +exit_free_security:
> + security_kdbus_bus_free(b);
> exit_unref:
> kdbus_node_deactivate(&b->node);
> kdbus_node_unref(&b->node);
> diff --git a/ipc/kdbus/bus.h b/ipc/kdbus/bus.h
> index 5bea5ef..03e4a54 100644
> --- a/ipc/kdbus/bus.h
> +++ b/ipc/kdbus/bus.h
> @@ -53,6 +53,7 @@ struct kdbus_user;
> * @notify_list: List of pending kernel-generated messages
> * @notify_lock: Notification list lock
> * @notify_flush_lock: Notification flushing lock
> + * @security: LSM security blob
> */
> struct kdbus_bus {
> struct kdbus_node node;
> @@ -81,6 +82,8 @@ struct kdbus_bus {
> struct list_head notify_list;
> spinlock_t notify_lock;
> struct mutex notify_flush_lock;
> +
> + void *security;
Security blobs are usually inside #ifdef CONFIG_SECURITY
> };
>
> struct kdbus_bus *kdbus_bus_ref(struct kdbus_bus *bus);
> diff --git a/ipc/kdbus/connection.c b/ipc/kdbus/connection.c
> index 9993753..b85cdc7 100644
> --- a/ipc/kdbus/connection.c
> +++ b/ipc/kdbus/connection.c
> @@ -31,6 +31,7 @@
> #include <linux/slab.h>
> #include <linux/syscalls.h>
> #include <linux/uio.h>
> +#include <linux/security.h>
>
> #include "bus.h"
> #include "connection.h"
> @@ -73,6 +74,8 @@ static struct kdbus_conn *kdbus_conn_new(struct
> kdbus_ep *ep, bool privileged,
> bool is_activator;
> bool is_monitor;
> struct kvec kvec;
> + u32 sid, len;
> + char *label;
> int ret;
>
> struct {
> @@ -222,6 +225,14 @@ static struct kdbus_conn *kdbus_conn_new(struct
> kdbus_ep *ep, bool privileged,
> }
> }
>
> + security_task_getsecid(current, &sid);
> + security_secid_to_secctx(sid, &label, &len);
> + ret = security_kdbus_connect(conn, label, len);
> + if (ret) {
> + ret = -EPERM;
> + goto exit_unref;
> + }
> +
> if (atomic_inc_return(&conn->user->connections) >
> KDBUS_USER_MAX_CONN) {
> /* decremented by destructor as conn->user is valid
> */
> ret = -EMFILE;
> @@ -276,6 +287,7 @@ static void __kdbus_conn_free(struct kref *kref)
> kdbus_pool_free(conn->pool);
> kdbus_ep_unref(conn->ep);
> put_cred(conn->cred);
> + security_kdbus_conn_free(conn);
> kfree(conn->description);
> kfree(conn->quota);
> kfree(conn);
> @@ -1107,6 +1119,12 @@ static int kdbus_conn_reply(struct kdbus_conn
> *src, struct kdbus_kmsg *kmsg)
> if (ret < 0)
> goto exit;
>
> + ret = security_kdbus_talk(src, dst);
> + if (ret) {
> + ret = -EPERM;
> + goto exit;
> + }
> +
> mutex_lock(&dst->lock);
> reply = kdbus_reply_find(src, dst, kmsg->msg.cookie_reply);
> if (reply) {
> @@ -1187,6 +1205,12 @@ static struct kdbus_reply
> *kdbus_conn_call(struct kdbus_conn *src,
> if (ret < 0)
> goto exit;
>
> + ret = security_kdbus_talk(src, dst);
> + if (ret) {
> + ret = -EPERM;
> + goto exit;
> + }
> +
> if (!kdbus_conn_policy_talk(src, current_cred(), dst)) {
> ret = -EPERM;
> goto exit;
> @@ -1248,6 +1272,12 @@ static int kdbus_conn_unicast(struct
> kdbus_conn *src, struct kdbus_kmsg *kmsg)
> if (ret < 0)
> goto exit;
>
> + ret = security_kdbus_talk(src, dst);
> + if (ret) {
> + ret = -EPERM;
> + goto exit;
> + }
> +
> if (is_signal) {
> /* like broadcasts we eavesdrop even if the msg is
> dropped */
> kdbus_bus_eavesdrop(bus, src, kmsg);
> @@ -1639,6 +1669,12 @@ struct kdbus_conn *kdbus_cmd_hello(struct
> kdbus_ep *ep, bool privileged,
> if (ret < 0)
> goto exit;
>
> + ret = security_kdbus_ep_setpolicy(c->ep->bus);
> + if (ret) {
> + ret = -EPERM;
> + goto exit;
> + }
> +
> ret = kdbus_policy_set(&c->ep->bus->policy_db,
> args.items,
> args.items_size, 1,
>
> kdbus_conn_is_policy_holder(c), c);
> @@ -1732,6 +1768,10 @@ int kdbus_cmd_conn_info(struct kdbus_conn
> *conn, void __user *argp)
> if (ret != 0)
> return ret;
>
> + ret = security_kdbus_conn_info(conn);
> + if (ret)
> + return -EPERM;
> +
> /* registry must be held throughout lookup *and* collecting
> data */
> down_read(&bus->name_registry->rwlock);
>
> @@ -1905,6 +1945,12 @@ int kdbus_cmd_update(struct kdbus_conn *conn,
> void __user *argp)
> /* now that we verified the input, update the connection */
>
> if (item_policy) {
> + ret = security_kdbus_ep_setpolicy(conn->ep->bus);
> + if (ret) {
> + ret = -EPERM;
> + goto exit;
> + }
> +
> ret = kdbus_policy_set(&conn->ep->bus->policy_db,
> cmd->items,
> KDBUS_ITEMS_SIZE(cmd, items),
> 1, true, conn);
> @@ -1948,6 +1994,10 @@ int kdbus_cmd_send(struct kdbus_conn *conn,
> struct file *f, void __user *argp)
> .argc = ARRAY_SIZE(argv),
> };
>
> + ret = security_kdbus_send(conn, conn->ep->bus);
> + if (ret)
> + return -EPERM;
> +
> if (!kdbus_conn_is_ordinary(conn))
> return -EOPNOTSUPP;
>
> @@ -2044,6 +2094,10 @@ int kdbus_cmd_recv(struct kdbus_conn *conn,
> void __user *argp)
> .argc = ARRAY_SIZE(argv),
> };
>
> + ret = security_kdbus_recv(conn, conn->ep->bus);
> + if (ret)
> + return -EPERM;
> +
> if (!kdbus_conn_is_ordinary(conn) &&
> !kdbus_conn_is_monitor(conn) &&
> !kdbus_conn_is_activator(conn))
> diff --git a/ipc/kdbus/connection.h b/ipc/kdbus/connection.h
> index d1ffe90..1f91d39 100644
> --- a/ipc/kdbus/connection.h
> +++ b/ipc/kdbus/connection.h
> @@ -19,6 +19,7 @@
> #include <linux/kref.h>
> #include <linux/lockdep.h>
> #include <linux/path.h>
> +#include <uapi/linux/kdbus.h>
>
> #include "limits.h"
> #include "metadata.h"
> @@ -73,6 +74,7 @@ struct kdbus_kmsg;
> * @names_queue_list: Well-known names this connection waits for
> * @privileged: Whether this connection is
> privileged on the bus
> * @faked_meta: Whether the metadata was faked on
> HELLO
> + * @security: LSM security blob
> */
> struct kdbus_conn {
> struct kref kref;
> @@ -113,6 +115,8 @@ struct kdbus_conn {
>
> bool privileged:1;
> bool faked_meta:1;
> +
> + void *security;
> };
>
> struct kdbus_conn *kdbus_conn_ref(struct kdbus_conn *conn);
> diff --git a/ipc/kdbus/domain.c b/ipc/kdbus/domain.c
> index ac9f760..da9cdab 100644
> --- a/ipc/kdbus/domain.c
> +++ b/ipc/kdbus/domain.c
> @@ -20,6 +20,7 @@
> #include <linux/sizes.h>
> #include <linux/slab.h>
> #include <linux/uaccess.h>
> +#include <linux/security.h>
>
> #include "bus.h"
> #include "domain.h"
> @@ -73,6 +74,7 @@ static void kdbus_domain_free(struct kdbus_node
> *node)
> put_user_ns(domain->user_namespace);
> ida_destroy(&domain->user_ida);
> idr_destroy(&domain->user_idr);
> + security_kdbus_domain_free(domain);
> kfree(domain);
> }
>
> @@ -104,6 +106,10 @@ struct kdbus_domain *kdbus_domain_new(unsigned
> int access)
> idr_init(&d->user_idr);
> ida_init(&d->user_ida);
>
> + ret = security_kdbus_domain_alloc(d);
> + if (ret)
> + return ERR_PTR(-EPERM);
> +
> /* Pin user namespace so we can guarantee domain-unique bus
> * names. */
> d->user_namespace = get_user_ns(current_user_ns());
>
> @@ -116,6 +122,7 @@ struct kdbus_domain *kdbus_domain_new(unsigned
> int access)
> exit_unref:
> kdbus_node_deactivate(&d->node);
> kdbus_node_unref(&d->node);
> + security_kdbus_domain_free(d);
> return ERR_PTR(ret);
> }
>
> @@ -264,7 +271,7 @@ static void __kdbus_user_free(struct kref *kref)
> if (uid_valid(user->uid))
> idr_remove(&user->domain->user_idr, __kuid_val(user
> ->uid));
> mutex_unlock(&user->domain->lock);
> -
> + security_kdbus_domain_free(user->domain);
> kdbus_domain_unref(user->domain);
> kfree(user);
> }
> diff --git a/ipc/kdbus/domain.h b/ipc/kdbus/domain.h
> index 447a2bd..3db06d8 100644
> --- a/ipc/kdbus/domain.h
> +++ b/ipc/kdbus/domain.h
> @@ -31,6 +31,7 @@
> * @user_ida: Set of all users to compute small indices
> * @user_namespace: User namespace, pinned at creation time
> * @dentry: Root dentry of VFS mount (don't use outside
> of kdbusfs)
> + * @security: LSM security blob
> */
> struct kdbus_domain {
> struct kdbus_node node;
> @@ -40,6 +41,7 @@ struct kdbus_domain {
> struct ida user_ida;
> struct user_namespace *user_namespace;
> struct dentry *dentry;
> + void *security;
> };
>
> /**
> diff --git a/ipc/kdbus/endpoint.c b/ipc/kdbus/endpoint.c
> index 9a95a5e..380228f 100644
> --- a/ipc/kdbus/endpoint.c
> +++ b/ipc/kdbus/endpoint.c
> @@ -21,6 +21,7 @@
> #include <linux/slab.h>
> #include <linux/uaccess.h>
> #include <linux/uio.h>
> +#include <linux/security.h>
>
> #include "bus.h"
> #include "connection.h"
> @@ -122,6 +123,12 @@ struct kdbus_ep *kdbus_ep_new(struct kdbus_bus
> *bus, const char *name,
> kdbus_policy_db_init(&e->policy_db);
> e->bus = kdbus_bus_ref(bus);
>
> + ret = security_kdbus_ep_create(bus);
> + if (ret) {
> + ret = -EPERM;
> + goto exit_unref;
> + }
> +
> ret = kdbus_node_link(&e->node, &bus->node, name);
> if (ret < 0)
> goto exit_unref;
> @@ -265,6 +272,10 @@ int kdbus_cmd_ep_update(struct kdbus_ep *ep,
> void __user *argp)
> .argc = ARRAY_SIZE(argv),
> };
>
> + ret = security_kdbus_ep_setpolicy(ep->bus);
> + if (ret)
> + return -EPERM;
> +
> ret = kdbus_args_parse(&args, argp, &cmd);
> if (ret != 0)
> return ret;
> diff --git a/ipc/kdbus/names.c b/ipc/kdbus/names.c
> index d77ee08..dd20bea 100644
> --- a/ipc/kdbus/names.c
> +++ b/ipc/kdbus/names.c
> @@ -24,6 +24,7 @@
> #include <linux/slab.h>
> #include <linux/uaccess.h>
> #include <linux/uio.h>
> +#include <linux/security.h>
>
> #include "bus.h"
> #include "connection.h"
> @@ -503,6 +504,12 @@ int kdbus_cmd_name_acquire(struct kdbus_conn
> *conn, void __user *argp)
> goto exit;
> }
>
> + ret = security_kdbus_name_acquire(conn, item_name);
> + if (ret) {
> + ret = -EPERM;
> + goto exit;
> + }
> +
> /*
> * Do atomic_inc_return here to reserve our slot, then
> decrement
> * it before returning.
> @@ -724,6 +731,10 @@ int kdbus_cmd_list(struct kdbus_conn *conn, void
> __user *argp)
> if (ret != 0)
> return ret;
>
> + ret = security_kdbus_name_list(conn->ep->bus);
> + if (ret)
> + return -EPERM;
> +
> /* lock order: domain -> bus -> ep -> names -> conn */
> down_read(®->rwlock);
> down_read(&conn->ep->bus->conn_rwlock);
> diff --git a/ipc/kdbus/queue.c b/ipc/kdbus/queue.c
> index 25bb3ad..9872fb4 100644
> --- a/ipc/kdbus/queue.c
> +++ b/ipc/kdbus/queue.c
> @@ -28,6 +28,7 @@
> #include <linux/slab.h>
> #include <linux/syscalls.h>
> #include <linux/uio.h>
> +#include <linux/security.h>
>
> #include "util.h"
> #include "domain.h"
> @@ -514,12 +515,17 @@ int kdbus_queue_entry_install(struct
> kdbus_queue_entry *entry,
>
> for (i = 0; i < res->fds_count; i++) {
> if (install_fds) {
> - fds[i] =
> get_unused_fd_flags(O_CLOEXEC);
> - if (fds[i] >= 0)
> - fd_install(fds[i],
> - get_file(res
> ->fds[i]));
> - else
> + if (security_file_receive(res
> ->fds[i])) {
> + fds[i] = -1;
> incomplete_fds = true;
> + } else {
> + fds[i] =
> get_unused_fd_flags(O_CLOEXEC);
> + if (fds[i] >= 0)
> + fd_install(fds[i],
> + get_file(res
> ->fds[i]));
> + else
> + incomplete_fds =
> true;
> + }
> } else {
> fds[i] = -1;
> }
> @@ -557,13 +563,17 @@ int kdbus_queue_entry_install(struct
> kdbus_queue_entry *entry,
> m.fd = -1;
>
> if (install_fds) {
> - m.fd = get_unused_fd_flags(O_CLOEXEC);
> - if (m.fd < 0) {
> - m.fd = -1;
> + if (security_file_receive(d->memfd.file)) {
> incomplete_fds = true;
> } else {
> - fd_install(m.fd,
> - get_file(d->memfd.file));
> + m.fd =
> get_unused_fd_flags(O_CLOEXEC);
> + if (m.fd < 0) {
> + m.fd = -1;
> + incomplete_fds = true;
> + } else {
> + fd_install(m.fd,
> + get_file(d
> ->memfd.file));
> + }
> }
> }
>
--
Lukasz Pawelczyk
Samsung R&D Institute Poland
Samsung Electronics
^ permalink raw reply
* Re: [PATCH V3 2/5] mm: mlock: Add new mlock, munlock, and munlockall system calls
From: Catalin Marinas @ 2015-07-08 11:06 UTC (permalink / raw)
To: Eric B Munson
Cc: Andrew Morton, linux-arch-u79uwXL29TY76Z2rM5mHXA, Michal Hocko,
linux-am33-list-H+wXaHxf7aLQT0dZR+AlfA,
linux-ia64-u79uwXL29TY76Z2rM5mHXA,
linux-parisc-u79uwXL29TY76Z2rM5mHXA,
linux-cris-kernel-VrBV9hrLPhE, linux-mips-6z/3iImG2C8G8FEW9MqTrA,
linux-s390-u79uwXL29TY76Z2rM5mHXA,
linux-xtensa-PjhNF2WwrV/0Sa2dR60CXw,
linux-sh-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
adi-buildroot-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
linux-mm-Bw31MaZKKs3YtjvyW6yDsg,
linux-m68k-cunTk1MwBs8S/qaLPR03pWD2FQJk+8+b, Vlastimil Babka,
linux-alpha-u79uwXL29TY76Z2rM5mHXA,
sparclinux-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA,
linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <1436288623-13007-3-git-send-email-emunson-JqFfY2XvxFXQT0dZR+AlfA@public.gmane.org>
On Tue, Jul 07, 2015 at 01:03:40PM -0400, Eric B Munson wrote:
> diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
> index 05745eb..514e77b 100644
> --- a/arch/arm/kernel/calls.S
> +++ b/arch/arm/kernel/calls.S
> @@ -397,6 +397,9 @@
> /* 385 */ CALL(sys_memfd_create)
> CALL(sys_bpf)
> CALL(sys_execveat)
> + CALL(sys_mlock2)
> + CALL(sys_munlock2)
> +/* 400 */ CALL(sys_munlockall2)
s/400/390/
> diff --git a/arch/arm64/include/asm/unistd32.h b/arch/arm64/include/asm/unistd32.h
> index cef934a..318072aa 100644
> --- a/arch/arm64/include/asm/unistd32.h
> +++ b/arch/arm64/include/asm/unistd32.h
> @@ -797,3 +797,9 @@ __SYSCALL(__NR_memfd_create, sys_memfd_create)
> __SYSCALL(__NR_bpf, sys_bpf)
> #define __NR_execveat 387
> __SYSCALL(__NR_execveat, compat_sys_execveat)
> +#define __NR_mlock2 388
> +__SYSCALL(__NR_mlock2, sys_mlock2)
> +#define __NR_munlock2 389
> +__SYSCALL(__NR_munlock2, sys_munlock2)
> +#define __NR_munlockall2 390
> +__SYSCALL(__NR_munlockall2, sys_munlockall2)
These look fine.
Catalin
^ permalink raw reply
* Re: [RFC 5/8] kdbus: use LSM hooks in kdbus code
From: Lukasz Pawelczyk @ 2015-07-08 11:09 UTC (permalink / raw)
To: Paul Osmialowski, Paul Moore, James Morris, Casey Schaufler,
Serge E. Hallyn, Kees Cook, Tetsuo Handa, Stephen Smalley,
Neil Brown, Mark Rustad, Greg Kroah-Hartman, Daniel Mack,
David Herrmann, Djalal Harouni, Shuah Khan, Al Viro,
linux-security-module-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA
Cc: Karol Lewandowski, Lukasz Skalski
In-Reply-To: <1436351110-5902-6-git-send-email-p.osmialowsk-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
On śro, 2015-07-08 at 12:25 +0200, Paul Osmialowski wrote:
> Originates from:
>
> https://github.com/lmctl/kdbus.git (branch: kdbus-lsm-v4.for-systemd
> -v212)
> commit: aa0885489d19be92fa41c6f0a71df28763228a40
>
> Signed-off-by: Karol Lewandowski <k.lewandowsk-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> Signed-off-by: Paul Osmialowski <p.osmialowsk-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> ---
> ipc/kdbus/bus.c | 12 ++++++++++-
> ipc/kdbus/bus.h | 3 +++
> ipc/kdbus/connection.c | 54
> ++++++++++++++++++++++++++++++++++++++++++++++++++
> ipc/kdbus/connection.h | 4 ++++
> ipc/kdbus/domain.c | 9 ++++++++-
> ipc/kdbus/domain.h | 2 ++
> ipc/kdbus/endpoint.c | 11 ++++++++++
> ipc/kdbus/names.c | 11 ++++++++++
> ipc/kdbus/queue.c | 30 ++++++++++++++++++----------
> 9 files changed, 124 insertions(+), 12 deletions(-)
>
> diff --git a/ipc/kdbus/bus.c b/ipc/kdbus/bus.c
> index bbdf0f2..9894895 100644
> --- a/ipc/kdbus/bus.c
> +++ b/ipc/kdbus/bus.c
> @@ -22,6 +22,7 @@
> #include <linux/slab.h>
> #include <linux/uaccess.h>
> #include <linux/uio.h>
> +#include <linux/security.h>
>
> #include "bus.h"
> #include "notify.h"
> @@ -51,6 +52,7 @@ static void kdbus_bus_free(struct kdbus_node *node)
> kdbus_domain_unref(bus->domain);
> kdbus_policy_db_clear(&bus->policy_db);
> kdbus_meta_proc_unref(bus->creator_meta);
> + security_kdbus_bus_free(bus);
> kfree(bus);
> }
>
> @@ -161,6 +163,12 @@ static struct kdbus_bus *kdbus_bus_new(struct
> kdbus_domain *domain,
> goto exit_unref;
> }
>
> + ret = security_kdbus_bus_alloc(b);
> + if (ret) {
> + ret = -EPERM;
> + goto exit_unref;
> + }
Also, why aren't the error codes passed from LSM? LSM can return
anything, from EINVAL, to ENOMEM. Returning EPERM can be misleading.
> +
> /*
> * Bus-limits of the creator are accounted on its real UID,
> just like
> * all other per-user limits.
> @@ -169,11 +177,13 @@ static struct kdbus_bus *kdbus_bus_new(struct
> kdbus_domain *domain,
> if (IS_ERR(b->creator)) {
> ret = PTR_ERR(b->creator);
> b->creator = NULL;
> - goto exit_unref;
> + goto exit_free_security;
> }
>
> return b;
>
> +exit_free_security:
> + security_kdbus_bus_free(b);
> exit_unref:
> kdbus_node_deactivate(&b->node);
> kdbus_node_unref(&b->node);
> diff --git a/ipc/kdbus/bus.h b/ipc/kdbus/bus.h
> index 5bea5ef..03e4a54 100644
> --- a/ipc/kdbus/bus.h
> +++ b/ipc/kdbus/bus.h
> @@ -53,6 +53,7 @@ struct kdbus_user;
> * @notify_list: List of pending kernel-generated messages
> * @notify_lock: Notification list lock
> * @notify_flush_lock: Notification flushing lock
> + * @security: LSM security blob
> */
> struct kdbus_bus {
> struct kdbus_node node;
> @@ -81,6 +82,8 @@ struct kdbus_bus {
> struct list_head notify_list;
> spinlock_t notify_lock;
> struct mutex notify_flush_lock;
> +
> + void *security;
> };
>
> struct kdbus_bus *kdbus_bus_ref(struct kdbus_bus *bus);
> diff --git a/ipc/kdbus/connection.c b/ipc/kdbus/connection.c
> index 9993753..b85cdc7 100644
> --- a/ipc/kdbus/connection.c
> +++ b/ipc/kdbus/connection.c
> @@ -31,6 +31,7 @@
> #include <linux/slab.h>
> #include <linux/syscalls.h>
> #include <linux/uio.h>
> +#include <linux/security.h>
>
> #include "bus.h"
> #include "connection.h"
> @@ -73,6 +74,8 @@ static struct kdbus_conn *kdbus_conn_new(struct
> kdbus_ep *ep, bool privileged,
> bool is_activator;
> bool is_monitor;
> struct kvec kvec;
> + u32 sid, len;
> + char *label;
> int ret;
>
> struct {
> @@ -222,6 +225,14 @@ static struct kdbus_conn *kdbus_conn_new(struct
> kdbus_ep *ep, bool privileged,
> }
> }
>
> + security_task_getsecid(current, &sid);
> + security_secid_to_secctx(sid, &label, &len);
> + ret = security_kdbus_connect(conn, label, len);
> + if (ret) {
> + ret = -EPERM;
> + goto exit_unref;
> + }
> +
> if (atomic_inc_return(&conn->user->connections) >
> KDBUS_USER_MAX_CONN) {
> /* decremented by destructor as conn->user is valid
> */
> ret = -EMFILE;
> @@ -276,6 +287,7 @@ static void __kdbus_conn_free(struct kref *kref)
> kdbus_pool_free(conn->pool);
> kdbus_ep_unref(conn->ep);
> put_cred(conn->cred);
> + security_kdbus_conn_free(conn);
> kfree(conn->description);
> kfree(conn->quota);
> kfree(conn);
> @@ -1107,6 +1119,12 @@ static int kdbus_conn_reply(struct kdbus_conn
> *src, struct kdbus_kmsg *kmsg)
> if (ret < 0)
> goto exit;
>
> + ret = security_kdbus_talk(src, dst);
> + if (ret) {
> + ret = -EPERM;
> + goto exit;
> + }
> +
> mutex_lock(&dst->lock);
> reply = kdbus_reply_find(src, dst, kmsg->msg.cookie_reply);
> if (reply) {
> @@ -1187,6 +1205,12 @@ static struct kdbus_reply
> *kdbus_conn_call(struct kdbus_conn *src,
> if (ret < 0)
> goto exit;
>
> + ret = security_kdbus_talk(src, dst);
> + if (ret) {
> + ret = -EPERM;
> + goto exit;
> + }
> +
> if (!kdbus_conn_policy_talk(src, current_cred(), dst)) {
> ret = -EPERM;
> goto exit;
> @@ -1248,6 +1272,12 @@ static int kdbus_conn_unicast(struct
> kdbus_conn *src, struct kdbus_kmsg *kmsg)
> if (ret < 0)
> goto exit;
>
> + ret = security_kdbus_talk(src, dst);
> + if (ret) {
> + ret = -EPERM;
> + goto exit;
> + }
> +
> if (is_signal) {
> /* like broadcasts we eavesdrop even if the msg is
> dropped */
> kdbus_bus_eavesdrop(bus, src, kmsg);
> @@ -1639,6 +1669,12 @@ struct kdbus_conn *kdbus_cmd_hello(struct
> kdbus_ep *ep, bool privileged,
> if (ret < 0)
> goto exit;
>
> + ret = security_kdbus_ep_setpolicy(c->ep->bus);
> + if (ret) {
> + ret = -EPERM;
> + goto exit;
> + }
> +
> ret = kdbus_policy_set(&c->ep->bus->policy_db,
> args.items,
> args.items_size, 1,
>
> kdbus_conn_is_policy_holder(c), c);
> @@ -1732,6 +1768,10 @@ int kdbus_cmd_conn_info(struct kdbus_conn
> *conn, void __user *argp)
> if (ret != 0)
> return ret;
>
> + ret = security_kdbus_conn_info(conn);
> + if (ret)
> + return -EPERM;
> +
> /* registry must be held throughout lookup *and* collecting
> data */
> down_read(&bus->name_registry->rwlock);
>
> @@ -1905,6 +1945,12 @@ int kdbus_cmd_update(struct kdbus_conn *conn,
> void __user *argp)
> /* now that we verified the input, update the connection */
>
> if (item_policy) {
> + ret = security_kdbus_ep_setpolicy(conn->ep->bus);
> + if (ret) {
> + ret = -EPERM;
> + goto exit;
> + }
> +
> ret = kdbus_policy_set(&conn->ep->bus->policy_db,
> cmd->items,
> KDBUS_ITEMS_SIZE(cmd, items),
> 1, true, conn);
> @@ -1948,6 +1994,10 @@ int kdbus_cmd_send(struct kdbus_conn *conn,
> struct file *f, void __user *argp)
> .argc = ARRAY_SIZE(argv),
> };
>
> + ret = security_kdbus_send(conn, conn->ep->bus);
> + if (ret)
> + return -EPERM;
> +
> if (!kdbus_conn_is_ordinary(conn))
> return -EOPNOTSUPP;
>
> @@ -2044,6 +2094,10 @@ int kdbus_cmd_recv(struct kdbus_conn *conn,
> void __user *argp)
> .argc = ARRAY_SIZE(argv),
> };
>
> + ret = security_kdbus_recv(conn, conn->ep->bus);
> + if (ret)
> + return -EPERM;
> +
> if (!kdbus_conn_is_ordinary(conn) &&
> !kdbus_conn_is_monitor(conn) &&
> !kdbus_conn_is_activator(conn))
> diff --git a/ipc/kdbus/connection.h b/ipc/kdbus/connection.h
> index d1ffe90..1f91d39 100644
> --- a/ipc/kdbus/connection.h
> +++ b/ipc/kdbus/connection.h
> @@ -19,6 +19,7 @@
> #include <linux/kref.h>
> #include <linux/lockdep.h>
> #include <linux/path.h>
> +#include <uapi/linux/kdbus.h>
>
> #include "limits.h"
> #include "metadata.h"
> @@ -73,6 +74,7 @@ struct kdbus_kmsg;
> * @names_queue_list: Well-known names this connection waits for
> * @privileged: Whether this connection is
> privileged on the bus
> * @faked_meta: Whether the metadata was faked on
> HELLO
> + * @security: LSM security blob
> */
> struct kdbus_conn {
> struct kref kref;
> @@ -113,6 +115,8 @@ struct kdbus_conn {
>
> bool privileged:1;
> bool faked_meta:1;
> +
> + void *security;
> };
>
> struct kdbus_conn *kdbus_conn_ref(struct kdbus_conn *conn);
> diff --git a/ipc/kdbus/domain.c b/ipc/kdbus/domain.c
> index ac9f760..da9cdab 100644
> --- a/ipc/kdbus/domain.c
> +++ b/ipc/kdbus/domain.c
> @@ -20,6 +20,7 @@
> #include <linux/sizes.h>
> #include <linux/slab.h>
> #include <linux/uaccess.h>
> +#include <linux/security.h>
>
> #include "bus.h"
> #include "domain.h"
> @@ -73,6 +74,7 @@ static void kdbus_domain_free(struct kdbus_node
> *node)
> put_user_ns(domain->user_namespace);
> ida_destroy(&domain->user_ida);
> idr_destroy(&domain->user_idr);
> + security_kdbus_domain_free(domain);
> kfree(domain);
> }
>
> @@ -104,6 +106,10 @@ struct kdbus_domain *kdbus_domain_new(unsigned
> int access)
> idr_init(&d->user_idr);
> ida_init(&d->user_ida);
>
> + ret = security_kdbus_domain_alloc(d);
> + if (ret)
> + return ERR_PTR(-EPERM);
> +
> /* Pin user namespace so we can guarantee domain-unique bus
> * names. */
> d->user_namespace = get_user_ns(current_user_ns());
>
> @@ -116,6 +122,7 @@ struct kdbus_domain *kdbus_domain_new(unsigned
> int access)
> exit_unref:
> kdbus_node_deactivate(&d->node);
> kdbus_node_unref(&d->node);
> + security_kdbus_domain_free(d);
> return ERR_PTR(ret);
> }
>
> @@ -264,7 +271,7 @@ static void __kdbus_user_free(struct kref *kref)
> if (uid_valid(user->uid))
> idr_remove(&user->domain->user_idr, __kuid_val(user
> ->uid));
> mutex_unlock(&user->domain->lock);
> -
> + security_kdbus_domain_free(user->domain);
> kdbus_domain_unref(user->domain);
> kfree(user);
> }
> diff --git a/ipc/kdbus/domain.h b/ipc/kdbus/domain.h
> index 447a2bd..3db06d8 100644
> --- a/ipc/kdbus/domain.h
> +++ b/ipc/kdbus/domain.h
> @@ -31,6 +31,7 @@
> * @user_ida: Set of all users to compute small indices
> * @user_namespace: User namespace, pinned at creation time
> * @dentry: Root dentry of VFS mount (don't use outside
> of kdbusfs)
> + * @security: LSM security blob
> */
> struct kdbus_domain {
> struct kdbus_node node;
> @@ -40,6 +41,7 @@ struct kdbus_domain {
> struct ida user_ida;
> struct user_namespace *user_namespace;
> struct dentry *dentry;
> + void *security;
> };
>
> /**
> diff --git a/ipc/kdbus/endpoint.c b/ipc/kdbus/endpoint.c
> index 9a95a5e..380228f 100644
> --- a/ipc/kdbus/endpoint.c
> +++ b/ipc/kdbus/endpoint.c
> @@ -21,6 +21,7 @@
> #include <linux/slab.h>
> #include <linux/uaccess.h>
> #include <linux/uio.h>
> +#include <linux/security.h>
>
> #include "bus.h"
> #include "connection.h"
> @@ -122,6 +123,12 @@ struct kdbus_ep *kdbus_ep_new(struct kdbus_bus
> *bus, const char *name,
> kdbus_policy_db_init(&e->policy_db);
> e->bus = kdbus_bus_ref(bus);
>
> + ret = security_kdbus_ep_create(bus);
> + if (ret) {
> + ret = -EPERM;
> + goto exit_unref;
> + }
> +
> ret = kdbus_node_link(&e->node, &bus->node, name);
> if (ret < 0)
> goto exit_unref;
> @@ -265,6 +272,10 @@ int kdbus_cmd_ep_update(struct kdbus_ep *ep,
> void __user *argp)
> .argc = ARRAY_SIZE(argv),
> };
>
> + ret = security_kdbus_ep_setpolicy(ep->bus);
> + if (ret)
> + return -EPERM;
> +
> ret = kdbus_args_parse(&args, argp, &cmd);
> if (ret != 0)
> return ret;
> diff --git a/ipc/kdbus/names.c b/ipc/kdbus/names.c
> index d77ee08..dd20bea 100644
> --- a/ipc/kdbus/names.c
> +++ b/ipc/kdbus/names.c
> @@ -24,6 +24,7 @@
> #include <linux/slab.h>
> #include <linux/uaccess.h>
> #include <linux/uio.h>
> +#include <linux/security.h>
>
> #include "bus.h"
> #include "connection.h"
> @@ -503,6 +504,12 @@ int kdbus_cmd_name_acquire(struct kdbus_conn
> *conn, void __user *argp)
> goto exit;
> }
>
> + ret = security_kdbus_name_acquire(conn, item_name);
> + if (ret) {
> + ret = -EPERM;
> + goto exit;
> + }
> +
> /*
> * Do atomic_inc_return here to reserve our slot, then
> decrement
> * it before returning.
> @@ -724,6 +731,10 @@ int kdbus_cmd_list(struct kdbus_conn *conn, void
> __user *argp)
> if (ret != 0)
> return ret;
>
> + ret = security_kdbus_name_list(conn->ep->bus);
> + if (ret)
> + return -EPERM;
> +
> /* lock order: domain -> bus -> ep -> names -> conn */
> down_read(®->rwlock);
> down_read(&conn->ep->bus->conn_rwlock);
> diff --git a/ipc/kdbus/queue.c b/ipc/kdbus/queue.c
> index 25bb3ad..9872fb4 100644
> --- a/ipc/kdbus/queue.c
> +++ b/ipc/kdbus/queue.c
> @@ -28,6 +28,7 @@
> #include <linux/slab.h>
> #include <linux/syscalls.h>
> #include <linux/uio.h>
> +#include <linux/security.h>
>
> #include "util.h"
> #include "domain.h"
> @@ -514,12 +515,17 @@ int kdbus_queue_entry_install(struct
> kdbus_queue_entry *entry,
>
> for (i = 0; i < res->fds_count; i++) {
> if (install_fds) {
> - fds[i] =
> get_unused_fd_flags(O_CLOEXEC);
> - if (fds[i] >= 0)
> - fd_install(fds[i],
> - get_file(res
> ->fds[i]));
> - else
> + if (security_file_receive(res
> ->fds[i])) {
> + fds[i] = -1;
> incomplete_fds = true;
> + } else {
> + fds[i] =
> get_unused_fd_flags(O_CLOEXEC);
> + if (fds[i] >= 0)
> + fd_install(fds[i],
> + get_file(res
> ->fds[i]));
> + else
> + incomplete_fds =
> true;
> + }
> } else {
> fds[i] = -1;
> }
> @@ -557,13 +563,17 @@ int kdbus_queue_entry_install(struct
> kdbus_queue_entry *entry,
> m.fd = -1;
>
> if (install_fds) {
> - m.fd = get_unused_fd_flags(O_CLOEXEC);
> - if (m.fd < 0) {
> - m.fd = -1;
> + if (security_file_receive(d->memfd.file)) {
> incomplete_fds = true;
> } else {
> - fd_install(m.fd,
> - get_file(d->memfd.file));
> + m.fd =
> get_unused_fd_flags(O_CLOEXEC);
> + if (m.fd < 0) {
> + m.fd = -1;
> + incomplete_fds = true;
> + } else {
> + fd_install(m.fd,
> + get_file(d
> ->memfd.file));
> + }
> }
> }
>
--
Lukasz Pawelczyk
Samsung R&D Institute Poland
Samsung Electronics
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox