[libcamera-devel] [PATCH 2/3] test: log/process: check CAP_SYS_ADMIN in test init
You-Sheng Yang
vicamo.yang at canonical.com
Mon Jul 27 17:50:39 CEST 2020
On 2020-07-27 07:47, Laurent Pinchart wrote:
> Hi again,
>
> On Mon, Jul 27, 2020 at 02:42:11AM +0300, Laurent Pinchart wrote:
>> Hi You-Sheng,
>>
>> Thank you for the patch.
>>
>> On Sat, Jul 25, 2020 at 08:24:41PM +0800, You-Sheng Yang wrote:
>>> While these tests may be executed as normal user at build time,
>>> unshare() call will fail and so are tests log_process and process_test.
>>> This change checks if one is granted with necessary capabilities so that
>>> we don't fail the build unexpectedly.
>>>
>>> Signed-off-by: You-Sheng Yang <vicamo.yang at canonical.com>
>>> ---
>>> test/log/log_process.cpp | 20 ++++++++++++++++++++
>>> test/log/meson.build | 2 +-
>>> test/meson.build | 2 ++
>>> test/process/meson.build | 2 +-
>>> test/process/process_test.cpp | 23 +++++++++++++++++++++++
>>> 5 files changed, 47 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/test/log/log_process.cpp b/test/log/log_process.cpp
>>> index d46d5e3..876da22 100644
>>> --- a/test/log/log_process.cpp
>>> +++ b/test/log/log_process.cpp
>>> @@ -9,6 +9,7 @@
>>> #include <iostream>
>>> #include <random>
>>> #include <string.h>
>>> +#include <sys/capability.h>
>>> #include <sys/stat.h>
>>> #include <sys/types.h>
>>> #include <unistd.h>
>>> @@ -55,6 +56,25 @@ class LogProcessTest : public Test
>>> protected:
>>> int init()
>>> {
>>> + int ret = TestPass;
>>> +
>>> + cap_t caps = cap_get_proc();
>>> + if (caps == NULL) {
>>> + cerr << "failed to check process capabilities" << endl;
>>> + return TestFail;
>>> + }
>>> +
>>> + /* Check required permissions: CAP_SYS_ADMIN: unshare */
>>> + cap_flag_value_t fv;
>>> + if ((cap_get_flag(caps, CAP_SYS_ADMIN, CAP_EFFECTIVE, &fv) < 0) || (fv != CAP_SET)) {
>>> + cerr << "skip due to insufficient capability" << endl;
>>> + ret = TestSkip;
>>> + }
>>
>> Would it make sense to add this as a helper function to the base Test
>> class ?
Will do. But probably after having a conclusion below.
>>> +
>>> + cap_free(caps);
>>> + if (ret != TestPass)
>>> + return ret;
>>> +
>>> random_device random;
>>> num_ = random();
>>> logPath_ = "/tmp/libcamera.worker.test." +
>>> diff --git a/test/log/meson.build b/test/log/meson.build
>>> index 8cd664e..000f980 100644
>>> --- a/test/log/meson.build
>>> +++ b/test/log/meson.build
>>> @@ -7,7 +7,7 @@ log_test = [
>>>
>>> foreach t : log_test
>>> exe = executable(t[0], t[1],
>>> - dependencies : libcamera_dep,
>>> + dependencies : [libcamera_dep, libcap],
>>> link_with : test_libraries,
>>> include_directories : test_includes_internal)
>>>
>>> diff --git a/test/meson.build b/test/meson.build
>>> index f41d6e7..b4db328 100644
>>> --- a/test/meson.build
>>> +++ b/test/meson.build
>>> @@ -1,5 +1,7 @@
>>> # SPDX-License-Identifier: CC0-1.0
>>>
>>> +libcap = dependency('libcap', required : true)
>>
>> 'true' is the default value for 'required', you can omit it. However,
>> I'd like to keep the dependency optional, as we try to also support
>> resource-constrainted embedded systems (based on musl or uclibc for
>> instance, and/or without udev).
>>
>> I have an idea how to do that, I'll try to submit a patch shortly.
>
> Actually, thinking about it some more, would it make sense to instead
> condition the call to unshare() to CAP_SYS_ADMIN in the
> Process:isolate() class ? Or turn it into a non-fatal error ?
It's about API design, so your opinions matter most.
I didn't have much idea about the rational behind the unshare() call
inside libcamera::Process, but I'm really suspect the necessity of it as
part of a, at least looks like, generic API. It implicitly adds a
constrain that any process tries to create a subprocess in libcamera
using libcamera::Process, its child process must be either executed by
root or have CAP_SYS_ADMIN. This doesn't really sound a good idea for
me, especially when I believe one should really build a multimedia
library to run as a normal user as possible.
Anyway, the only user of this API in libcamera is ipa_proxy_linux, you
could have put unshare() into ipa_proxy_linux itself. This way you could
install some selinux/apparmor rules to grant such permission to this
executable explicitly. But again, is that really necessary? Is
ipa_proxy_linux really has to own its own network and uid namespace?
> Could you maybe elaborate a little bit on the failure this patch is
> trying to solve ? I haven't seen any such failure, how can they be
> reproduced ?
Please see https://gitlab.com/vicamo/libcamera/-/jobs/650449281
21/55 libcamera:process / process_test FAIL
0.01s (exit status 255 or signal 127 SIGinvalid)
--- command ---
10:26:15
/builds/vicamo/libcamera/debian/output/libcamera-0~git20200722+d929555/obj-x86_64-linux-gnu/test/process/process_test
--- stderr ---
I was trying to fix debian packaging and to have a daily build based on
master tip.
You-Sheng Yang
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <https://lists.libcamera.org/pipermail/libcamera-devel/attachments/20200727/3cee0c7f/attachment.sig>
More information about the libcamera-devel
mailing list