-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
conf-parser breaks lines at LINE_MAX with unintended consequences/security ramifications #3302
Comments
Yeah, we should probably generate a warning at least. Silently proceeding with the rest of the line as a new line is indeed not a good idea. |
NixOS/nixpkgs#3403 also suffers from this limit. Why can't you engineer systems such that they Just Work? Why are there limitations in the system? Why didn't you just make it such that people who work in resource constrained environments have to do extra work (like specifying an upper bound on various buffers of systemd) to obtain this instead of bothering people with 256GB RAM servers? |
@butterflya I don't know, but 256 GB servers are rare. I will say, though, that this limit is too small. |
@butterflya well, we generally put limits on all resources, as a matter of writing safe code. Clients should not be able to reserve resources without bounds for their operations. And I am pretty sure the existing code actually works for most people, using overly long lines is not precisely the most typical of cases. Note that that libc and POSIX actually acknowledge the need for limits, by defining LINE_MAX which we piggyback on here, so that we don't have to come up with out own limit. I am pretty sure we should enforce a limit here. I am also pretty sure we should not silently consider overly long lines multiple lines, but log about this case. And I figure we can raise the limit. But I still think that there needs to be a limit enforced. |
What about continued lines? Should they count towards the limit? On Aug 19, 2016 10:20 AM, "Lennart Poettering" notifications@github.com
|
This commit workarounds a systemd bug, which causes unit file to be incorrectly parsed. This is triggered by property lines longer than `LINE_MAX` (2048), which frequently occur when passing a large set of values (eg. seccomp and paths). In this case, we will now split such values across multiple lines. Reference: systemd/systemd#3302
This commit workarounds a systemd bug, which causes unit file to be incorrectly parsed. This is triggered by property lines longer than `LINE_MAX` (2048), which frequently occur when passing a large set of values (eg. seccomp and paths). In this case, we will now split such values across multiple lines. Reference: systemd/systemd#3302
Clear documentation and a warning would be a start |
We already allowed entries of arbitrary length, either through repeated configuration items (for the items that allow that), or by using continuation characters. So the requirement to keep individual lines below LINE_LENGTH (2048 characters) brought no additional safety or resiliency. An arbitrary (and small) limit can be quite easily hit in automatically generated files (even by our own generators). Fixes systemd#3302.
We already allowed entries of arbitrary length, either through repeated configuration items (for the items that allow that), or by using continuation characters. So the requirement to keep individual lines below LINE_LENGTH (2048 characters) brought no additional safety or resiliency. An arbitrary (and small) limit can be quite easily hit in automatically generated files (even by our own generators). Fixes systemd#3302.
We already allowed entries of arbitrary length, either through repeated configuration items (for the items that allow that), or by using continuation characters. So the requirement to keep individual lines below LINE_LENGTH (2048 characters) brought no additional safety or resiliency. An arbitrary (and small) limit can be quite easily hit in automatically generated files (even by our own generators). Fixes systemd#3302.
We already allowed entries of arbitrary length, either through repeated configuration items (for the items that allow that), or by using continuation characters. So the requirement to keep individual lines below LINE_LENGTH (2048 characters) brought very little additional safety or resiliency, but the arbitrary (and small) limit could be quite easily hit in automatically generated files (even by our own generators). Instead allow lines up to a fairly large limit, but not infinity, to catch mistakes where the parser is fed a very long text file without any newlines. The new logic also limits the number of line continuations to 512. Fixes systemd#3302.
Let's use read_line() to solve our long line limitation. Fixes systemd#3302. (cherry picked from commit e6dde45) Resolves: #1503106
The length check was introduced[0] to match systemd's max line length. This limit has been increased[1][2] to 1MiB, starting with systemd v235. [0] NixOS#3403 [1] systemd/systemd@e6dde45 (relevant systemd commit) [2] systemd/systemd#3302 (more context on systemd change)
Let's use read_line() to solve our long line limitation. Fixes systemd#3302. (cherry picked from commit e6dde45) [fbui: fixes bsc#1137053]
Submission type
systemd version the issue has been seen with
systemd 229
+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ -LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD -IDN
Used distribution
Debian unstable (systemd: 229-6)
Expected behaviour you didn't see
In case a unit file contains lines that are longer than
LINE_MAX
characters,LINE_MAX
characters long parts before parsing) orLINE_MAX
characters and ignore the rest (with an appropriate warning?) orUnexpected behaviour you saw
In case a unit file contains lines that are longer than
LINE_MAX
characters, such lines are silently split everyLINE_MAX
characters and the resulting segments are treated as individual lines and parsed as such.Steps to reproduce the problem
Use
systemd-run
to execute a rather long command as a scope unit. By default (unless an explicit--description
is passed) the command string will be used as description for the generated unit file. If the command is longer thanLINE_MAX
(minus theDescription=
prefix), this allows to insert an additional configuration directive into the unit file by carefully crafting the command line.Executing the following command (the
aaa
is just padding)leads to a journal entry like this:
May 13 14:29:18 debian systemd[1]: [/run/systemd/system/test.scope.d/50-Description.conf:3] Unknown lvalue 'test' in section 'Unit'
Including a
Requires=something.service
orConflicts=something.service
allows to start or stop arbitrary additional services (which can result in DoS and other security issues).JoinNameSpaceOf
also looks pretty problematic/abusable to me, as do theConditionXXX
directives with would enable information leakage to an attacker.This is not limited to systemd-run, as the root cause is in https://github.com/systemd/systemd/blob/master/src/shared/conf-parser.c#L318-L395 , but since systemd-run is often used to execute commands in a resource-limiting fashion which might contain user input somewhere on the commandline and this parser behaviour is quite unexpected it seems especially problematic. Quoting and escaping the user input is only of limited value here because the command that is executed via systemd-run might also use the "xyz=abc" syntax for passing options, and with sufficient padding possibilities an attacker can move that part to the
LINE_MAX
break that happens in the parser.This issue is easily mitigated (for systemd-run) by setting an explicit description (for users of systemd-run) or by cutting off the autogenerated description if none is set explicitly (somewhere in the code-path executed by systemd-run?). I'd rather (or additionally) see the parser itself fixed though - I don't know where else systemd unit files are generated in a way that offers an attack surface via the parser's strange line splitting behaviour.
Other information
BOOT_IMAGE=/boot/vmlinuz-4.5.0-2-amd64 root=UUID=5e1db0da-44cd-4bee-9cc4-016c964436b3 ro systemd.log_level=debug systemd.log_target=kmsg log_buf_len=1M quiet
#2099 was basically the same issue, but was just worked-around by changing the generator to not produce long unit file lines (instead of fixing the root cause in the parser).
dmesg.txt
messages.txt
The text was updated successfully, but these errors were encountered: