Discussion:
[yocto] [meta-oe] Set linux capabilities on binary on a recipe in meta-oe layer
Markus W
2018-11-07 10:32:36 UTC
Permalink
Hi!

*Background:*
In my raspberry project I am developing a nodejs app that needs access to
bluetooth/ble device. I want to run the node application as non root user
for security reasons. In order to get access from within the app, the node
binary need to have the following capability *cap_net_raw+eip *set. I am
using the nodejs recipe from meta-oe and added it in my local.conf:

IMAGE_INSTALL_append = " *nodejs* i2c-tools bluez5 kernel-image
kernel-devicetree"

*Question:*
Where should I apply the following command? *setcap cap_net_raw+eip
/usr/bin/node*

What are my options? Can I create a recipe in a different package that will
apply the above command on the meta-oe package for the nodejs recipe?

I have been following this thread (
https://lists.yoctoproject.org/pipermail/yocto/2016-June/030811.html), but
the node binaries and my node-app are in different layers and packages.

Any advice how to do this is much appreciated?

Regards,
Markus
Markus W
2018-11-08 08:56:23 UTC
Permalink
I have tested to set capabilities on the node binary within a custom recipe
(custom layer) but that failed.

pkg_postinst_${PN} () {
setcap cap_net_raw+eip $D${bindir}/node
}
PACKAGE_WRITE_DEPS = "libcap-native"
RDEPENDS_${PN} = "libcap"

The error message:

ERROR: core-image-full-cmdline-1.0-r0 do_rootfs: [log_check]
core-image-full-cmdline: found 1 error message in the logfile:
[log_check] Failed to set capabilities on file
`/home/ubuntu/yocto-sumo/build/tmp/work/raspberrypi3-poky-linux-gnueabi/core-image-full-cmdline/1.0-r0/rootfs/usr/bin/node'
(No such file or directory)

When I check the node binary is there in the rootfs directory. It seems
that when the the pkg_postinst function is executed the node binary is not
there.

What am I missing? Any answer is much appreciated!

Regards,
Markus
Post by Markus W
Hi!
In my raspberry project I am developing a nodejs app that needs access to
bluetooth/ble device. I want to run the node application as non root user
for security reasons. In order to get access from within the app, the node
binary need to have the following capability cap_net_raw+eip set. I am
IMAGE_INSTALL_append = " nodejs i2c-tools bluez5 kernel-image
kernel-devicetree"
Where should I apply the following command? setcap cap_net_raw+eip
/usr/bin/node
What are my options? Can I create a recipe in a different package that
will apply the above command on the meta-oe package for the nodejs recipe?
I have been following this thread (
https://lists.yoctoproject.org/pipermail/yocto/2016-June/030811.html),
but the node binaries and my node-app are in different layers and packages.
Any advice how to do this is much appreciated?
Regards,
Markus
Piotr Tworek
2018-11-08 21:53:20 UTC
Permalink
Hi Markus,

Have you tried doing it in the postinst step executed on your target? Try:

pkg_postinst_ontarget_${PN} () {
setcap cap_net_raw+eip $D${bindir}/node
}

RDEPENDS_${PN} += "libcap-bin"

/ptw
Post by Markus W
I have tested to set capabilities on the node binary within a custom recipe
(custom layer) but that failed.
pkg_postinst_${PN} () {
setcap cap_net_raw+eip $D${bindir}/node
}
PACKAGE_WRITE_DEPS = "libcap-native"
RDEPENDS_${PN} = "libcap"
ERROR: core-image-full-cmdline-1.0-r0 do_rootfs: [log_check]
[log_check] Failed to set capabilities on file
`/home/ubuntu/yocto-sumo/build/tmp/work/raspberrypi3-poky-linux-gnueabi/core
-image-full-cmdline/1.0-r0/rootfs/usr/bin/node' (No such file or directory)
When I check the node binary is there in the rootfs directory. It seems
that when the the pkg_postinst function is executed the node binary is not
there.
What am I missing? Any answer is much appreciated!
Regards,
Markus
Post by Markus W
Hi!
In my raspberry project I am developing a nodejs app that needs access to
bluetooth/ble device. I want to run the node application as non root user
for security reasons. In order to get access from within the app, the node
binary need to have the following capability cap_net_raw+eip set. I am
IMAGE_INSTALL_append = " nodejs i2c-tools bluez5 kernel-image
kernel-devicetree"
Where should I apply the following command? setcap cap_net_raw+eip
/usr/bin/node
What are my options? Can I create a recipe in a different package that
will apply the above command on the meta-oe package for the nodejs recipe?
I have been following this thread (
https://lists.yoctoproject.org/pipermail/yocto/2016-June/030811.html),
but the node binaries and my node-app are in different layers and packages.
Any advice how to do this is much appreciated?
Regards,
Markus
--
Markus W
2018-11-09 10:16:11 UTC
Permalink
Thanks Piotr, that worked!

How can this be achieved when the rootfs is created and not on first boot?
I would like not to ship libcap binaries with the target in production.

/Markus
Post by Piotr Tworek
Hi Markus,
pkg_postinst_ontarget_${PN} () {
setcap cap_net_raw+eip $D${bindir}/node
}
RDEPENDS_${PN} += "libcap-bin"
/ptw
Post by Markus W
I have tested to set capabilities on the node binary within a custom
recipe
Post by Markus W
(custom layer) but that failed.
pkg_postinst_${PN} () {
setcap cap_net_raw+eip $D${bindir}/node
}
PACKAGE_WRITE_DEPS = "libcap-native"
RDEPENDS_${PN} = "libcap"
ERROR: core-image-full-cmdline-1.0-r0 do_rootfs: [log_check]
[log_check] Failed to set capabilities on file
`/home/ubuntu/yocto-sumo/build/tmp/work/raspberrypi3-poky-linux-gnueabi/core
Post by Markus W
-image-full-cmdline/1.0-r0/rootfs/usr/bin/node' (No such file or
directory)
Post by Markus W
When I check the node binary is there in the rootfs directory. It seems
that when the the pkg_postinst function is executed the node binary is
not
Post by Markus W
there.
What am I missing? Any answer is much appreciated!
Regards,
Markus
Post by Markus W
Hi!
In my raspberry project I am developing a nodejs app that needs access
to
Post by Markus W
Post by Markus W
bluetooth/ble device. I want to run the node application as non root
user
Post by Markus W
Post by Markus W
for security reasons. In order to get access from within the app, the
node
Post by Markus W
Post by Markus W
binary need to have the following capability cap_net_raw+eip set. I am
IMAGE_INSTALL_append = " nodejs i2c-tools bluez5 kernel-image
kernel-devicetree"
Where should I apply the following command? setcap cap_net_raw+eip
/usr/bin/node
What are my options? Can I create a recipe in a different package that
will apply the above command on the meta-oe package for the nodejs
recipe?
Post by Markus W
Post by Markus W
I have been following this thread (
https://lists.yoctoproject.org/pipermail/yocto/2016-June/030811.html),
but the node binaries and my node-app are in different layers and packages.
Any advice how to do this is much appreciated?
Regards,
Markus
Uwe Geuder
2018-11-09 14:35:10 UTC
Permalink
Hi!
...
Post by Markus W
Post by Piotr Tworek
pkg_postinst_ontarget_${PN} () {
setcap cap_net_raw+eip $D${bindir}/node
}
...
Post by Markus W
How can this be achieved when the rootfs is created and not on first
boot? I would like not to ship libcap binaries with the target in
production.
Ideally I would do it "locally" in do_install of the node recipe (you can
append extra statements to the task in your own .bbappend in your own
layer, don't edit existing recipes)

That of course requires that the package manager preserves the
capabilites. I have no experience which package manager would do
or not do that.

"Globally" you can do it by appending a new function to ROOTFS_POSTPROCESS_COMMAND

https://www.yoctoproject.org/docs/2.5.1/mega-manual/mega-manual.html#var-
ROOTFS_POSTPROCESS_COMMAND

This is done in your image recipe.

Regards,

Uwe Geuder
Neuro Event Labs Oy
Tampere, Finland
***@neuroeventlabs.com (Bot check: fix one obvious typo)
--
Markus W
2018-11-12 13:09:10 UTC
Permalink
Thanks Uwe!

I tried the global approach by adding the following to my local.conf file:

ROOTFS_POSTPROCESS_COMMAND += "my_setcap_function"

my_setcap_function() {
setcap cap_net_raw+eip ${IMAGE_ROOTFS}/usr/bin/node
}

But got the following warning:
WARNING: core-image-full-cmdline-1.0-r0 do_rootfs: Function
my_setcap_function doesn't exist

I have tried to add the function into a recipe but this doesn't work
either. Where should the function be defined?

Regards,
Markus
Post by Uwe Geuder
Hi!
...
Post by Markus W
Post by Piotr Tworek
pkg_postinst_ontarget_${PN} () {
setcap cap_net_raw+eip $D${bindir}/node
}
...
Post by Markus W
How can this be achieved when the rootfs is created and not on first
boot? I would like not to ship libcap binaries with the target in
production.
Ideally I would do it "locally" in do_install of the node recipe (you can
append extra statements to the task in your own .bbappend in your own
layer, don't edit existing recipes)
That of course requires that the package manager preserves the
capabilites. I have no experience which package manager would do
or not do that.
"Globally" you can do it by appending a new function to
ROOTFS_POSTPROCESS_COMMAND
https://www.yoctoproject.org/docs/2.5.1/mega-manual/mega-manual.html#var-
ROOTFS_POSTPROCESS_COMMAND
This is done in your image recipe.
Regards,
Uwe Geuder
Neuro Event Labs Oy
Tampere, Finland
--
_______________________________________________
yocto mailing list
https://lists.yoctoproject.org/listinfo/yocto
Mike Looijmans
2018-11-12 13:47:06 UTC
Permalink
Sometimes the problem is that parts of the underscored function name are seen
as overrides, so you should try using "mysetcapfunction" instead as a name.

Also, there's a semicolon missing:
ROOTFS_POSTPROCESS_COMMAND += "my_setcap_function;"
Post by Markus W
Thanks Uwe!
ROOTFS_POSTPROCESS_COMMAND += "my_setcap_function"
my_setcap_function() {
    setcap cap_net_raw+eip ${IMAGE_ROOTFS}/usr/bin/node
}
WARNING: core-image-full-cmdline-1.0-r0 do_rootfs: Function my_setcap_function
doesn't exist
I have tried to add the function into a recipe but this doesn't work either.
Where should the function be defined?
Regards,
Markus
Hi!
On Fri, Nov 9, 2018 at 12:16 PM Markus W markus4dev-at-gmail.com
...
Post by Markus W
Post by Piotr Tworek
pkg_postinst_ontarget_${PN} () {
    setcap cap_net_raw+eip $D${bindir}/node
}
...
Post by Markus W
How can this be achieved when the rootfs is created and not on first
boot? I would like not to ship libcap binaries with the target in
production.
Ideally I would do it "locally" in do_install of the node recipe (you can
append extra statements to the task in your own .bbappend in your own
layer, don't edit existing recipes)
That of course requires that the package manager preserves the
capabilites. I have no experience which package manager would do
or not do that.
"Globally" you can do it by appending a new function to
ROOTFS_POSTPROCESS_COMMAND
https://www.yoctoproject.org/docs/2.5.1/mega-manual/mega-manual.html#var-
ROOTFS_POSTPROCESS_COMMAND
This is done in your image recipe.
Regards,
Uwe Geuder
Neuro Event Labs Oy
Tampere, Finland
check: fix one obvious typo)
--
_______________________________________________
yocto mailing list
https://lists.yoctoproject.org/listinfo/yocto
--
Uwe Geuder
2018-11-13 13:43:31 UTC
Permalink
Post by Markus W
Thanks Uwe!
ROOTFS_POSTPROCESS_COMMAND += "my_setcap_function"
my_setcap_function() {
setcap cap_net_raw+eip ${IMAGE_ROOTFS}/usr/bin/node
}
WARNING: core-image-full-cmdline-1.0-r0 do_rootfs: Function my_setcap_function doesn't exist
I have tried to add the function into a recipe but this doesn't work either. Where should the function be defined?
Post by Uwe Geuder
This is done in your image recipe.
At least this is where I do it and it works for me.

My use of "global" was probably not so lucky, I did not mean bitbake
configuration. I just meant that it is done in the image recipe and not
in the node recipe.

You can always use "bitbake -e" to check variable and recipe function
definitions if you are wondering what is really going on. I often
understand problems when looking at the listing produced by this
command. In your case "bitbake -e core-image-full-cmdline"

There are also other functions in the value of ROOTFS_POSTPROCESS_COMMAND so as
Post by Markus W
ROOTFS_POSTPROCESS_COMMAND += "my_setcap_function;"
The final value of ROOTFS_POSTPROCESS_COMMAND as shown by "bitbake -e"
should be list of function names separated by semicolons.

My previous link was broken, hopefully this time it survives intact...

https://www.yoctoproject.org/docs/2.5.1/mega-manual/mega-manual.html#var-ROOTFS_POSTPROCESS_COMMAND
Post by Markus W
Sometimes the problem is that parts of the underscored function name are seen
as overrides, so you should try using "mysetcapfunction" instead as a name.
That has never happened to me and I use underscores in my function
names. But I could imagine that it's possible in some case. I would
strongly expect to see such issue in the output of "bitbake -e", too.


Regards,

Uwe Geuder
Neuro Event Labs Oy
Tampere, Finland
***@neuroeventlabs.com (Bot check: fix one obvious typo)
--

Loading...