summaryrefslogtreecommitdiffstats
path: root/meta
diff options
context:
space:
mode:
authorTrent Piepho <trent.piepho@igorinstitute.com>2026-01-19 17:17:45 -0800
committerPaul Barker <paul@pbarker.dev>2026-03-25 17:34:13 +0000
commit5cc40d3e64a8c0c79e7492a738858224474fd416 (patch)
tree2fa26b8cc9fcfa1c5663cc47b88ea704ebfa5d6a /meta
parent26475426bdb4f3c856b7a8b21367ca3b4a1d5aad (diff)
downloadpoky-5cc40d3e64a8c0c79e7492a738858224474fd416.tar.gz
systemd-systemctl: Fix instance name parsing with escapes or periods
Fixes [YOCTO #16130] When extracting the instance name from a template instances such as 'example@host.domain.com.service', the systemctl replacement script will split the instance on the first period, producing an instance argument of 'host' and a template of 'example@.domain.com.service'. This is incorrect, as systemd will split on the last period, producing an instance argument of 'host.domain.com' and a template of 'example@.service'. When constructing the template name, the script will also pass the string as is to re.sub(), which will try to process any backslash escapes in the string. These are legal in systemd unit names and should be preserved. They also are not valid Python escape sequences. Use re.escape() to preserve anything in the unit name that might be considered a regex exscape. (From OE-Core rev: 0514c317523330f75937123c45bb0528e4830f61) Signed-off-by: Trent Piepho <trent.piepho@igorinstitute.com> Signed-off-by: Yoann Congal <yoann.congal@smile.fr> Signed-off-by: Paul Barker <paul@pbarker.dev>
Diffstat (limited to 'meta')
-rwxr-xr-xmeta/recipes-core/systemd/systemd-systemctl/systemctl7
1 files changed, 4 insertions, 3 deletions
diff --git a/meta/recipes-core/systemd/systemd-systemctl/systemctl b/meta/recipes-core/systemd/systemd-systemctl/systemctl
index 2229bc7b6d..b9e04a9070 100755
--- a/meta/recipes-core/systemd/systemd-systemctl/systemctl
+++ b/meta/recipes-core/systemd/systemd-systemctl/systemctl
@@ -202,7 +202,8 @@ class SystemdUnit():
202 try: 202 try:
203 for dependent in config.get('Install', prop): 203 for dependent in config.get('Install', prop):
204 # expand any %i to instance (ignoring escape sequence %%) 204 # expand any %i to instance (ignoring escape sequence %%)
205 dependent = re.sub("([^%](%%)*)%i", "\\g<1>{}".format(instance), dependent) 205 if instance is not None:
206 dependent = re.sub("([^%](%%)*)%i", "\\g<1>{}".format(re.escape(instance)), dependent)
206 wants = systemdir / "{}.{}".format(dependent, dirstem) / service 207 wants = systemdir / "{}.{}".format(dependent, dirstem) / service
207 add_link(wants, target) 208 add_link(wants, target)
208 209
@@ -212,13 +213,13 @@ class SystemdUnit():
212 def enable(self, units_enabled=[]): 213 def enable(self, units_enabled=[]):
213 # if we're enabling an instance, first extract the actual instance 214 # if we're enabling an instance, first extract the actual instance
214 # then figure out what the template unit is 215 # then figure out what the template unit is
215 template = re.match(r"[^@]+@(?P<instance>[^\.]*)\.", self.unit) 216 template = re.match(r"[^@]+@(?P<instance>.*)\.", self.unit)
216 instance_unit_name = None 217 instance_unit_name = None
217 if template: 218 if template:
218 instance = template.group('instance') 219 instance = template.group('instance')
219 if instance != "": 220 if instance != "":
220 instance_unit_name = self.unit 221 instance_unit_name = self.unit
221 unit = re.sub(r"@[^\.]*\.", "@.", self.unit, 1) 222 unit = re.sub(r"@{}\.".format(re.escape(instance)), "@.", self.unit, 1)
222 else: 223 else:
223 instance = None 224 instance = None
224 unit = self.unit 225 unit = self.unit