diff options
author | Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com> | 2020-04-19 08:35:29 +0200 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2020-04-26 14:00:50 +0100 |
commit | 90164f0f3d713de70842317869343dd4a3ef5140 (patch) | |
tree | dfd8a4b43d3280e3c79acf8b5eb3d556c2395547 /scripts | |
parent | 3e9cdd878887d0e59754447f313c39d142b71971 (diff) | |
download | poky-90164f0f3d713de70842317869343dd4a3ef5140.tar.gz |
wic: Fix permissions when using exclude or include path
When parameters include_path or exclude_path are passed to the rootfs
plugin, it will copy the partition content into a folder and make all
the modifications there.
This is done using copyhardlinktree(), which does not take into
consideration the content of the pseudo folder, which contains the
information about the right permissions and ownership of the folders.
This results in a rootfs owned by the user that is running the wic
command (usually UID 1000), which makes some rootfs unbootable.
This bug can be easily triggerd with the following .wks
part / --source rootfs --fstype=ext4 --exclude-path=home
And this sequence:
$ wic create test-permissions -e core-image-minimal -o test/
$ sudo mount test/test-permissions-202004080823-sda.direct.p1 /mnt
$ ls -la /mnt/etc/shadow
To fix this we copy the content of the pseudo folders to the new folder
and modify the pseudo database using the "pseudo -B" command.
If the rootfs is not a rootfs generated by bitbake a warning is shown
making the user aware that the permissions on the target might not match
what he expects.
WARNING: /tmp/test/../pseudo folder does not exist. Usernames and permissions will be invalid
Cc: Paul Barker <pbarker@konsulko.com>
(From OE-Core rev: fd739c15cdba221d9d497d3402b7d929c0be2ca4)
Signed-off-by: Ricardo Ribalda Delgado <ricardo@ribalda.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/lib/wic/partition.py | 7 | ||||
-rw-r--r-- | scripts/lib/wic/plugins/source/rootfs.py | 37 |
2 files changed, 38 insertions, 6 deletions
diff --git a/scripts/lib/wic/partition.py b/scripts/lib/wic/partition.py index 2d95f78439..b02711be37 100644 --- a/scripts/lib/wic/partition.py +++ b/scripts/lib/wic/partition.py | |||
@@ -190,7 +190,7 @@ class Partition(): | |||
190 | (self.mountpoint, self.size, self.fixed_size)) | 190 | (self.mountpoint, self.size, self.fixed_size)) |
191 | 191 | ||
192 | def prepare_rootfs(self, cr_workdir, oe_builddir, rootfs_dir, | 192 | def prepare_rootfs(self, cr_workdir, oe_builddir, rootfs_dir, |
193 | native_sysroot, real_rootfs = True): | 193 | native_sysroot, real_rootfs = True, pseudo_dir = None): |
194 | """ | 194 | """ |
195 | Prepare content for a rootfs partition i.e. create a partition | 195 | Prepare content for a rootfs partition i.e. create a partition |
196 | and fill it from a /rootfs dir. | 196 | and fill it from a /rootfs dir. |
@@ -198,8 +198,9 @@ class Partition(): | |||
198 | Currently handles ext2/3/4, btrfs, vfat and squashfs. | 198 | Currently handles ext2/3/4, btrfs, vfat and squashfs. |
199 | """ | 199 | """ |
200 | p_prefix = os.environ.get("PSEUDO_PREFIX", "%s/usr" % native_sysroot) | 200 | p_prefix = os.environ.get("PSEUDO_PREFIX", "%s/usr" % native_sysroot) |
201 | p_localstatedir = os.environ.get("PSEUDO_LOCALSTATEDIR", | 201 | if (pseudo_dir == None): |
202 | "%s/../pseudo" % rootfs_dir) | 202 | pseudo_dir = "%s/../pseudo" % rootfs_dir |
203 | p_localstatedir = os.environ.get("PSEUDO_LOCALSTATEDIR", pseudo_dir) | ||
203 | p_passwd = os.environ.get("PSEUDO_PASSWD", rootfs_dir) | 204 | p_passwd = os.environ.get("PSEUDO_PASSWD", rootfs_dir) |
204 | p_nosymlinkexp = os.environ.get("PSEUDO_NOSYMLINKEXP", "1") | 205 | p_nosymlinkexp = os.environ.get("PSEUDO_NOSYMLINKEXP", "1") |
205 | pseudo = "export PSEUDO_PREFIX=%s;" % p_prefix | 206 | pseudo = "export PSEUDO_PREFIX=%s;" % p_prefix |
diff --git a/scripts/lib/wic/plugins/source/rootfs.py b/scripts/lib/wic/plugins/source/rootfs.py index 705aeb5563..8b2a067385 100644 --- a/scripts/lib/wic/plugins/source/rootfs.py +++ b/scripts/lib/wic/plugins/source/rootfs.py | |||
@@ -20,7 +20,7 @@ from oe.path import copyhardlinktree | |||
20 | 20 | ||
21 | from wic import WicError | 21 | from wic import WicError |
22 | from wic.pluginbase import SourcePlugin | 22 | from wic.pluginbase import SourcePlugin |
23 | from wic.misc import get_bitbake_var | 23 | from wic.misc import get_bitbake_var, exec_native_cmd |
24 | 24 | ||
25 | logger = logging.getLogger('wic') | 25 | logger = logging.getLogger('wic') |
26 | 26 | ||
@@ -44,6 +44,15 @@ class RootfsPlugin(SourcePlugin): | |||
44 | 44 | ||
45 | return os.path.realpath(image_rootfs_dir) | 45 | return os.path.realpath(image_rootfs_dir) |
46 | 46 | ||
47 | @staticmethod | ||
48 | def __get_pseudo(native_sysroot, rootfs, pseudo_dir): | ||
49 | pseudo = "export PSEUDO_PREFIX=%s/usr;" % native_sysroot | ||
50 | pseudo += "export PSEUDO_LOCALSTATEDIR=%s;" % pseudo_dir | ||
51 | pseudo += "export PSEUDO_PASSWD=%s;" % rootfs | ||
52 | pseudo += "export PSEUDO_NOSYMLINKEXP=1;" | ||
53 | pseudo += "%s " % get_bitbake_var("FAKEROOTCMD") | ||
54 | return pseudo | ||
55 | |||
47 | @classmethod | 56 | @classmethod |
48 | def do_prepare_partition(cls, part, source_params, cr, cr_workdir, | 57 | def do_prepare_partition(cls, part, source_params, cr, cr_workdir, |
49 | oe_builddir, bootimg_dir, kernel_dir, | 58 | oe_builddir, bootimg_dir, kernel_dir, |
@@ -68,8 +77,14 @@ class RootfsPlugin(SourcePlugin): | |||
68 | "it is not a valid path, exiting" % part.rootfs_dir) | 77 | "it is not a valid path, exiting" % part.rootfs_dir) |
69 | 78 | ||
70 | part.rootfs_dir = cls.__get_rootfs_dir(rootfs_dir) | 79 | part.rootfs_dir = cls.__get_rootfs_dir(rootfs_dir) |
80 | pseudo_dir = os.path.join(part.rootfs_dir, "../pseudo") | ||
81 | if not os.path.lexists(pseudo_dir): | ||
82 | logger.warn("%s folder does not exist. " | ||
83 | "Usernames and permissions will be invalid " % pseudo_dir) | ||
84 | pseudo_dir = None | ||
71 | 85 | ||
72 | new_rootfs = None | 86 | new_rootfs = None |
87 | new_pseudo = None | ||
73 | # Handle excluded paths. | 88 | # Handle excluded paths. |
74 | if part.exclude_path or part.include_path: | 89 | if part.exclude_path or part.include_path: |
75 | # We need a new rootfs directory we can delete files from. Copy to | 90 | # We need a new rootfs directory we can delete files from. Copy to |
@@ -78,9 +93,24 @@ class RootfsPlugin(SourcePlugin): | |||
78 | 93 | ||
79 | if os.path.lexists(new_rootfs): | 94 | if os.path.lexists(new_rootfs): |
80 | shutil.rmtree(os.path.join(new_rootfs)) | 95 | shutil.rmtree(os.path.join(new_rootfs)) |
81 | |||
82 | copyhardlinktree(part.rootfs_dir, new_rootfs) | 96 | copyhardlinktree(part.rootfs_dir, new_rootfs) |
83 | 97 | ||
98 | # Convert the pseudo directory to its new location | ||
99 | if (pseudo_dir): | ||
100 | new_pseudo = os.path.realpath( | ||
101 | os.path.join(cr_workdir, "pseudo%d" % part.lineno)) | ||
102 | if os.path.lexists(new_pseudo): | ||
103 | shutil.rmtree(new_pseudo) | ||
104 | os.mkdir(new_pseudo) | ||
105 | shutil.copy(os.path.join(pseudo_dir, "files.db"), | ||
106 | os.path.join(new_pseudo, "files.db")) | ||
107 | |||
108 | pseudo_cmd = "%s -B -m %s -M %s" % (cls.__get_pseudo(native_sysroot, | ||
109 | new_rootfs, | ||
110 | new_pseudo), | ||
111 | part.rootfs_dir, new_rootfs) | ||
112 | exec_native_cmd(pseudo_cmd, native_sysroot) | ||
113 | |||
84 | for path in part.include_path or []: | 114 | for path in part.include_path or []: |
85 | copyhardlinktree(path, new_rootfs) | 115 | copyhardlinktree(path, new_rootfs) |
86 | 116 | ||
@@ -112,4 +142,5 @@ class RootfsPlugin(SourcePlugin): | |||
112 | shutil.rmtree(full_path) | 142 | shutil.rmtree(full_path) |
113 | 143 | ||
114 | part.prepare_rootfs(cr_workdir, oe_builddir, | 144 | part.prepare_rootfs(cr_workdir, oe_builddir, |
115 | new_rootfs or part.rootfs_dir, native_sysroot) | 145 | new_rootfs or part.rootfs_dir, native_sysroot, |
146 | pseudo_dir = new_pseudo or pseudo_dir) | ||