summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorRicardo Ribalda Delgado <ricardo.ribalda@gmail.com>2020-04-19 08:35:29 +0200
committerRichard Purdie <richard.purdie@linuxfoundation.org>2021-02-03 14:13:53 +0000
commit3b06f25a804a8ac4b0a0219649088da22e7a2641 (patch)
treebf29d5aa4d6d095cc1dcfb9a9cac8f58991d9e50 /scripts
parent4e7c21160b74d0e63d90cae535ff73579cc4fa8b (diff)
downloadpoky-3b06f25a804a8ac4b0a0219649088da22e7a2641.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: 9ea7162e9efc29beacdf1c8f4ec98f4895dd5df6) Signed-off-by: Ricardo Ribalda Delgado <ricardo@ribalda.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> (cherry picked from commit fd739c15cdba221d9d497d3402b7d929c0be2ca4) Signed-off-by: Steve Sakoman <steve@sakoman.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'scripts')
-rw-r--r--scripts/lib/wic/partition.py7
-rw-r--r--scripts/lib/wic/plugins/source/rootfs.py37
2 files changed, 38 insertions, 6 deletions
diff --git a/scripts/lib/wic/partition.py b/scripts/lib/wic/partition.py
index 3490b4e75d..6e87770f3a 100644
--- a/scripts/lib/wic/partition.py
+++ b/scripts/lib/wic/partition.py
@@ -191,7 +191,7 @@ class Partition():
191 (self.mountpoint, self.size, self.fixed_size)) 191 (self.mountpoint, self.size, self.fixed_size))
192 192
193 def prepare_rootfs(self, cr_workdir, oe_builddir, rootfs_dir, 193 def prepare_rootfs(self, cr_workdir, oe_builddir, rootfs_dir,
194 native_sysroot, real_rootfs = True): 194 native_sysroot, real_rootfs = True, pseudo_dir = None):
195 """ 195 """
196 Prepare content for a rootfs partition i.e. create a partition 196 Prepare content for a rootfs partition i.e. create a partition
197 and fill it from a /rootfs dir. 197 and fill it from a /rootfs dir.
@@ -199,8 +199,9 @@ class Partition():
199 Currently handles ext2/3/4, btrfs, vfat and squashfs. 199 Currently handles ext2/3/4, btrfs, vfat and squashfs.
200 """ 200 """
201 p_prefix = os.environ.get("PSEUDO_PREFIX", "%s/usr" % native_sysroot) 201 p_prefix = os.environ.get("PSEUDO_PREFIX", "%s/usr" % native_sysroot)
202 p_localstatedir = os.environ.get("PSEUDO_LOCALSTATEDIR", 202 if (pseudo_dir == None):
203 "%s/../pseudo" % rootfs_dir) 203 pseudo_dir = "%s/../pseudo" % rootfs_dir
204 p_localstatedir = os.environ.get("PSEUDO_LOCALSTATEDIR", pseudo_dir)
204 p_passwd = os.environ.get("PSEUDO_PASSWD", rootfs_dir) 205 p_passwd = os.environ.get("PSEUDO_PASSWD", rootfs_dir)
205 p_nosymlinkexp = os.environ.get("PSEUDO_NOSYMLINKEXP", "1") 206 p_nosymlinkexp = os.environ.get("PSEUDO_NOSYMLINKEXP", "1")
206 pseudo = "export PSEUDO_PREFIX=%s;" % p_prefix 207 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
21from wic import WicError 21from wic import WicError
22from wic.pluginbase import SourcePlugin 22from wic.pluginbase import SourcePlugin
23from wic.misc import get_bitbake_var 23from wic.misc import get_bitbake_var, exec_native_cmd
24 24
25logger = logging.getLogger('wic') 25logger = 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)