core: Try to prevent infinite recursive template instantiation

To prevent situations like in #17602 from happening, let's drop
direct recursive template dependencies. These will almost certainly
lead to infinite recursion so let's drop them immediately to avoid
instantiating potentially thousands of irrelevant units.

Example of a template that would lead to infinite recursion which
is caught by this check:

notify@.service:

```
[Unit]
Wants=notify@%n.service
```
This commit is contained in:
Daan De Meyer
2021-10-28 11:42:21 +01:00
parent 11e9347bc6
commit 88022148c4
7 changed files with 210 additions and 2 deletions
+24
View File
@@ -8,6 +8,7 @@
#include "alloc-util.h"
#include "glob-util.h"
#include "hexdecoct.h"
#include "memory-util.h"
#include "path-util.h"
#include "special.h"
#include "string-util.h"
@@ -797,3 +798,26 @@ bool slice_name_is_valid(const char *name) {
return true;
}
bool unit_name_prefix_equal(const char *a, const char *b) {
const char *p, *q;
assert(a);
assert(b);
if (!unit_name_is_valid(a, UNIT_NAME_ANY) || !unit_name_is_valid(b, UNIT_NAME_ANY))
return false;
p = strchr(a, '@');
if (!p)
p = strrchr(a, '.');
q = strchr(b, '@');
if (!q)
q = strrchr(b, '.');
assert(p);
assert(q);
return memcmp_nn(a, p - a, b, q - b) == 0;
}
+2
View File
@@ -62,3 +62,5 @@ static inline int unit_name_mangle(const char *name, UnitNameMangle flags, char
int slice_build_parent_slice(const char *slice, char **ret);
int slice_build_subslice(const char *slice, const char *name, char **subslice);
bool slice_name_is_valid(const char *name);
bool unit_name_prefix_equal(const char *a, const char *b);